GnuCash 2.3.0
Files | Defines | Functions
Uri conversion
Utility functions

Files

file  gnc-uri-utils.h
 

Utility functions for convert uri in separate components and back.


Defines

#define GNC_DATAFILE_EXT   ".gnucash"
#define GNC_LOGFILE_EXT   ".log"

Functions

void gnc_uri_get_components (const gchar *uri, gchar **protocol, gchar **hostname, gint32 *port, gchar **username, gchar **password, gchar **path)
gchar * gnc_uri_get_protocol (const gchar *uri)
gchar * gnc_uri_get_path (const gchar *uri)
gchar * gnc_uri_create_uri (const gchar *protocol, const gchar *hostname, gint32 port, const gchar *username, const gchar *password, const gchar *path)
gchar * gnc_uri_normalize_uri (const gchar *uri, gboolean allow_password)
gboolean gnc_uri_is_known_protocol (const gchar *protocol)
gboolean gnc_uri_is_file_protocol (const gchar *protocol)
gboolean gnc_uri_is_file_uri (const gchar *uri)
gchar * gnc_uri_add_extension (const gchar *uri, const gchar *extension)

Function Documentation

gchar* gnc_uri_add_extension ( const gchar *  uri,
const gchar *  extension 
)

Adds an extension to the uri if: * the uri is not empty and file based * doesn't already have the extension

Parameters:
uriThe uri to process
extensionThe extension to add if missing. Note that the extension is added verbatim, so if a dot should be added, this should be part of the extension.
Returns:
The uri, but garanteed to end with extension if the uri is file based. Otherwise the uri is returned unmodified. Note that the returned value should be freed with g_free when no longer needed.

Definition at line 328 of file gnc-uri-utils.c.

{
    g_return_val_if_fail( uri != 0, NULL );

    /* Only add extension if the user provided the extension and the uri is
     * file based.
     */
    if ( !extension || !gnc_uri_is_file_uri( uri ) )
        return g_strdup( uri );

    /* Don't add extension if it's already there */
    if ( g_str_has_suffix( uri, extension ) )
        return g_strdup( uri );

    /* Ok, all tests passed, let's add the extension */
    return g_strconcat( uri, extension, NULL );
}
gchar* gnc_uri_create_uri ( const gchar *  protocol,
const gchar *  hostname,
gint32  port,
const gchar *  username,
const gchar *  password,
const gchar *  path 
)

Composes a normalized uri starting from its separate components.

The resulting uri will take either of these forms:

  • file:///some/absolute/path (file could also be xml or sqlite)
  • file://c:\some\windows\path (file could also be xml or sqlite)
  • protocol://[user[:password]@]hostname[:port]/path

Only the components that are provided will be inserted in the uri. However if no protocol has been provided, 'file' will be used as default protocol.

The function allocates memory for the uri. The calling function should free this memory with g_free the uri is no longer needed.

Parameters:
protocolThe protocol for this uri. If NULL,, 'file' will be used in the uri.
hostnameThe host name of the server to connect to. This will be ignored for the 'file' type protocols ('file', 'xml', 'sqlite').
portAn optional port to set o, the uri, or 0 if no port is to be set. This will be ignored for the 'file' type protocols ('file', 'xml', 'sqlite').
usernameOptional user name to set in the uri or NULL otherwise. This will be ignored for the 'file' type protocols ('file', 'xml', 'sqlite').
passwordOptional password to set in the uri or NULL otherwise. This will be ignored for the 'file' type protocols ('file', 'xml', 'sqlite').
pathThe path to set in the uri.
Returns:
The normalized uri.

Definition at line 237 of file gnc-uri-utils.c.

{
    gchar *userpass = NULL, *portstr = NULL, *uri = NULL;

    g_return_val_if_fail( path != 0, NULL );

    if ( (protocol == NULL) || gnc_uri_is_file_protocol ( protocol ) )
    {
        /* Compose a file based uri, which means ignore everything but
         * the protocol and the path
         * We return an absolute pathname if the protocol is known or
         * no protocol was given. For an unknown protocol, we return the
         * path info as is.
         */
        gchar *abs_path;
        if ( protocol && (!gnc_uri_is_known_protocol (protocol)) )
            abs_path = g_strdup ( path );
        else
            abs_path = gnc_resolve_file_path ( path );
        if ( protocol == NULL )
            uri = g_strdup_printf ( "file://%s", abs_path );
        else
            uri = g_strdup_printf ( "%s://%s", protocol, abs_path );
        g_free (abs_path);
        return uri;
    }

    /* Not a file based uri, we need to setup all components that are not NULL
     * For this scenario, hostname is mandatory.
     */
    g_return_val_if_fail( hostname != 0, NULL );

    if ( username != NULL && *username )
    {
        if ( password != NULL && *password )
            userpass = g_strdup_printf ( "%s:%s@", username, password );
        else
            userpass = g_strdup_printf ( "%s@", username );
    }
    else
        userpass = g_strdup ( "" );

    if ( port != 0 )
        portstr = g_strdup_printf ( ":%d", port );
    else
        portstr = g_strdup ( "" );

    // XXX Do I have to add the slash always or are there situations
    //     it is in the path already ?
    uri = g_strconcat ( protocol, "://", userpass, hostname, portstr, "/", path, NULL );

    g_free ( userpass );
    g_free ( portstr );

    return uri;

}
void gnc_uri_get_components ( const gchar *  uri,
gchar **  protocol,
gchar **  hostname,
gint32 *  port,
gchar **  username,
gchar **  password,
gchar **  path 
)

