## rb-file-helpers

rb-file-helpers — An assortment of file and URI helper functions

## Synopsis

    const char *        rb_file                             (const char *filename);
    const char *        rb_user_data_dir                    (void);
    const char *        rb_user_cache_dir                   (void);
    const char *        rb_music_dir                        (void);
    char *              rb_find_user_data_file              (const char *name,
                                                             GError **error);
    char *              rb_find_user_cache_file             (const char *name,
                                                             GError **error);
    void                rb_file_helpers_init                (gboolean uninstalled);
    void                rb_file_helpers_shutdown            (void);
    char *              rb_uri_resolve_symlink              (const char *uri,
                                                             GError **error);
    gboolean            rb_uri_is_directory                 (const char *uri);
    gboolean            rb_uri_exists                       (const char *uri);
    gboolean            rb_uri_is_readable                  (const char *uri);
    gboolean            rb_uri_is_writable                  (const char *uri);
    gboolean            rb_uri_is_local                     (const char *uri);
    gboolean            rb_uri_is_hidden                    (const char *uri);
    gboolean            rb_uri_could_be_podcast             (const char *uri,
                                                             gboolean *is_opml);
    char *              rb_uri_make_hidden                  (const char *uri);
    void                rb_uri_handle_recursively           (const char *uri,
                                                             GCancellable *cancel,
                                                             RBUriRecurseFunc func,
                                                             gpointer user_data);
    void                rb_uri_handle_recursively_async     (const char *uri,
                                                             GCancellable *cancel,
                                                             RBUriRecurseFunc func,
                                                             gpointer user_data,
                                                             GDestroyNotify data_destroy);
    gboolean            rb_uri_mkstemp                      (const char *prefix,
                                                             char **uri_ret,
                                                             GOutputStream **stream,
                                                             GError **error);
    char *              rb_canonicalise_uri                 (const char *uri);
    char*               rb_uri_append_path                  (const char *uri,
                                                             const char *path);
    char*               rb_uri_append_uri                   (const char *uri,
                                                             const char *fragment);
    char *              rb_uri_get_dir_name                 (const char *uri);
    char *              rb_uri_get_short_path_name          (const char *uri);
    gboolean            rb_check_dir_has_space              (GFile *dir,
                                                             guint64 bytes_needed);
    gboolean            rb_check_dir_has_space_uri          (const char *uri,
                                                             guint64 bytes_needed);
    char *              rb_uri_get_mount_point              (const char *uri);
    gboolean            rb_uri_create_parent_dirs           (const char *uri,
                                                             GError **error);
    GFile *             rb_file_find_extant_parent          (GFile *file);
    char *              rb_uri_get_filesystem_type          (const char *uri);
    void                rb_sanitize_path_for_msdos_filesystem
                                                            (char *path);
    char *              rb_sanitize_uri_for_filesystem      (const char *uri);
    gboolean            (*RBUriRecurseFunc)                 (GFile *file,
                                                             gboolean dir,
                                                             gpointer data);

## Description

This is a variety of functions for dealing with files and URIs, including locating installed files, finding user cache and config directories, and dealing with file naming restrictions for various filesystems.

## Details

### rb_file ()

    const char *        rb_file                             (const char *filename);

Searches for an installed file, returning the full path name if found, NULL otherwise.

`filename` : | name of file to search for
Returns : | Full file name, if found. Must not be freed.

### rb_user_data_dir ()

    const char *        rb_user_data_dir                    (void);

This will create the rhythmbox user data directory, using the XDG Base Directory specification. If none of the XDG environment variables are set, this will be ~/.local/share/rhythmbox.

Returns : | string holding the path to the rhythmbox user data directory, or NULL if the directory does not exist and cannot be created.

### rb_user_cache_dir ()

    const char *        rb_user_cache_dir                   (void);

This will create the rhythmbox user cache directory, using the XDG Base Directory specification. If none of the XDG environment variables are set, this will be ~/.cache/rhythmbox.

Returns : | string holding the path to the rhythmbox user cache directory, or NULL if the directory does not exist and could not be created.

### rb_music_dir ()

    const char *        rb_music_dir                        (void);

Returns the default directory for the user's music library. This will usually be the 'Music' directory under the home directory.

Returns : | user's music directory. must not be freed.

### rb_find_user_data_file ()

    char *              rb_find_user_data_file              (const char *name,
                                                             GError **error);

Determines the full path to use for user-specific files, such as rhythmdb.xml. This first checks in the user data directory (see `rb_user_data_dir`). If the file does not exist in the user data directory, it then checks the old .gnome2 directory, moving the file to the user data directory if found there. If an error occurs while moving the file, this will be reported through `error` and the .gnome2 path will be returned.

`name` : | name of file to find
`error` : | returns error information
Returns : | allocated string containing the location of the file to use, even if an error occurred.

