Skip to content

Commit

Permalink
Redesign gnc-uri-utils
Browse files Browse the repository at this point in the history
- 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)
  • Loading branch information
gjanssens committed Dec 27, 2018
1 parent 06da9e9 commit 4b39832
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 65 deletions.
2 changes: 1 addition & 1 deletion gnucash/gnome-utils/dialog-file-access.c
Expand Up @@ -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 );
Expand Down
29 changes: 18 additions & 11 deletions gnucash/gnome-utils/gnc-file.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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 ! */
Expand Down Expand Up @@ -689,8 +689,10 @@ gnc_post_file_open (GtkWindow *parent, const char * filename, gboolean is_readon
* 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,
Expand Down Expand Up @@ -774,10 +776,11 @@ gnc_post_file_open (GtkWindow *parent, const char * filename, gboolean is_readon
);
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,
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions gnucash/gnome-utils/gnc-main-window.c
Expand Up @@ -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) */
Expand Down Expand Up @@ -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. */
Expand Down
4 changes: 2 additions & 2 deletions gnucash/gnome-utils/gnc-plugin-file-history.c
Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion libgnucash/app-utils/gnc-state.c
Expand Up @@ -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);
Expand Down
83 changes: 72 additions & 11 deletions libgnucash/engine/gnc-uri-utils.c
Expand Up @@ -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)
*/
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -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;
}
Expand Down

0 comments on commit 4b39832

Please sign in to comment.