Converts a uri in separate components.

Uri's can take any of the following forms:

  • /some/filesystem/path A simple file system path (unix style)
  • c:\some\windows\path A simple file system path (Windows style)
  • 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.

Parameters:
uriThe uri to convert
protocolThe 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.
hostnameThe host name of the server to connect to. In case of the 'file' protocol, this will be NULL
portAn 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.
usernameOptional user name found in this uri or NULL if none is found.
passwordOptional password found in this uri or NULL if none is found.
pathThe path found in this uri. Note that if the protocol is a file based protocol, the path will be converted to an absolute path.

Definition at line 82 of file gnc-uri-utils.c.

{
    gchar **splituri, **spliturl;
    gchar *url = NULL, *tmpusername = NULL, *tmphostname = NULL;
    gchar *delimiter = NULL;

    *protocol = NULL;
    *hostname = NULL;
    *port      = 0;
    *username = NULL;
    *password = NULL;
    *path     = NULL;

    g_return_if_fail( uri != NULL );

    splituri = g_strsplit ( uri, "://", 2 );
    if ( splituri[1] == NULL )
    {
        /* No protocol means simple file uri */
        *protocol = g_strdup ( "file" );
        *path     = g_strdup ( splituri[0] );
        g_strfreev ( splituri );
        return;
    }

    /* At least a protocol was found, set it here */
    *protocol = g_strdup ( splituri[0] );

    if ( gnc_uri_is_file_protocol ( *protocol ) )
    {
        /* Protocol indicates file based uri.
         * Note that unknown protocols are treated as if they are
         * file-based protocols. This is done to prevent password
         * lookups on unknown protocols.
         * On the other hand, since we don't know the specifics of
         * unknown protocols, we don't attempt to return an absolute
         * pathname for them, just whatever was there.
         */
        if ( gnc_uri_is_known_protocol ( *protocol ) )
            *path     = gnc_resolve_file_path ( splituri[1] );
        else
            *path     = g_strdup ( splituri[1] );
        g_strfreev ( splituri );
        return;
    }

    /* Protocol indicates full network style uri, let's see if it
     * has a username and/or password
     */
    url = g_strdup (splituri[1]);
    g_strfreev ( splituri );

    /* Check for "@" sign, but start from the end - the password may contain
     * this sign as well
     */
    delimiter = g_strrstr ( url, "@" );
    if ( delimiter != NULL )
    {
        /* There is at least a username in the url */
        delimiter[0] = '\0';
        tmpusername = url;
        tmphostname = delimiter + 1;

        /* Check if there's a password too by looking for a :
         * Start from the beginning this time to avoid possible :
         * in the password */
        delimiter = g_strstr_len ( tmpusername, -1, ":" );
        if ( delimiter != NULL )
        {
            /* There is password in the url */
            delimiter[0] = '\0';
            *password = g_strdup ( (const gchar*)(delimiter + 1) );
        }
        *username = g_strdup ( (const gchar*)tmpusername );
    }
    else
    {
        /* No username and password were given */
        tmphostname = url;
    }

    /* Find the path part */
    delimiter = g_strstr_len ( tmphostname, -1, "/" );
    if ( delimiter != NULL )
    {
        delimiter[0] = '\0';
        if ( gnc_uri_is_file_protocol ( *protocol ) ) /* always return absolute file paths */
            *path = gnc_resolve_file_path ( (const gchar*)(delimiter + 1) );
        else /* path is no file path, so copy it as is */
            *path = g_strdup ( (const gchar*)(delimiter + 1) );
    }

    /* Check for a port specifier */
    delimiter = g_strstr_len ( tmphostname, -1, ":" );
    if ( delimiter != NULL )
    {
        delimiter[0] = '\0';
        *port = g_ascii_strtoll ( delimiter + 1, NULL, 0 );
    }

    *hostname = g_strdup ( (const gchar*)tmphostname );

    g_free ( url );

    return;

}
gchar* gnc_uri_get_path ( const gchar *  uri)

Extracts the path part from a uri

Uri's can take any of the following forms:

  • /some/filesystem/path A simple file system path (unix style)
  • c:\some\windows\path A simple file system path (Windows style)
  • 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.

Parameters:
uriThe uri to extract the path part from
Returns:
The protocol for this uri, or NULL if no path could be extracted.

