mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Redesign gnc-uri-utils
- gnc_uri_get_components will now return NULL as protocol if the input is a normal file system path instead of a uri (it used to return 'file') - gnc_uri_get_protocol will now return NULL if the input is a normal file system path instead of a uri (it used to return 'file') - gnc_uri_is_file_protocol now returns FALSE if protocol is NULL (it used to return TRUE) - gnc_uri_is_file_uri now returns FALSE if input is a normal file system path instead of a uri (it used to return TRUE) - a new function gnc_uri_targets_local_fs will return TRUE only if its input is either a file uri or a normal file system path. This function is now mostly used instead of gnc_uri_is_file_uri in the current code base - a new function gnc_uri_is_uri is added to check whether its input is a valid uri (has protocol, path and hostname for non-file uris)
This commit is contained in:
parent
06da9e9712
commit
4b398325ea
@ -335,7 +335,7 @@ gnc_ui_file_access (GtkWindow *parent, int type)
|
||||
if (type == FILE_ACCESS_OPEN || type == FILE_ACCESS_SAVE_AS)
|
||||
{
|
||||
last = gnc_history_get_last();
|
||||
if ( last && gnc_uri_is_file_uri ( last ) )
|
||||
if ( last && gnc_uri_targets_local_fs (last))
|
||||
{
|
||||
gchar *filepath = gnc_uri_get_path ( last );
|
||||
faw->starting_dir = g_path_get_dirname( filepath );
|
||||
|
@ -208,11 +208,11 @@ show_session_error (GtkWindow *parent,
|
||||
{
|
||||
displayname = g_strdup(_("(null)"));
|
||||
}
|
||||
else if (! gnc_uri_is_file_uri (newfile)) /* Hide the db password in error messages */
|
||||
else if (!gnc_uri_targets_local_fs (newfile)) /* Hide the db password in error messages */
|
||||
displayname = gnc_uri_normalize_uri ( newfile, FALSE);
|
||||
else
|
||||
{
|
||||
/* Strip the protocol from the file name. */
|
||||
/* Strip the protocol from the file name and ensure absolute filename. */
|
||||
char *uri = gnc_uri_normalize_uri(newfile, FALSE);
|
||||
displayname = gnc_uri_get_path(uri);
|
||||
g_free(uri);
|
||||
@ -515,7 +515,7 @@ gnc_add_history (QofSession * session)
|
||||
if ( !strlen (url) )
|
||||
return;
|
||||
|
||||
if ( gnc_uri_is_file_uri ( url ) )
|
||||
if (gnc_uri_targets_local_fs (url))
|
||||
file = gnc_uri_get_path ( url );
|
||||
else
|
||||
file = gnc_uri_normalize_uri ( url, FALSE ); /* Note that the password is not saved in history ! */
|
||||
@ -689,8 +689,10 @@ RESTART:
|
||||
* function will ask the user to enter a password. The user can
|
||||
* cancel this dialog, in which case the open file action will be
|
||||
* abandoned.
|
||||
* Note newfile is normalized uri so we can safely call
|
||||
* gnc_uri_is_file_protocol on it.
|
||||
*/
|
||||
if ( !gnc_uri_is_file_protocol (protocol) && !password)
|
||||
if (!gnc_uri_is_file_protocol (protocol) && !password)
|
||||
{
|
||||
gboolean have_valid_pw = FALSE;
|
||||
have_valid_pw = gnc_keyring_get_password ( NULL, protocol, hostname, port,
|
||||
@ -774,10 +776,11 @@ RESTART:
|
||||
);
|
||||
int rc;
|
||||
|
||||
if (! gnc_uri_is_file_uri (newfile)) /* Hide the db password in error messages */
|
||||
/* Hide the db password and local filesystem schemes in error messages */
|
||||
if (!gnc_uri_is_file_uri (newfile))
|
||||
displayname = gnc_uri_normalize_uri ( newfile, FALSE);
|
||||
else
|
||||
displayname = g_strdup (newfile);
|
||||
displayname = gnc_uri_get_path (newfile);
|
||||
|
||||
dialog = gtk_message_dialog_new(parent,
|
||||
0,
|
||||
@ -1050,7 +1053,7 @@ gnc_file_open (GtkWindow *parent)
|
||||
if (!gnc_file_query_save (parent, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ( last && gnc_uri_is_file_uri ( last ) )
|
||||
if ( last && gnc_uri_targets_local_fs (last))
|
||||
{
|
||||
gchar *filepath = gnc_uri_get_path ( last );
|
||||
default_dir = g_path_get_dirname( filepath );
|
||||
@ -1099,7 +1102,7 @@ gnc_file_export (GtkWindow *parent)
|
||||
ENTER(" ");
|
||||
|
||||
last = gnc_history_get_last();
|
||||
if ( last && gnc_uri_is_file_uri ( last ) )
|
||||
if ( last && gnc_uri_targets_local_fs (last))
|
||||
{
|
||||
gchar *filepath = gnc_uri_get_path ( last );
|
||||
default_dir = g_path_get_dirname( filepath );
|
||||
@ -1198,7 +1201,9 @@ gnc_file_do_export(GtkWindow *parent, const char * filename)
|
||||
newfile = norm_file;
|
||||
}
|
||||
|
||||
/* Some extra steps for file based uri's only */
|
||||
/* Some extra steps for file based uri's only
|
||||
* Note newfile is normalized uri so we can safely call
|
||||
* gnc_uri_is_file_protocol on it. */
|
||||
if (gnc_uri_is_file_protocol(protocol))
|
||||
{
|
||||
if (check_file_path (path))
|
||||
@ -1360,7 +1365,7 @@ gnc_file_save_as (GtkWindow *parent)
|
||||
ENTER(" ");
|
||||
|
||||
last = gnc_history_get_last();
|
||||
if ( last && gnc_uri_is_file_uri ( last ) )
|
||||
if ( last && gnc_uri_targets_local_fs (last))
|
||||
{
|
||||
gchar *filepath = gnc_uri_get_path ( last );
|
||||
default_dir = g_path_get_dirname( filepath );
|
||||
@ -1430,7 +1435,9 @@ gnc_file_do_save_as (GtkWindow *parent, const char* filename)
|
||||
newfile = norm_file;
|
||||
}
|
||||
|
||||
/* Some extra steps for file based uri's only */
|
||||
/* Some extra steps for file based uri's only
|
||||
* Note newfile is normalized uri so we can safely call
|
||||
* gnc_uri_is_file_protocol on it. */
|
||||
if (gnc_uri_is_file_protocol(protocol))
|
||||
{
|
||||
if (check_file_path (path))
|
||||
|
@ -1518,7 +1518,7 @@ gnc_main_window_generate_title (GncMainWindow *window)
|
||||
filename = g_strdup(_("Unsaved Book"));
|
||||
else
|
||||
{
|
||||
if ( gnc_uri_is_file_uri ( book_id ) )
|
||||
if (gnc_uri_targets_local_fs (book_id))
|
||||
{
|
||||
/* The filename is a true file.
|
||||
* The Gnome HIG 2.0 recommends only the file name (no path) be used. (p15) */
|
||||
@ -1657,7 +1657,7 @@ static gchar *generate_statusbar_lastmodified_message()
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
if ( gnc_uri_is_file_uri ( book_id ) )
|
||||
if (gnc_uri_targets_local_fs (book_id))
|
||||
{
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
/* The filename is a true file. */
|
||||
|
@ -329,7 +329,7 @@ gnc_history_generate_label (int index, const gchar *filename)
|
||||
gchar *label, *result;
|
||||
gchar **splitlabel;
|
||||
|
||||
if ( gnc_uri_is_file_uri ( filename ) )
|
||||
if (gnc_uri_targets_local_fs (filename))
|
||||
{
|
||||
/* for file paths, only display the file name */
|
||||
gchar *filepath = gnc_uri_get_path ( filename );
|
||||
@ -368,7 +368,7 @@ static gchar *
|
||||
gnc_history_generate_tooltip (int index, const gchar *filename)
|
||||
{
|
||||
|
||||
if ( gnc_uri_is_file_uri ( filename ) )
|
||||
if (gnc_uri_targets_local_fs (filename))
|
||||
/* for file paths, display the full file path */
|
||||
return gnc_uri_get_path ( filename );
|
||||
else
|
||||
|
@ -97,7 +97,7 @@ gnc_state_set_base (const QofSession *session)
|
||||
guid = qof_entity_get_guid(QOF_INSTANCE(book));
|
||||
guid_to_string_buff(guid, guid_string);
|
||||
|
||||
if (gnc_uri_is_file_uri (uri))
|
||||
if (gnc_uri_targets_local_fs (uri))
|
||||
{
|
||||
/* The book_uri is a true file, use its basename. */
|
||||
gchar *path = gnc_uri_get_path (uri);
|
||||
|
@ -27,6 +27,34 @@
|
||||
#include "gnc-filepath-utils.h"
|
||||
#include "qofsession.h"
|
||||
|
||||
/* Checks if the given uri is a valid uri
|
||||
*/
|
||||
gboolean gnc_uri_is_uri (const gchar *uri)
|
||||
{
|
||||
|
||||
gchar *protocol = NULL, *hostname = NULL;
|
||||
gchar *username = NULL, *password = NULL;
|
||||
gchar *path = NULL;
|
||||
gint port = 0;
|
||||
gboolean is_uri = FALSE;
|
||||
|
||||
gnc_uri_get_components ( uri, &protocol, &hostname, &port,
|
||||
&username, &password, &path );
|
||||
|
||||
/* For gnucash to consider a uri valid the following must be true:
|
||||
* - protocol and path must not be NULL
|
||||
* - for anything but local filesystem uris, hostname must be valid as well */
|
||||
is_uri = (protocol && path && (gnc_uri_is_file_protocol(protocol) || hostname));
|
||||
|
||||
g_free (protocol);
|
||||
g_free (hostname);
|
||||
g_free (username);
|
||||
g_free (password);
|
||||
g_free (path);
|
||||
|
||||
return is_uri;
|
||||
}
|
||||
|
||||
/* Checks if the given protocol is used to refer to a file
|
||||
* (as opposed to a network service)
|
||||
*/
|
||||
@ -52,17 +80,19 @@ gboolean gnc_uri_is_known_protocol (const gchar *protocol)
|
||||
|
||||
/* Checks if the given protocol is used to refer to a file
|
||||
* (as opposed to a network service)
|
||||
* For simplicity, handle all unknown protocols as if it were
|
||||
* file based protocols. This will avoid password lookups and such.
|
||||
* Note unknown protocols are always considered network protocols.
|
||||
*
|
||||
* *Compatibility note:*
|
||||
* This used to be the other way around before gnucash 3.4. Before
|
||||
* that unknown protocols were always considered local file system
|
||||
* uri protocols.
|
||||
*/
|
||||
gboolean gnc_uri_is_file_protocol (const gchar *protocol)
|
||||
{
|
||||
if ( !g_ascii_strcasecmp (protocol, "mysql") ||
|
||||
!g_ascii_strcasecmp (protocol, "postgres")
|
||||
)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
return (protocol &&
|
||||
(!g_ascii_strcasecmp (protocol, "file") ||
|
||||
!g_ascii_strcasecmp (protocol, "xml") ||
|
||||
!g_ascii_strcasecmp (protocol, "sqlite3")));
|
||||
}
|
||||
|
||||
/* Checks if the given uri defines a file
|
||||
@ -78,6 +108,37 @@ gboolean gnc_uri_is_file_uri (const gchar *uri)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Checks if the given uri is a valid uri
|
||||
*/
|
||||
gboolean gnc_uri_targets_local_fs (const gchar *uri)
|
||||
{
|
||||
|
||||
gchar *protocol = NULL, *hostname = NULL;
|
||||
gchar *username = NULL, *password = NULL;
|
||||
gchar *path = NULL;
|
||||
gint port = 0;
|
||||
gboolean is_local_fs = FALSE;
|
||||
|
||||
gnc_uri_get_components ( uri, &protocol, &hostname, &port,
|
||||
&username, &password, &path );
|
||||
|
||||
/* For gnucash to consider a uri to target the local fs:
|
||||
* path must not be NULL
|
||||
* AND
|
||||
* protocol should be NULL
|
||||
* OR
|
||||
* protocol must be file type protocol (file, xml, sqlite) */
|
||||
is_local_fs = (path && (!protocol || gnc_uri_is_file_protocol(protocol)));
|
||||
|
||||
g_free (protocol);
|
||||
g_free (hostname);
|
||||
g_free (username);
|
||||
g_free (password);
|
||||
g_free (path);
|
||||
|
||||
return is_local_fs;
|
||||
}
|
||||
|
||||
/* Splits a uri into its separate components */
|
||||
void gnc_uri_get_components (const gchar *uri,
|
||||
gchar **protocol,
|
||||
@ -103,9 +164,9 @@ void gnc_uri_get_components (const gchar *uri,
|
||||
splituri = g_strsplit ( uri, "://", 2 );
|
||||
if ( splituri[1] == NULL )
|
||||
{
|
||||
/* No protocol means simple file uri */
|
||||
*protocol = g_strdup ( "file" );
|
||||
*path = g_strdup ( splituri[0] );
|
||||
/* No protocol means simple file path.
|
||||
Set path to copy of the input. */
|
||||
*path = g_strdup ( uri );
|
||||
g_strfreev ( splituri );
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,25 @@
|
||||
* (being protocol, host name, port, user name, password and path) or
|
||||
* to compose a uri from these separate components.
|
||||
*
|
||||
* A full uri can be described as:
|
||||
*
|
||||
* @li @c proto://[[username[:password]@]hostname[:port]]/path (universal uri)
|
||||
* @li @c file://[localhost]/path (uri refering to a file on the local file system)
|
||||
*
|
||||
* Anything in square brackets is optional.
|
||||
*
|
||||
* While not strictly uris this function will also accept input in the form
|
||||
* of a local file system path for convenience:
|
||||
*
|
||||
* @li @c some/filesystem/path A simple relative file system path (unix style)
|
||||
* @li @c /some/filesystem/path A simple absolute file system path (unix style)
|
||||
* @li @c some\\windows\\path A simple relative file system path (Windows style)
|
||||
* @li @c c:\\some\\windows\\path A simple file system path (Windows style)
|
||||
*
|
||||
* The local path will then be considered as the path component of a uri where
|
||||
* appropriate. In case of conversion from a file system path to a uri the relative
|
||||
* paths will be converted to absolute paths as uris don't allow relative paths.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GNCURIUTILS_H_
|
||||
@ -42,33 +61,35 @@
|
||||
#define GNC_DATAFILE_EXT ".gnucash"
|
||||
#define GNC_LOGFILE_EXT ".log"
|
||||
|
||||
/** Checks if the given uri is a valid uri
|
||||
*
|
||||
* A valid uri is defined by having at least a protocol and a path.
|
||||
* If the uri is not referring to a file on the local file system
|
||||
* a hostname should be set as well.
|
||||
*
|
||||
* @param uri The uri to check
|
||||
*
|
||||
* @return TRUE if the input is a valid uri, FALSE otherwise
|
||||
*/
|
||||
gboolean gnc_uri_is_uri (const gchar *uri);
|
||||
|
||||
/** Converts a uri in separate components.
|
||||
*
|
||||
* Uri's can take any of the following forms:
|
||||
*
|
||||
* @li @c /some/filesystem/path A simple file system path (unix style)
|
||||
* @li @c c:\\some\\windows\\path A simple file system path (Windows style)
|
||||
* @li @c proto://[[username[:password]@]hostname[:port]]/path (universal uri)
|
||||
*
|
||||
* In the last form, anything in square brackets is optional.
|
||||
*
|
||||
* The function allocates memory for each of the components that it finds
|
||||
* in the uri. The calling function should free this memory with g_free
|
||||
* if the items are no longer needed.
|
||||
* when the items are no longer needed.
|
||||
*
|
||||
* @param uri The uri to convert
|
||||
*
|
||||
* @param protocol The protocol for this uri. If the uri didn't have an
|
||||
* explicit protocol, 'file' will be the assumed protocol and hence what
|
||||
* will be returned.
|
||||
* explicit protocol, NULL will be returned.
|
||||
* @param hostname The host name of the server to connect to. In case of
|
||||
* the 'file' protocol, this will be NULL
|
||||
* the local file system path, NULL will be returned
|
||||
* @param port An optional port to connect to or 0 if the default port is to
|
||||
* be used. For the 'file' protocol this is always 0 as well.
|
||||
* be used. For local filesystem path this is always 0 as well.
|
||||
* @param username Optional user name found in this uri or NULL if none is found.
|
||||
* @param password Optional password found in this uri or NULL if none is found.
|
||||
* @param path The path found in this uri. Note that if the protocol is a file based
|
||||
* protocol, the path will be converted to an absolute path.
|
||||
* @param path The path found in this uri.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -81,14 +102,6 @@ void gnc_uri_get_components (const gchar *uri,
|
||||
gchar **path);
|
||||
|
||||
/** Extracts the protocol from a uri
|
||||
*
|
||||
* Uri's can take any of the following forms:
|
||||
*
|
||||
* @li @c /some/filesystem/path A simple file system path (unix style)
|
||||
* @li @c c:\\some\\windows\\path A simple file system path (Windows style)
|
||||
* @li @c proto://[[username[:password]@]hostname[:port]]/path (universal uri)
|
||||
*
|
||||
* In the last form, anything in square brackets is optional.
|
||||
*
|
||||
* The function allocates memory for the protocol. The calling function should
|
||||
* free this memory with g_free if it no longer needs the string.
|
||||
@ -96,20 +109,12 @@ void gnc_uri_get_components (const gchar *uri,
|
||||
* @param uri The uri to extract the protocol from
|
||||
*
|
||||
* @return The protocol for this uri. If the uri didn't have an
|
||||
* explicit protocol, 'file' will be returned as protocol.
|
||||
* explicit protocol, NULL will be returned.
|
||||
*/
|
||||
|
||||
gchar *gnc_uri_get_protocol (const gchar *uri);
|
||||
|
||||
/** Extracts the path part from a uri
|
||||
*
|
||||
* Uri's can take any of the following forms:
|
||||
*
|
||||
* @li @c /some/filesystem/path A simple file system path (unix style)
|
||||
* @li @c c:\\some\\windows\\path A simple file system path (Windows style)
|
||||
* @li @c proto://[[username[:password]@]hostname[:port]]/path (universal uri)
|
||||
*
|
||||
* In the last form, anything in square brackets is optional.
|
||||
*
|
||||
* The function allocates memory for the path. The calling function should
|
||||
* free this memory with g_free if it no longer needs the string.
|
||||
@ -160,8 +165,8 @@ gchar *gnc_uri_create_uri (const gchar *protocol,
|
||||
/** Composes a normalized uri starting from any uri (filename, db spec,...).
|
||||
*
|
||||
* The resulting uri will take either of these forms:
|
||||
* @li @c file:///some/absolute/path (file could also be xml or sqlite)
|
||||
* @li @c file://c:\\some\\windows\\path (file could also be xml or sqlite)
|
||||
* @li @c file:///some/absolute/path ('file' can also be xml or sqlite)
|
||||
* @li @c file://c:\\some\\windows\\path ('file' can also be xml or sqlite)
|
||||
* @li @c protocol://[user[:password]@]hostname[:port]/path
|
||||
*
|
||||
* Only the components that are provided will be inserted in the uri. The
|
||||
@ -182,6 +187,19 @@ gchar *gnc_uri_create_uri (const gchar *protocol,
|
||||
gchar *gnc_uri_normalize_uri (const gchar *uri, gboolean allow_password);
|
||||
|
||||
|
||||
/** Checks if the given uri is a valid uri
|
||||
*
|
||||
* A valid uri is defined by having at least a protocol and a path.
|
||||
* If the uri is not referring to a file on the local file system
|
||||
* a hostname should be set as well.
|
||||
*
|
||||
* @param uri The uri to check
|
||||
*
|
||||
* @return TRUE if the input is a valid uri, FALSE otherwise
|
||||
*/
|
||||
gboolean gnc_uri_is_uri (const gchar *uri);
|
||||
|
||||
|
||||
/** Checks if there is a backend that explicitly stated to handle the given protocol.
|
||||
*
|
||||
* @param protocol The protocol to check
|
||||
@ -190,6 +208,7 @@ gchar *gnc_uri_normalize_uri (const gchar *uri, gboolean allow_password);
|
||||
*/
|
||||
gboolean gnc_uri_is_known_protocol (const gchar *protocol);
|
||||
|
||||
|
||||
/** Checks if the given protocol is used to refer to a file
|
||||
* (as opposed to a network service like a database or web url)
|
||||
*
|
||||
@ -210,6 +229,19 @@ gboolean gnc_uri_is_file_protocol (const gchar *protocol);
|
||||
*/
|
||||
gboolean gnc_uri_is_file_uri (const gchar *uri);
|
||||
|
||||
/** Checks if the given uri is either a valid file uri or a local filesystem path
|
||||
*
|
||||
* A valid uri is defined by having at least a protocol and a path.
|
||||
* If the uri is not referring to a file on the local file system
|
||||
* a hostname should be set as well.
|
||||
*
|
||||
* @param uri The uri to check
|
||||
*
|
||||
* @return TRUE if the input is a valid file uri or a local filesystem path.
|
||||
* FALSE otherwise
|
||||
*/
|
||||
gboolean gnc_uri_targets_local_fs (const gchar *uri);
|
||||
|
||||
/** Adds an extension to the uri if:
|
||||
* * the uri is not empty and file based
|
||||
* * doesn't already have the extension
|
||||
|
@ -56,9 +56,9 @@ test_strings strs[] =
|
||||
/* basic file tests in posix like environment */
|
||||
{
|
||||
"/test/path/file.gnucash", FALSE,
|
||||
"file", NULL, NULL, NULL, "/test/path/file.gnucash", 0,
|
||||
NULL, NULL, NULL, NULL, "/test/path/file.gnucash", 0,
|
||||
"file:///test/path/file.gnucash",
|
||||
"file:///test/path/file.gnucash", TRUE
|
||||
"file:///test/path/file.gnucash", FALSE
|
||||
},
|
||||
{
|
||||
"file:///test/path/file.gnucash", FALSE,
|
||||
@ -82,9 +82,9 @@ test_strings strs[] =
|
||||
/* basic file tests in windows environment */
|
||||
{
|
||||
"c:\\test\\path\\file.gnucash", FALSE,
|
||||
"file", NULL, NULL, NULL, "c:\\test\\path\\file.gnucash", 0,
|
||||
NULL, NULL, NULL, NULL, "c:\\test\\path\\file.gnucash", 0,
|
||||
"file://c:\\test\\path\\file.gnucash",
|
||||
"file://c:\\test\\path\\file.gnucash", TRUE
|
||||
"file://c:\\test\\path\\file.gnucash", FALSE
|
||||
},
|
||||
{
|
||||
"file://c:\\test\\path\\file.gnucash", FALSE,
|
||||
|
Loading…
Reference in New Issue
Block a user