### rb_find_user_cache_file ()

    char *              rb_find_user_cache_file             (const char *name,
                                                             GError **error);

Determines the full path to use for user-specific cached files. This first checks in the user cache directory (see `rb_user_cache_dir`). If the file does not exist in the user cache directory, it then checks the old .gnome2 directory, moving the file to the user cache directory if found there. If an error occurs while moving the file, this will be reported through `error` and the .gnome2 path will be returned.

`name` : | name of file to find
`error` : | returns error information
Returns : | allocated string containing the location of the file to use, even if an error occurred.

### rb_file_helpers_init ()

    void                rb_file_helpers_init                (gboolean uninstalled);

Sets up file search paths for `rb_file`. Must be called on startup.

`uninstalled` : | if `TRUE`, search in source and build directories as well as installed locations

### rb_file_helpers_shutdown ()

    void                rb_file_helpers_shutdown            (void);

Frees various data allocated by file helper functions. Should be called on shutdown.

### rb_uri_resolve_symlink ()

    char *              rb_uri_resolve_symlink              (const char *uri,
                                                             GError **error);

Attempts to resolve symlinks in `uri` and return a canonical URI for the file it identifies.

`uri` : | the URI to process
`error` : | returns error information
Returns : | resolved URI, or NULL on error

### rb_uri_is_directory ()

    gboolean            rb_uri_is_directory                 (const char *uri);

Checks if `uri` identifies a directory.

`uri` : | the URI to check
Returns : | `TRUE` if `uri` is a directory

### rb_uri_exists ()

    gboolean            rb_uri_exists                       (const char *uri);

Checks if a URI identifies a resource that exists

`uri` : | a URI to check
Returns : | `TRUE` if `uri` exists

### rb_uri_is_readable ()

    gboolean            rb_uri_is_readable                  (const char *uri);

Checks if the user can read the resource identified by `uri`

`uri` : | a URI to check
Returns : | `TRUE` if `uri` is readable

### rb_uri_is_writable ()

    gboolean            rb_uri_is_writable                  (const char *uri);

Checks if the user can write to the resource identified by `uri`

`uri` : | a URI to check
Returns : | `TRUE` if `uri` is writable

### rb_uri_is_local ()

    gboolean            rb_uri_is_local                     (const char *uri);

Checks if `uri` identifies a local resource. Currently this just checks that it uses the 'file' URI scheme.

`uri` : | a URI to check
Returns : | `TRUE` if `uri` is local

### rb_uri_is_hidden ()

    gboolean            rb_uri_is_hidden                    (const char *uri);

Checks if `uri` is hidden, according to the Unix filename convention. If the filename component of `uri` begins with a dot, the file is considered hidden.

`uri` : | a URI to check
Returns : | `TRUE` if `uri` is hidden

### rb_uri_could_be_podcast ()

    gboolean            rb_uri_could_be_podcast             (const char *uri,
                                                             gboolean *is_opml);

Checks if `uri` identifies a resource that is probably a podcast (RSS or Atom feed). This does not perform any IO, it just guesses based on the URI itself.

`uri` : | a URI to check
`is_opml` : | returns whether the URI identifies an OPML document
Returns : | `TRUE` if `uri` may be a podcast

### rb_uri_make_hidden ()

    char *              rb_uri_make_hidden                  (const char *uri);

Constructs a URI that is similar to `uri` but which identifies a hidden file. This can be used for temporary files that should not be visible to the user while they are in use.

`uri` : | a URI to construct a hidden version of
Returns : | hidden URI, must be freed by the caller.

### rb_uri_handle_recursively ()

    void                rb_uri_handle_recursively           (const char *uri,
                                                             GCancellable *cancel,
                                                             RBUriRecurseFunc func,
                                                             gpointer user_data);

Calls `func` for each file found under the directory identified by `uri`. If `uri` identifies a file, calls `func` for that instead.

`uri` : | URI to visit
`cancel` : | an optional GCancellable to allow cancellation
`func` : | Callback function
`user_data` : | Data for callback function

### rb_uri_handle_recursively_async ()

    void                rb_uri_handle_recursively_async     (const char *uri,
                                                             GCancellable *cancel,
                                                             RBUriRecurseFunc func,
                                                             gpointer user_data,
                                                             GDestroyNotify data_destroy);

Calls `func` for each file found under the directory identified by `uri`, or if `uri` identifies a file, calls it once with that.

Directory recursion happens on a separate thread, but the callbacks are called on the main thread.

If non-NULL, `destroy_data` will be called once all files have been processed, or when the operation is cancelled.

`uri` : | the URI to visit
`cancel` : | a GCancellable to allow cancellation
`func` : | callback function
`user_data` : | data to pass to callback
`data_destroy` : | function to call to free `user_data`

### rb_uri_mkstemp ()

    gboolean            rb_uri_mkstemp                      (const char *prefix,
                                                             char **uri_ret,
                                                             GOutputStream **stream,
                                                             GError **error);

Creates a temporary file whose URI begins with `prefix`, returning the file URI and an output stream for writing to it.

`prefix` : | URI prefix
`uri_ret` : | returns the temporary file URI
`stream` : | returns a `GOutputStream` for the temporary file
`error` : | returns error information
Returns : | `TRUE` if successful

### rb_canonicalise_uri ()

    char *              rb_canonicalise_uri                 (const char *uri);

Converts `uri` to canonical URI form, ensuring it doesn't contain any redundant directory fragments or unnecessarily escaped characters. All URIs passed to RhythmDB functions should be canonicalised.

`uri` : | URI to canonicalise
Returns : | canonical URI, must be freed by caller

### rb_uri_append_path ()

    char*               rb_uri_append_path                  (const char *uri,
                                                             const char *path);

Creates a new URI consisting of `path` appended to `uri`.

`uri` : | the URI to append to
`path` : | the path fragment to append
Returns : | new URI, must be freed by caller

### rb_uri_append_uri ()

    char*               rb_uri_append_uri                   (const char *uri,
                                                             const char *fragment);

Creates a new URI consisting of `fragment` appended to `uri`. Generally isn't a good idea.

`uri` : | the URI to append to
`fragment` : | the URI fragment to append
Returns : | new URI, must be freed by caller

### rb_uri_get_dir_name ()

    char *              rb_uri_get_dir_name                 (const char *uri);

Returns the directory component of `uri`, that is, everything up to the start of the filename.

`uri` : | a URI
Returns : | new URI for parent of `uri`, must be freed by caller.

### rb_uri_get_short_path_name ()

    char *              rb_uri_get_short_path_name          (const char *uri);

Returns the filename component of `uri`, that is, everything after the final slash and before the start of the query string or fragment.

`uri` : | a URI
Returns : | filename component of `uri`, must be freed by caller

### rb_check_dir_has_space ()

    gboolean            rb_check_dir_has_space              (GFile *dir,
                                                             guint64 bytes_needed);

Checks that the filesystem holding `file` has at least `bytes_needed` bytes available.

`dir` : | a GFile to check
`bytes_needed` : | number of bytes to check for
Returns : | `TRUE` if enough space is available.

### rb_check_dir_has_space_uri ()

    gboolean            rb_check_dir_has_space_uri          (const char *uri,
                                                             guint64 bytes_needed);

Checks that the filesystem holding `uri` has at least `bytes_needed` bytes available.

`uri` : | a URI to check
`bytes_needed` : | number of bytes to check for
Returns : | `TRUE` if enough space is available.

### rb_uri_get_mount_point ()

    char *              rb_uri_get_mount_point              (const char *uri);

Returns the mount point of the filesystem holding `uri`. If `uri` is on a normal filesystem mount (such as /, /home, /var, etc.) this will be NULL.

`uri` : | a URI
Returns : | filesystem mount point (must be freed by caller) or NULL.

### rb_uri_create_parent_dirs ()

    gboolean            rb_uri_create_parent_dirs           (const char *uri,
                                                             GError **error);

Ensures that all parent directories of `uri` exist so that `uri` itself can be created directly.

`uri` : | a URI for which to create parent directories
`error` : | returns error information
Returns : | `TRUE` if successful

### rb_file_find_extant_parent ()

    GFile *             rb_file_find_extant_parent          (GFile *file);

Walks up the filesystem hierarchy to find a GFile representing the nearest extant ancestor of the specified file, which may be the file itself if it exists.

`file` : | a GFile to find an extant ancestor of
Returns : | GFile for the nearest extant ancestor

### rb_uri_get_filesystem_type ()

    char *              rb_uri_get_filesystem_type          (const char *uri);

Returns a string describing the type of the filesystem containing `uri`.

`uri` : | URI to get filesystem type for
Returns : | filesystem type string, must be freed by caller.

### rb_sanitize_path_for_msdos_filesystem ()

    void                rb_sanitize_path_for_msdos_filesystem
                                                            (char *path);

Modifies `path` such that it represents a legal path for MS DOS filesystems.

`path` : | a path to sanitize (modified in place)

### rb_sanitize_uri_for_filesystem ()

    char *              rb_sanitize_uri_for_filesystem      (const char *uri);

Removes characters from `uri` that are not allowed by the filesystem on which it would be stored. At present, this only supports MS DOS filesystems.

`uri` : | a URI to sanitize
Returns : | sanitized copy of `uri`, must be freed by caller.

### RBUriRecurseFunc ()

    gboolean            (*RBUriRecurseFunc)                 (GFile *file,
                                                             gboolean dir,
                                                             gpointer data);

`file` : |
`dir` : |
`data` : |
Returns : |