Definition at line 216 of file gnc-uri-utils.c.

{
    gchar *protocol = NULL;
    gchar *hostname = NULL;
    gint32 port = 0;
    gchar *username = NULL;
    gchar *password = NULL;
    gchar *path     = NULL;

    gnc_uri_get_components ( uri, &protocol, &hostname, &port,
                             &username, &password, &path );

    g_free (protocol);
    g_free (hostname);
    g_free (username);
    g_free (password);

    return path;
}
gchar* gnc_uri_get_protocol ( const gchar *  uri)

Extracts the protocol from a uri

Uri's can take any of the following forms:

  • /some/filesystem/path A simple file system path (unix style)
  • c:\some\windows\path A simple file system path (Windows style)
  • 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.

Parameters:
uriThe uri to extract the protocol from
Returns:
The protocol for this uri. If the uri didn't have an explicit protocol, 'file' will be returned as protocol.

Definition at line 196 of file gnc-uri-utils.c.

{
    gchar *protocol = NULL;
    gchar *hostname = NULL;
    gint32 port     = 0;
    gchar *username = NULL;
    gchar *password = NULL;
    gchar *path     = NULL;

    gnc_uri_get_components ( uri, &protocol, &hostname, &port,
                             &username, &password, &path );

    g_free (hostname);
    g_free (username);
    g_free (password);
    g_free (path);

    return protocol;
}
gboolean gnc_uri_is_file_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)

Parameters:
protocolThe protocol to check
Returns:
TRUE if the protocol is used with files, FALSE of the protocol is normally used with network services (database, web url,...)

Definition at line 58 of file gnc-uri-utils.c.

{
    if ( !g_ascii_strcasecmp (protocol, "mysql") ||
            !g_ascii_strcasecmp (protocol, "postgres")
       )
        return FALSE;
    else
        return TRUE;
}
gboolean gnc_uri_is_file_uri ( const gchar *  uri)

Checks if the given uri defines a file (as opposed to a network service like a database or web url)

Parameters:
uriThe uri to check
Returns:
TRUE if the uri is a files, FALSE of the protocol is normally used with network services (database, web url,...)

Definition at line 71 of file gnc-uri-utils.c.

{
    gchar *protocol = gnc_uri_get_protocol ( uri );
    gboolean result = gnc_uri_is_file_protocol ( protocol );

    g_free ( protocol );

    return result;
}
gboolean gnc_uri_is_known_protocol ( const gchar *  protocol)

Checks if there is a backend that explicitly stated to handle the given protocol.

Parameters:
protocolThe protocol to check
Returns:
TRUE if at least one backend explicitly handles this protocol, otherwise FALSE

Definition at line 33 of file gnc-uri-utils.c.

{
    gboolean is_known_proto = FALSE;
    GList *node;
    GList *known_proto_list = qof_backend_get_registered_access_method_list();

    for ( node = known_proto_list; node != NULL; node = node->next )
    {
        gchar *known_proto = node->data;
        if ( !g_ascii_strcasecmp (protocol, known_proto) )
        {
            is_known_proto = TRUE;
            break;
        }
    }

    g_list_free (known_proto_list);
    return is_known_proto;
}
gchar* gnc_uri_normalize_uri ( const gchar *  uri,
gboolean  allow_password 
)

Composes a normalized uri starting from any uri (filename, db spec,...).

The resulting uri will take either of these forms:

  • file:///some/absolute/path (file could also be xml or sqlite)
  • file://c:\some\windows\path (file could also be xml or sqlite)
  • protocol://[user[:password]@]hostname[:port]/path

Only the components that are provided will be inserted in the uri. The allow_password parameter controls if the password should be added to the returned uri when available. If no protocol has been provided, 'file' will be used as default protocol.

The function allocates memory for the uri. The calling function should free this memory with g_free the uri is no longer needed.

Parameters:
uriThe uri that schould be converted into a normalized uri
allow_passwordIf set to TRUE, the normalized uri and the input uri has a password, this passworld will also be set in the normalized uri. Otherwise no password will be set in the normalized uri.
Returns:
The normalized uri.

Definition at line 300 of file gnc-uri-utils.c.

{
    gchar *protocol = NULL;
    gchar *hostname = NULL;
    gint32 port = 0;
    gchar *username = NULL;
    gchar *password = NULL;
    gchar *path     = NULL;
    gchar *newuri   = NULL;

    gnc_uri_get_components ( uri, &protocol, &hostname, &port,
                             &username, &password, &path );
    if (allow_password)
        newuri = gnc_uri_create_uri ( protocol, hostname, port,
                                      username, password, path);
    else
        newuri = gnc_uri_create_uri ( protocol, hostname, port,
                                      username, /* no password */ NULL, path);

    g_free (protocol);
    g_free (hostname);
    g_free (username);
    g_free (password);
    g_free (path);

    return newuri;
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines