LCOV - code coverage report
Current view: top level - libgnucash/app-utils - gnc-state.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 0.0 % 122 0
Test Date: 2025-02-07 16:25:45 Functions: 0.0 % 5 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /********************************************************************\
       2                 :             :  * file-utils.c -- simple file utilities                            *
       3                 :             :  * Copyright (C) 1997 Robin D. Clark <rclark@cs.hmc.edu>            *
       4                 :             :  * Copyright (C) 1998 Rob Browning                                  *
       5                 :             :  * Copyright (C) 1998-2000 Linas Vepstas <linas@linas.org>          *
       6                 :             :  *                                                                  *
       7                 :             :  * This program is free software; you can redistribute it and/or    *
       8                 :             :  * modify it under the terms of the GNU General Public License as   *
       9                 :             :  * published by the Free Software Foundation; either version 2 of   *
      10                 :             :  * the License, or (at your option) any later version.              *
      11                 :             :  *                                                                  *
      12                 :             :  * This program is distributed in the hope that it will be useful,  *
      13                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      14                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      15                 :             :  * GNU General Public License for more details.                     *
      16                 :             :  *                                                                  *
      17                 :             :  * You should have received a copy of the GNU General Public License*
      18                 :             :  * along with this program; if not, write to the Free Software      *
      19                 :             :  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        *
      20                 :             : \********************************************************************/
      21                 :             : 
      22                 :             : #include <config.h>
      23                 :             : 
      24                 :             : #include <glib.h>
      25                 :             : //#include <glib/gstdio.h>
      26                 :             : //#include <errno.h>
      27                 :             : 
      28                 :             : #include "gnc-state.h"
      29                 :             : //#include "gnc-engine.h"
      30                 :             : #include "gnc-filepath-utils.h"
      31                 :             : #include "gnc-gkeyfile-utils.h"
      32                 :             : #include "gnc-uri-utils.h"
      33                 :             : #include "qof.h"
      34                 :             : 
      35                 :             : /* This static indicates the debugging module that this .o belongs to.  */
      36                 :             : static QofLogModule log_module = G_LOG_DOMAIN;
      37                 :             : 
      38                 :             : /* Absolute path to the state file for the current book
      39                 :             :  * Before 2.4.1, this file didn't have an extension.
      40                 :             :  * The code will look for such pre 2.4.0 file if no post 2.4.1
      41                 :             :  * version is found. If there is an old style file, save the
      42                 :             :  * name here as well. The old style state file will then be
      43                 :             :  * converted into a new style one the next time state is saved.
      44                 :             :  */
      45                 :             : static gchar* state_file_name = NULL;
      46                 :             : static gchar* state_file_name_pre_241 = NULL;
      47                 :             : /* State file data for current book */
      48                 :             : static GKeyFile *state_file = NULL;
      49                 :             : 
      50                 :             : /* Determine which file name to use for the state file. This name is based
      51                 :             :  * the current book's uri and guid.
      52                 :             :  *
      53                 :             :  * The state files will be searched for in the books directory in GnuCash'
      54                 :             :  * private configuration directory. This configuration directory is
      55                 :             :  * platform dependent and can be overridden with environment variable
      56                 :             :  * DOT_GNUCASH_DIR. On linux for example this is ~/.gnucash by default.
      57                 :             :  *
      58                 :             :  * The URL is used to compute the base name of the state file and the
      59                 :             :  * guid is used to differentiate when the user has multiple data files
      60                 :             :  * with the same name.
      61                 :             :  *
      62                 :             :  * As of GnuCash 2.4.1 state files will have their own extension to
      63                 :             :  * differentiate them from data files saved by the user. New state
      64                 :             :  * files will always be created with such an extension. But GnuCash
      65                 :             :  * will continue to search for state files without an extension if
      66                 :             :  * no proper state file with extension is found. */
      67                 :             : 
      68                 :             : 
      69                 :             : static void
      70                 :           0 : gnc_state_set_base (const QofSession *session)
      71                 :             : {
      72                 :           0 :     gchar *basename, *original = NULL, *filename, *file_guid;
      73                 :           0 :     gchar *sf_extension = NULL;
      74                 :             :     const gchar *uri;
      75                 :             :     gchar guid_string[GUID_ENCODING_LENGTH+1];
      76                 :             :     QofBook *book;
      77                 :             :     const GncGUID *guid;
      78                 :           0 :     GKeyFile *key_file = NULL;
      79                 :             :     gint i;
      80                 :             : 
      81                 :             :     /* Reset filenames possibly found in a previous run */
      82                 :           0 :     g_free (state_file_name);
      83                 :           0 :     g_free (state_file_name_pre_241);
      84                 :           0 :     state_file_name = NULL;
      85                 :           0 :     state_file_name_pre_241 = NULL;
      86                 :             : 
      87                 :           0 :     uri = qof_session_get_url (session);
      88                 :           0 :     ENTER("session %p (%s)", session, uri ? uri : "(null)");
      89                 :           0 :     if (!strlen (uri))
      90                 :             :     {
      91                 :           0 :         LEAVE("no uri, nothing to do");
      92                 :           0 :         return;
      93                 :             :     }
      94                 :             : 
      95                 :             :     /* Get the book GncGUID */
      96                 :           0 :     book = qof_session_get_book(session);
      97                 :           0 :     guid = qof_entity_get_guid(QOF_INSTANCE(book));
      98                 :           0 :     guid_to_string_buff(guid, guid_string);
      99                 :             : 
     100                 :           0 :     if (gnc_uri_targets_local_fs (uri))
     101                 :             :     {
     102                 :             :         /* The book_uri is a true file, use its basename. */
     103                 :           0 :         gchar *path = gnc_uri_get_path (uri);
     104                 :           0 :         basename = g_path_get_basename (path);
     105                 :           0 :         g_free (path);
     106                 :             :     }
     107                 :             :     else
     108                 :             :     {
     109                 :             :         /* The book_uri is composed of database connection parameters. */
     110                 :           0 :         gchar* scheme = NULL;
     111                 :           0 :         gchar* host = NULL;
     112                 :           0 :         gchar* dbname = NULL;
     113                 :           0 :         gchar* username = NULL;
     114                 :           0 :         gchar* password = NULL;
     115                 :           0 :         gint portnum = 0;
     116                 :           0 :         gnc_uri_get_components (uri, &scheme, &host, &portnum,
     117                 :             :                                 &username, &password, &dbname);
     118                 :             : 
     119                 :           0 :         basename = g_strjoin ("_", scheme, host, username, dbname, NULL);
     120                 :           0 :         g_free (scheme);
     121                 :           0 :         g_free (host);
     122                 :           0 :         g_free (username);
     123                 :           0 :         g_free (password);
     124                 :           0 :         g_free (dbname);
     125                 :             :     }
     126                 :             : 
     127                 :           0 :     DEBUG ("Basename %s", basename);
     128                 :           0 :     original = gnc_build_book_path (basename);
     129                 :           0 :     g_free (basename);
     130                 :           0 :     DEBUG ("Original %s", original);
     131                 :             : 
     132                 :           0 :     sf_extension = g_strdup (STATE_FILE_EXT);
     133                 :           0 :     i = 1;
     134                 :             :     while (1)
     135                 :             :     {
     136                 :           0 :         if (i == 1)
     137                 :           0 :             filename = g_strconcat (original, sf_extension, NULL);
     138                 :             :         else
     139                 :           0 :             filename = g_strdup_printf ("%s_%d%s", original, i, sf_extension);
     140                 :           0 :         DEBUG ("Trying %s", filename);
     141                 :           0 :         key_file = gnc_key_file_load_from_file (filename, TRUE, FALSE, NULL);
     142                 :           0 :         DEBUG ("Result %p", key_file);
     143                 :             : 
     144                 :           0 :         if (!key_file)
     145                 :             :         {
     146                 :           0 :             DEBUG ("No key file by that name");
     147                 :           0 :             if (g_strcmp0 (sf_extension, STATE_FILE_EXT) == 0)
     148                 :             :             {
     149                 :           0 :                 DEBUG ("Trying old state file names for compatibility");
     150                 :           0 :                 i = 1;
     151                 :           0 :                 g_free (sf_extension);
     152                 :           0 :                 sf_extension = g_strdup ("");
     153                 :             : 
     154                 :             :                 /* Regardless of whether or not an old state file is found,
     155                 :             :                  * the currently tested name should be used for the future
     156                 :             :                  * state file.
     157                 :             :                  */
     158                 :           0 :                 state_file_name = filename;
     159                 :           0 :                 continue;
     160                 :             :             }
     161                 :             : 
     162                 :             :             /* No old style file found. We'll return with the new file name
     163                 :             :              * we set earlier, and no existing key file. */
     164                 :           0 :             g_free (filename);
     165                 :           0 :             break;
     166                 :             :         }
     167                 :             : 
     168                 :           0 :         file_guid = g_key_file_get_string (key_file,
     169                 :             :                                            STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
     170                 :             :                                            NULL);
     171                 :           0 :         DEBUG ("File GncGUID is %s", file_guid ? file_guid : "<not found>");
     172                 :           0 :         if (g_strcmp0 (guid_string, file_guid) == 0)
     173                 :             :         {
     174                 :           0 :             DEBUG ("Matched !!!");
     175                 :             :             /* Save the found file for later use. Which name to save to
     176                 :             :              * depends on whether it was an old or new style file name
     177                 :             :              */
     178                 :           0 :             if (g_strcmp0 (sf_extension, STATE_FILE_EXT) == 0)
     179                 :           0 :                 state_file_name = filename;
     180                 :             :             else
     181                 :           0 :                 state_file_name_pre_241 = filename;
     182                 :             : 
     183                 :           0 :             g_free (file_guid);
     184                 :           0 :             break;
     185                 :             :         }
     186                 :           0 :         DEBUG ("Clean up this pass");
     187                 :           0 :         g_free (file_guid);
     188                 :           0 :         g_key_file_free (key_file);
     189                 :           0 :         g_free (filename);
     190                 :           0 :         i++;
     191                 :             :     }
     192                 :             : 
     193                 :           0 :     DEBUG("Clean up");
     194                 :           0 :     g_free(sf_extension);
     195                 :           0 :     g_free(original);
     196                 :           0 :     if (key_file != NULL)
     197                 :           0 :         g_key_file_free (key_file);
     198                 :             : 
     199                 :           0 :     LEAVE ();
     200                 :             : }
     201                 :             : 
     202                 :           0 : GKeyFile *gnc_state_load (const QofSession *session)
     203                 :             : {
     204                 :             :     /* Drop possible previous state_file first */
     205                 :           0 :     if (state_file)
     206                 :             :     {
     207                 :           0 :         g_key_file_free (state_file);
     208                 :           0 :         state_file = NULL;
     209                 :             :     }
     210                 :             : 
     211                 :           0 :     gnc_state_set_base (session);
     212                 :             : 
     213                 :           0 :     if (state_file_name_pre_241)
     214                 :           0 :         state_file = gnc_key_file_load_from_file (state_file_name_pre_241,
     215                 :             :                      TRUE, TRUE, NULL);
     216                 :           0 :     else if (state_file_name)
     217                 :           0 :         state_file = gnc_key_file_load_from_file (state_file_name,
     218                 :             :                      TRUE, TRUE, NULL);
     219                 :             : 
     220                 :           0 :     return gnc_state_get_current ();
     221                 :             : }
     222                 :             : 
     223                 :           0 : void gnc_state_save (const QofSession *session)
     224                 :             : {
     225                 :           0 :     GError *error = NULL;
     226                 :             : 
     227                 :           0 :     if (!strlen (qof_session_get_url(session)))
     228                 :             :     {
     229                 :           0 :         DEBUG("No file associated with session - skip state saving");
     230                 :           0 :         return;
     231                 :             :     }
     232                 :             : 
     233                 :           0 :     gnc_state_set_base (session);
     234                 :             : 
     235                 :             :     /* Write it all out to disk */
     236                 :           0 :     if (state_file_name)
     237                 :           0 :         gnc_key_file_save_to_file(state_file_name, state_file, &error);
     238                 :             :     else
     239                 :           0 :         PWARN ("No state file name set, can't save state");
     240                 :             : 
     241                 :           0 :     if (error)
     242                 :             :     {
     243                 :           0 :         PERR ("Error: Cannot open state file %s", error->message);
     244                 :           0 :         g_error_free (error);
     245                 :             :     }
     246                 :             : }
     247                 :             : 
     248                 :           0 : GKeyFile *gnc_state_get_current (void)
     249                 :             : {
     250                 :           0 :     if (!state_file)
     251                 :             :     {
     252                 :           0 :         PINFO ("No pre-existing state found, creating new one");
     253                 :           0 :         state_file = g_key_file_new ();
     254                 :             :     }
     255                 :             : 
     256                 :           0 :     return state_file;
     257                 :             : 
     258                 :             : }
     259                 :             : 
     260                 :           0 : gint gnc_state_drop_sections_for (const gchar *partial_name)
     261                 :             : {
     262                 :             :     gchar **groups;
     263                 :           0 :     gint found_count = 0, dropped_count = 0;
     264                 :             :     gsize i, num_groups;
     265                 :           0 :     GError *error = NULL;
     266                 :             : 
     267                 :           0 :     if (!state_file)
     268                 :             :     {
     269                 :           0 :         PWARN ("No pre-existing state found, ignoring drop request");
     270                 :           0 :         return 0;
     271                 :             :     }
     272                 :             : 
     273                 :           0 :     ENTER("");
     274                 :             : 
     275                 :           0 :     groups = g_key_file_get_groups (state_file, &num_groups);
     276                 :           0 :     for (i = 0; i < num_groups; i++)
     277                 :             :     {
     278                 :           0 :         if (g_strstr_len (groups[i], -1, partial_name))
     279                 :             :         {
     280                 :           0 :             DEBUG ("Section \"%s\" matches \"%s\", removing", groups[i], partial_name);
     281                 :           0 :             found_count++;
     282                 :           0 :             if (!g_key_file_remove_group (state_file, groups[i], &error))
     283                 :             :             {
     284                 :           0 :                 PWARN ("Warning: unable to remove section %s.\n  %s",
     285                 :             :                         groups[i],
     286                 :             :                         error->message);
     287                 :           0 :                 g_error_free (error);
     288                 :             :             }
     289                 :             :             else
     290                 :           0 :                 dropped_count++;
     291                 :             : 
     292                 :             :         }
     293                 :             :     }
     294                 :           0 :     g_strfreev (groups);
     295                 :             : 
     296                 :           0 :     LEAVE("Found %i sections matching \"%s\", successfully removed %i",
     297                 :             :             found_count, partial_name, dropped_count);
     298                 :           0 :     return dropped_count;
     299                 :             : 
     300                 :             : }
     301                 :             : 
        

Generated by: LCOV version 2.0-1