[Gnucash-changes] r12023 - gnucash/trunk - Consolidate the creation of all file names under ~/.gnucash, and also

David Hampton hampton at cvs.gnucash.org
Wed Nov 23 17:40:04 EST 2005


Author: hampton
Date: 2005-11-23 17:40:03 -0500 (Wed, 23 Nov 2005)
New Revision: 12023
Trac: http://svn.gnucash.org/trac/changeset/12023

Modified:
   gnucash/trunk/ChangeLog
   gnucash/trunk/src/app-utils/gnc-exp-parser.c
   gnucash/trunk/src/engine/gnc-filepath-utils.c
   gnucash/trunk/src/engine/gnc-filepath-utils.h
   gnucash/trunk/src/engine/gw-engine-spec.scm
   gnucash/trunk/src/import-export/qif-import/qif-guess-map.scm
   gnucash/trunk/src/scm/command-line.scm
   gnucash/trunk/src/scm/main-window.scm
   gnucash/trunk/src/scm/main.scm
   gnucash/trunk/src/scm/path.scm
Log:
Consolidate the creation of all file names under ~/.gnucash, and also
the checks for the existence of ~/.gnucash and ~/.gnucash/books.  Add
better error messages when there is a problem.


Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/ChangeLog	2005-11-23 22:40:03 UTC (rev 12023)
@@ -1,3 +1,18 @@
+2005-11-23  David Hampton  <hampton at employees.org>
+
+	* src/import-export/qif-import/qif-guess-map.scm:
+	* src/scm/command-line.scm:
+	* src/scm/main.scm:
+	* src/scm/main-window.scm:
+	* src/scm/path.scm:
+	* src/engine/gnc-filepath-utils.c:
+	* src/engine/gnc-filepath-utils.h:
+	* src/engine/gw-engine-spec.scm:
+	* src/app-utils/gnc-exp-parser.c: Consolidate the creation of all
+	file names under ~/.gnucash, and also consolidate checks for the
+	existence of ~/.gnucash and ~/.gnucash/books.  Add better error
+	messages when there is a problem.
+
 2005-11-22  David Hampton  <hampton at employees.org>
 
 	* src/import-export/schemas/apps_gnucash_import_generic_matcher.schemas:

Modified: gnucash/trunk/src/app-utils/gnc-exp-parser.c
===================================================================
--- gnucash/trunk/src/app-utils/gnc-exp-parser.c	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/app-utils/gnc-exp-parser.c	2005-11-23 22:40:03 UTC (rev 12023)
@@ -29,6 +29,7 @@
 
 #include "finproto.h"
 #include "fin_spl_protos.h"
+#include "gnc-filepath-utils.h"
 #include "gnc-gkeyfile-utils.h"
 #include "gnc-exp-parser.h"
 #include "gnc-ui-util.h"
@@ -56,7 +57,7 @@
 static gchar *
 gnc_exp_parser_filname (void)
 {
-  return g_build_filename(g_get_home_dir(), ".gnucash", "expressions-2.0", NULL);
+  return gnc_build_dotgnucash_path("expressions-2.0");
 }
 
 void

Modified: gnucash/trunk/src/engine/gnc-filepath-utils.c
===================================================================
--- gnucash/trunk/src/engine/gnc-filepath-utils.c	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/engine/gnc-filepath-utils.c	2005-11-23 22:40:03 UTC (rev 12023)
@@ -32,13 +32,18 @@
 
 #include "config.h"
 
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <errno.h>
 
-#include <glib.h>
 #include "gnc-engine.h"
 #include "gnc-filepath-utils.h"
 
@@ -304,4 +309,118 @@
   return (xaccResolveFilePath (pathfrag));
 }
 
+/* ====================================================================== */
+
+static void
+gnc_validate_directory (const gchar *dirname)
+{
+  struct stat statbuf;
+  gint rc;
+
+  rc = stat (dirname, &statbuf);
+  if (rc) {
+    switch (errno) {
+    case ENOENT:
+      rc = mkdir (dirname, S_IRWXU);   /* perms = S_IRWXU = 0700 */
+      if (rc) {
+	g_fprintf(stderr,
+		  _("An error occurred wile creating the directory:\n"
+		    "  %s\n"
+		    "Please correct the problem and restart gnucash\n"
+		    "The reported error was '%s' (errno %d).\n"),
+		  dirname, strerror(errno), errno);
+	exit(1);
+      }
+      stat (dirname, &statbuf);
+      break;
+
+    case EACCES:
+      g_fprintf(stderr,
+		_("The directory\n"
+		  "  %s\n"
+		  "exists but cannot be accessed.  This program \n"
+		  "must have full access (read/write/execute) to \n"
+		  "the directory in order to function properly.\n"),
+		dirname);
+      exit(1);
+
+    case ENOTDIR:
+      g_fprintf(stderr,
+		_("The path\n"
+		  "  %s\n"
+		  "exists but it is not a directory. Please delete\n"
+		  "the file and start gnucash again.\n"),
+		dirname);
+      exit(1);
+      
+    default:
+      g_fprintf(stderr,
+		_("An unknown error occurred when validating that the\n"
+		  "  %s\n"
+		  "directory exists and is usable. Please correct the\n"
+		  "problem and restart gnucash.  The reported error \n"
+		  "was '%s' (errno %d)."),
+		dirname, strerror(errno), errno);
+      exit(1);
+    }
+  }
+
+  if ((statbuf.st_mode & S_IFDIR) != S_IFDIR) {
+    g_fprintf(stderr,
+	      _("The path\n"
+		"  %s\n"
+		"exists but it is not a directory. Please delete\n"
+		"the file and start gnucash again.\n"),
+	      dirname);
+    exit(1);
+  }
+  if ((statbuf.st_mode & S_IRWXU) != S_IRWXU) {
+    g_fprintf(stderr,
+	      _("The permissions are wrong on the directory\n"
+		"  %s\n"
+		"They must be at least 'rwx' for the user.\n"),
+	      dirname);
+    exit(1);
+  }
+}
+
+const gchar *
+gnc_dotgnucash_dir (void)
+{
+  static gchar *dotgnucash = NULL, *books_dir;
+  const gchar *home;
+
+  if (dotgnucash)
+    return dotgnucash;
+
+  home = g_get_home_dir();
+  if (!home) {
+    g_warning("Cannot find home directory. Using tmp directory instead.");
+    home = g_get_tmp_dir();
+  }
+  g_assert(home);
+
+  dotgnucash = g_build_filename(home, ".gnucash", (gchar *)NULL);
+  gnc_validate_directory(dotgnucash);
+
+  /* Since we're in code that is only executed once.... */
+  books_dir = g_build_filename(dotgnucash, "books", (gchar *)NULL);
+  gnc_validate_directory(books_dir);
+  g_free(books_dir);
+
+  return dotgnucash;
+}
+
+gchar *
+gnc_build_dotgnucash_path (const gchar *filename)
+{
+  return g_build_filename(gnc_dotgnucash_dir(), filename, (gchar *)NULL);
+}
+
+gchar *
+gnc_build_book_path (const gchar *filename)
+{
+  return g_build_filename(gnc_dotgnucash_dir(), "books", filename, (gchar *)NULL);
+}
+
 /* =============================== END OF FILE ========================== */

Modified: gnucash/trunk/src/engine/gnc-filepath-utils.h
===================================================================
--- gnucash/trunk/src/engine/gnc-filepath-utils.h	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/engine/gnc-filepath-utils.h	2005-11-23 22:40:03 UTC (rev 12023)
@@ -46,4 +46,8 @@
 char * xaccResolveFilePath (const char * filefrag);
 char * xaccResolveURL (const char * pathfrag);
 
+const gchar *gnc_dotgnucash_dir (void);
+gchar *gnc_build_dotgnucash_path (const gchar *filename);
+gchar *gnc_build_book_path (const gchar *filename);
+
 #endif /* GNC_FILEPATH_UTILS_H */

