[Gnucash-changes] move the file-path utilities out of qofsession.
Linas Vepstas
linas at cvs.gnucash.org
Sun Jun 13 13:23:27 EDT 2004
Log Message:
-----------
move the file-path utilities out of qofsession.
Added Files:
-----------
gnucash/src/engine:
gnc-filepath-utils.c
gnc-filepath-utils.h
Revision Data
-------------
--- /dev/null
+++ src/engine/gnc-filepath-utils.c
@@ -0,0 +1,309 @@
+/********************************************************************\
+ * gnc-filepath-utils.c -- file path resolutin utilitie *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
+ * Boston, MA 02111-1307, USA gnu at gnu.org *
+\********************************************************************/
+
+/*
+ * @file gnc-filepath-utils.c
+ * @breif file path resolutionutilities
+ * @author Copyright (c) 1998-2004 Linas Vepstas <linas at linas.org>
+ * @author Copyright (c) 2000 Dave Peticolas
+ *
+ * XXX this file does not belong in the gnucash engine; it is here
+ * for the moment only because both the file backend and the app-file
+ * GUI code make use of it.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "gnc-filepath-utils.h"
+#include "gnc-trace.h"
+
+static short module = MOD_BACKEND;
+
+
+/* ====================================================================== */
+/*
+ * If $HOME/.gnucash/data directory doesn't exist, then create it.
+ */
+
+static void
+MakeHomeDir (void)
+{
+ int rc;
+ struct stat statbuf;
+ char *home;
+ char *path;
+ char *data;
+
+ /* Punt. Can't figure out where home is. */
+ home = getenv ("HOME");
+ if (!home) return;
+
+ path = g_strconcat(home, "/.gnucash", NULL);
+
+ rc = stat (path, &statbuf);
+ if (rc)
+ {
+ /* assume that the stat failed only because the dir is absent,
+ * and not because its read-protected or other error.
+ * Go ahead and make it. Don't bother much with checking mkdir
+ * for errors; seems pointless. */
+ mkdir (path, S_IRWXU); /* perms = S_IRWXU = 0700 */
+ }
+
+ data = g_strconcat (path, "/data", NULL);
+ rc = stat (data, &statbuf);
+ if (rc)
+ mkdir (data, S_IRWXU);
+
+ g_free (path);
+ g_free (data);
+}
+
+/* ====================================================================== */
+
+/* XXX hack alert -- we should be yanking this out of some config file */
+static char * searchpaths[] =
+{
+ "/usr/share/gnucash/data/",
+ "/usr/local/share/gnucash/data/",
+ "/usr/share/gnucash/accounts/",
+ "/usr/local/share/gnucash/accounts/",
+ NULL,
+};
+
+typedef gboolean (*pathGenerator)(char *pathbuf, int which);
+
+static gboolean
+xaccAddEndPath(char *pathbuf, const char *ending, int len)
+{
+ if(len + strlen(pathbuf) >= PATH_MAX)
+ return FALSE;
+
+ strcat (pathbuf, ending);
+ return TRUE;
+}
+
+static gboolean
+xaccCwdPathGenerator(char *pathbuf, int which)
+{
+ if(which != 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ /* try to find a file by this name in the cwd ... */
+ if (getcwd (pathbuf, PATH_MAX) == NULL)
+ return FALSE;
+
+ strcat (pathbuf, "/");
+ return TRUE;
+ }
+}
+
+static gboolean
+xaccDataPathGenerator(char *pathbuf, int which)
+{
+ char *path;
+
+ if(which != 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ path = getenv ("HOME");
+ if (!path)
+ return FALSE;
+
+ if (PATH_MAX <= (strlen (path) + 20))
+ return FALSE;
+
+ strcpy (pathbuf, path);
+ strcat (pathbuf, "/.gnucash/data/");
+ return TRUE;
+ }
+}
+
+static gboolean
+xaccUserPathPathGenerator(char *pathbuf, int which)
+{
+ char *path = NULL;
+
+ if(searchpaths[which] == NULL)
+ {
+ return FALSE;
+ }
+ else
+ {
+ path = searchpaths[which];
+
+ if (PATH_MAX <= strlen(path))
+ return FALSE;
+
+ strcpy (pathbuf, path);
+ return TRUE;
+ }
+}
+
+/* ====================================================================== */
+
+char *
+xaccResolveFilePath (const char * filefrag)
+{
+ struct stat statbuf;
+ char pathbuf[PATH_MAX];
+ pathGenerator gens[4];
+ char *filefrag_dup;
+ int namelen;
+ int i;
+
+ /* seriously invalid */
+ if (!filefrag)
+ {
+ PERR("filefrag is NULL");
+ return NULL;
+ }
+
+ ENTER ("filefrag=%s", filefrag);
+
+ /* ---------------------------------------------------- */
+ /* OK, now we try to find or build an absolute file path */
+
+ /* check for an absolute file path */
+ if (*filefrag == '/')
+ return g_strdup (filefrag);
+
+ if (!g_strncasecmp(filefrag, "file:", 5))
+ {
+ char *ret = g_new(char, strlen(filefrag) - 5 + 1);
+ strcpy(ret, filefrag + 5);
+ return ret;
+ }
+
+ /* get conservative on the length so that sprintf(getpid()) works ... */
+ /* strlen ("/.LCK") + sprintf (%x%d) */
+ namelen = strlen (filefrag) + 25;
+
+ gens[0] = xaccCwdPathGenerator;
+ gens[1] = xaccDataPathGenerator;
+ gens[2] = xaccUserPathPathGenerator;
+ gens[3] = NULL;
+
+ for (i = 0; gens[i] != NULL; i++)
+ {
+ int j;
+ for(j = 0; gens[i](pathbuf, j) ; j++)
+ {
+ if(xaccAddEndPath(pathbuf, filefrag, namelen))
+ {
+ int rc = stat (pathbuf, &statbuf);
+ if ((!rc) && (S_ISREG(statbuf.st_mode)))
+ {
+ return (g_strdup (pathbuf));
+ }
+ }
+ }
+ }
+ /* OK, we didn't find the file. */
+
+ /* make sure that the gnucash home dir exists. */
+ MakeHomeDir();
+
+ filefrag_dup = g_strdup (filefrag);
+
+ /* Replace '/' with ',' for non file backends */
+ if (strstr (filefrag, "://"))
+ {
+ char *p;
+
+ p = strchr (filefrag_dup, '/');
+ while (p) {
+ *p = ',';
+ p = strchr (filefrag_dup, '/');
+ }
+ }
+
+ /* Lets try creating a new file in $HOME/.gnucash/data */
+ if (xaccDataPathGenerator(pathbuf, 0))
+ {
+ if(xaccAddEndPath(pathbuf, filefrag_dup, namelen))
+ {
+ g_free (filefrag_dup);
+ return (g_strdup (pathbuf));
+ }
+ }
+
+ /* OK, we still didn't find the file */
+ /* Lets try creating a new file in the cwd */
+ if (xaccCwdPathGenerator(pathbuf, 0))
+ {
+ if(xaccAddEndPath(pathbuf, filefrag_dup, namelen))
+ {
+ g_free (filefrag_dup);
+ return (g_strdup (pathbuf));
+ }
+ }
+
+ g_free (filefrag_dup);
+
+ return NULL;
+}
+
+/* ====================================================================== */
+
+char *
+xaccResolveURL (const char * pathfrag)
+{
+ /* seriously invalid */
+ if (!pathfrag) return NULL;
+
+ /* At this stage of checking, URL's are always, by definition,
+ * resolved. If there's an error connecting, we'll find out later.
+ *
+ * FIXME -- we should probably use ghttp_uri_validate
+ * to make sure the uri is in good form.
+ */
+
+ if (!g_strncasecmp (pathfrag, "http://", 7) ||
+ !g_strncasecmp (pathfrag, "https://", 8) ||
+ !g_strncasecmp (pathfrag, "postgres://", 11) ||
+ !g_strncasecmp (pathfrag, "rpc://", 6))
+ {
+ return g_strdup(pathfrag);
+ }
+
+ if (!g_strncasecmp (pathfrag, "file:", 5)) {
+ return (xaccResolveFilePath (pathfrag));
+ }
+
+ return (xaccResolveFilePath (pathfrag));
+}
+
+/* =============================== END OF FILE ========================== */
--- /dev/null
+++ src/engine/gnc-filepath-utils.h
@@ -0,0 +1,49 @@
+/********************************************************************\
+ * gnc-filepath-utils.h -- file path resolutin utilitie *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
+ * Boston, MA 02111-1307, USA gnu at gnu.org *
+\********************************************************************/
+
+/**
+ * @file gnc-filepath-utils.h
+ * @breif file path resolutionutilities
+ * @author Copyright (c) 1998-2004 Linas Vepstas <linas at linas.org>
+ * @author Copyright (c) 2000 Dave Peticolas
+ *
+ * XXX this file does not belong in the gnucash engine; it is here
+ * for the moment only because both the file backend and the app-file
+ * GUI code make use of it. It should be moved away someday.
+ */
+
+#ifndef GNC_FILEPATH_UTILS_H
+#define GNC_FILEPATH_UTILS_H
+
+/** The xaccResolveFilePath() routine is a utility that will accept
+ * a fragmentary filename as input, and resolve it into a fully
+ * qualified path in the file system, i.e. a path that begins with
+ * a leading slash. First, the current working directory is
+ * searched for the file. Next, the directory $HOME/.gnucash/data,
+ * and finally, a list of other (configurable) paths. If the file
+ * is not found, then the path $HOME/.gnucash/data is used. If
+ * $HOME is not defined, then the current working directory is
+ * used.
+ */
+char * xaccResolveFilePath (const char * filefrag);
+char * xaccResolveURL (const char * pathfrag);
+
+#endif /* GNC_FILEPATH_UTILS_H */
More information about the gnucash-changes
mailing list