Modified: gnucash/trunk/src/engine/gw-engine-spec.scm
===================================================================
--- gnucash/trunk/src/engine/gw-engine-spec.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/engine/gw-engine-spec.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -29,6 +29,7 @@
     "#include <gnc-budget.h>\n"
     "#include <gnc-commodity.h>\n"
     "#include <gnc-engine.h>\n"
+    "#include <gnc-filepath-utils.h>\n"
     "#include <gnc-pricedb.h>\n"
     "#include <gnc-lot.h>\n"
     "#include <gnc-session-scm.h>\n"
@@ -2420,6 +2421,26 @@
 the timepair representing midday on that day")
 
 ;;
+;; gnc-filepath-utils.h
+;;
+
+(gw:wrap-function
+ ws
+ 'gnc:build-dotgnucash-path
+ '(<gw:mchars> caller-owned)
+ "gnc_build_dotgnucash_path"
+ '(((<gw:mchars> caller-owned) filename))
+ "Convert a relative path name into a full path name in the .gnucash directory")
+
+(gw:wrap-function
+ ws
+ 'gnc:build-book-path
+ '(<gw:mchars> caller-owned)
+ "gnc_build_book_path"
+ '(((<gw:mchars> caller-owned) filename))
+ "Convert a relative path name into a full path name in the .gnucash/books directory")
+
+;;
 ;; gnc-lot.h
 ;;
 

Modified: gnucash/trunk/src/import-export/qif-import/qif-guess-map.scm
===================================================================
--- gnucash/trunk/src/import-export/qif-import/qif-guess-map.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/import-export/qif-import/qif-guess-map.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -63,15 +63,12 @@
   ;;    (older saved prefs may not have this one)
   ;;  - a hash of QIF stock name to gnc-commodity*
   ;;    (older saved prefs may not have this one)
-  (let* ((pref-dir (build-path (getenv "HOME") ".gnucash"))
-         (pref-filename (build-path pref-dir "qif-accounts-map"))
+  (let* ((pref-filename (gnc:build-dotgnucash-path "qif-accounts-map"))
          (results '()))
     
     ;; first, read the account map and category map from the 
     ;; user's qif-accounts-map file.     
-    (if (and (access? pref-dir F_OK)
-             (access? pref-dir X_OK) 
-             (access? pref-filename R_OK))
+    (if (access? pref-filename R_OK)
         (with-input-from-file pref-filename
           (lambda ()
             (let ((qif-account-list #f)
@@ -178,22 +175,10 @@
 
 
 (define (qif-import:save-map-prefs acct-map cat-map memo-map stock-map)
-  (let* ((pref-dir (build-path (getenv "HOME") ".gnucash"))
-         (pref-filename (build-path pref-dir "qif-accounts-map"))
-         (save-ok #f))
+  (let* ((pref-filename (gnc:build-dotgnucash-path "qif-accounts-map")))
     ;; does the file exist? if not, create it; in either case,
     ;; make sure it's a directory and we have write and execute 
     ;; permission. 
-    (let ((perm (access? pref-dir F_OK)))
-      (if (not perm)
-          (mkdir pref-dir))
-      (let ((stats (stat pref-dir)))
-        (if (and (eq? (stat:type stats) 'directory)
-                 (access? pref-dir X_OK)
-                 (access? pref-dir W_OK))
-            (set! save-ok #t))))        
-    
-    (if save-ok 
         (with-output-to-file pref-filename
           (lambda ()
             (display ";;; qif-accounts-map\n")
@@ -214,7 +199,7 @@
 
             (display ";;; map from QIF stock name to GNC commodity") (newline)
             (qif-import:write-commodities stock-map)           
-            (newline))))))
+            (newline)))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Modified: gnucash/trunk/src/scm/command-line.scm
===================================================================
--- gnucash/trunk/src/scm/command-line.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/scm/command-line.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -145,7 +145,7 @@
 where 'default expands to the default path, and 'current expands to \
 the current value of the path.")
          (let ((result (cons
-                        (build-path (getenv "HOME") ".gnucash" "html")
+                        (gnc:build-dotgnucash-path "html")
                         gnc:_install-doc-path_)))
          (lambda () result))))
 

Modified: gnucash/trunk/src/scm/main-window.scm
===================================================================
--- gnucash/trunk/src/scm/main-window.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/scm/main-window.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -101,20 +101,10 @@
 (define (gnc:main-window-save-state session)
   (let* ((book-url (gnc:session-get-url session))
 	 (conf-file-name (gnc:html-encode-string book-url))
-	 (dotgnucash-dir (build-path (getenv "HOME") ".gnucash"))
-         (file-dir (build-path dotgnucash-dir "books"))
-         (save-file? #f)
          (book-path #f))
 
-    ;; make sure ~/.gnucash/books is there
-    (set! save-file? (and (gnc:make-dir dotgnucash-dir)
-                         (gnc:make-dir file-dir)))
-
-    (if (not save-file?) (gnc:warn (_ "Can't save window state")))
-
-    (if (and save-file? conf-file-name)
-        (let ((book-path (build-path (getenv "HOME") ".gnucash" "books" 
-                                     conf-file-name)))
+    (if (conf-file-name)
+        (let ((book-path (gnc:build-book-path conf-file-name)))
           (with-output-to-port (open-output-file book-path)
             (lambda ()
               (hash-fold 
@@ -148,7 +138,7 @@
 
 (define (gnc:main-window-book-open-handler session)
   (define (try-load file-suffix)
-    (let ((file (build-path (getenv "HOME") ".gnucash" "books" file-suffix)))
+    (let ((file (gnc:build-book-path file-suffix)))
       ;; make sure the books directory is there 
       (if (access? file F_OK)
           (if (not (false-if-exception (primitive-load file)))

Modified: gnucash/trunk/src/scm/main.scm
===================================================================
--- gnucash/trunk/src/scm/main.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/scm/main.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -61,7 +61,6 @@
 (re-export string-split)
 
 ;; from path.scm
-(export gnc:make-home-dir)
 (export gnc:current-config-auto)
 (export gnc:current-saved-reports)
 (export gnc:current-saved-stylesheets)

Modified: gnucash/trunk/src/scm/path.scm
===================================================================
--- gnucash/trunk/src/scm/path.scm	2005-11-23 16:48:11 UTC (rev 12022)
+++ gnucash/trunk/src/scm/path.scm	2005-11-23 22:40:03 UTC (rev 12023)
@@ -35,24 +35,20 @@
       #t
       (false-if-exception (mkdir dir #o700))))
 
-(define (gnc:make-home-dir)
-  (let ((home-dir (build-path (getenv "HOME") ".gnucash")))
-    (gnc:make-dir home-dir)))
-
 (define gnc:current-config-auto
-  (build-path (getenv "HOME") ".gnucash" "config-2.0.auto"))
+  (gnc:build-dotgnucash-path "config-2.0.auto"))
 
 (define gnc:current-saved-reports
-  (build-path (getenv "HOME") ".gnucash" "saved-reports-2.0"))
+  (gnc:build-dotgnucash-path "saved-reports-2.0"))
 
 (define gnc:current-saved-stylesheets
-  (build-path (getenv "HOME") ".gnucash" "stylesheets-2.0"))
+  (gnc:build-dotgnucash-path "stylesheets-2.0"))
 
 (define gnc:load-user-config-if-needed
   (let ((user-config-loaded? #f))
 
     (define (try-load-no-set file-suffix)
-      (let ((file (build-path (getenv "HOME") ".gnucash" file-suffix)))
+      (let ((file (gnc:build-dotgnucash-path file-suffix)))
 	(gnc:debug "trying to load " file)
         (if (access? file F_OK)
             (if (false-if-exception (primitive-load file))



More information about the gnucash-changes mailing list