GnuCash 2.3.0
Files | Defines | Functions
File
Utility functions

Files

file  file-utils.h
 

Utility functions for file access.


Defines

#define STATE_FILE_TOP   "Top"
#define STATE_FILE_BOOK_GUID   "BookGuid"
#define STATE_FILE_EXT   ".gcm"

Functions

char * gncFindFile (const char *filename)
int gncReadFile (const char *filename, char **data)
gint64 gnc_getline (gchar **line, FILE *file)
GKeyFile * gnc_find_state_file (const gchar *url, const gchar *guid, gchar **filename)

Function Documentation

GKeyFile* gnc_find_state_file ( const gchar *  url,
const gchar *  guid,
gchar **  filename 
)

Find the state file that corresponds to this URL and guid.

The URL is used to compute the base name of the file (which will be in ~/.gnucash/books) and the guid is used to differentiate when the user has multiple data files with the same name.

Parameters:
urlThe url of the data file being used.
guidThe guid of the book associated with this data file.
filenameReturn the next available file name if the data file cannot be found.
Returns:
The name of the data file that was located.

Definition at line 206 of file file-utils.c.

{
    gchar *basename, *original = NULL, *filename, *tmp, *file_guid;
    gchar *sf_extension = NULL, *newstyle_filename = NULL;
    GKeyFile *key_file = NULL;
    gint i;

    ENTER("url %s, guid %s", url, guid);

    if ( gnc_uri_is_file_uri ( url ) )
    {
        /* The url is a true file, use its basename. */
        gchar *path = gnc_uri_get_path ( url );
        basename = g_path_get_basename ( path );
        g_free ( path );
    }
    else
    {
        /* The url is composed of database connection parameters. */
        gchar* protocol = NULL;
        gchar* host = NULL;
        gchar* dbname = NULL;
        gchar* username = NULL;
        gchar* password = NULL;
        gint portnum = 0;
        gnc_uri_get_components ( url, &protocol, &host, &portnum,
                                 &username, &password, &dbname );

        basename = g_strjoin("_", protocol, host, username, dbname, NULL);
        g_free( protocol );
        g_free( host );
        g_free( username );
        g_free( password );
        g_free( dbname );
    }

    DEBUG("Basename %s", basename);
    original = gnc_build_book_path(basename);
    g_free(basename);
    DEBUG("Original %s", original);

    sf_extension = g_strdup(STATE_FILE_EXT);
    i = 1;
    while (1)
    {
        if (i == 1)
            filename = g_strconcat(original, sf_extension, NULL);
        else
            filename = g_strdup_printf("%s_%d%s", original, i, sf_extension);
        DEBUG("Trying %s", filename);
        key_file = gnc_key_file_load_from_file(filename, FALSE, FALSE, NULL);
        DEBUG("Result %p", key_file);

        if (!key_file)
        {
            DEBUG("No key file by that name");
            if (g_strcmp0(sf_extension, STATE_FILE_EXT) == 0)
            {
                DEBUG("Trying old state file names for compatibility");
                newstyle_filename = filename;
                i = 1;
                g_free( sf_extension);
                sf_extension = g_strdup("");
                continue;
            }
            break;
        }

        file_guid = g_key_file_get_string(key_file,
                                          STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
                                          NULL);
        DEBUG("File GncGUID is %s", file_guid ? file_guid : "<not found>");
        if (safe_strcmp(guid, file_guid) == 0)
        {
            DEBUG("Matched !!!");
            g_free(file_guid);
            break;
        }
        DEBUG("Clean up this pass");
        g_free(file_guid);
        g_key_file_free(key_file);
        g_free(filename);
        i++;
    }

    DEBUG("Clean up");
    g_free(original);
    /* Pre-2.4.1 compatibility block: make sure when the state file is
     * written again later, it will use the next available filename with
     * extension and optional counter. (This name was determined earlier
     * in the loop.) */
    if (newstyle_filename)
    {
        g_free(filename);
        filename = newstyle_filename;
    }

    if (filename_p)
        *filename_p = filename;
    else
        g_free(filename);
    LEAVE("key_file %p, filename %s", key_file,
          filename_p ? *filename_p : "(none)");
    return key_file;
}
gint64 gnc_getline ( gchar **  line,
FILE *  file 
)

Read a line from the input file, up to and including the newline.

The caller MUST g_free() the line returned from this call in all cases where it is non-NULL!

Parameters:
linepointer to hold the buffer for the whole line (allocated by this function)
filethe file from which to read
Returns:
The number of bytes read

Definition at line 162 of file file-utils.c.

{
    char str[BUFSIZ];
    gint64 len;
    GString *gs;

    g_return_val_if_fail(line, -1);
    *line = NULL;
    g_return_val_if_fail(file, -1);

    gs = g_string_new("");

    while (fgets(str, sizeof(str), file) != NULL)
    {
        g_string_append(gs, str);

        len = strlen(str);
        if (str[len-1] == '\n')
            break;
    }

    len = gs->len;
    *line = gs->str;
    g_string_free(gs, FALSE);
    return len;
}
char* gncFindFile ( const char *  filename)

Locates a file in the search path of the program and returns its absolute pathname.

If the file is not found this function will return NULL.

Uses the global xxxPath as the path to search

Parameters:
filenameThe filename to search
Returns:
The absolute path to the file or NULL if the file wasn't found.

Definition at line 55 of file file-utils.c.

{
    char *full_filename = NULL;
    char * return_string = NULL;
    SCM find_doc_file;
    SCM scm_filename;
    SCM scm_result;

    if (!filename || *filename == '\0')
        return NULL;

    find_doc_file = scm_c_eval_string("gnc:find-doc-file");
    scm_filename = scm_makfrom0str ((char *) filename);
    scm_result = scm_call_1(find_doc_file, scm_filename);

    if (scm_is_string(scm_result))
    {
        char * str;

        scm_dynwind_begin (0);
        full_filename = scm_to_locale_string(scm_result);
        return_string = g_strdup (full_filename);
        scm_dynwind_free (full_filename);
        scm_dynwind_end ();
    }

    return return_string;
}
int gncReadFile ( const char *  filename,
char **  data 
)

Reads the contents of a file into a buffer for further processing.

If the filename is not an absolute filename, it will be searched for in the search path available to the program. This can be used to find for example help files,...

Uses the global xxxPath as the path to search

Parameters:
filenamethe name of the html file to read
dataPointer to a buffer to store the file's content.
Returns:
The file size

Definition at line 93 of file file-utils.c.

{
    char *buf = NULL;
    char  *fullname;
    int   size = 0;
    int   fd;

    /* construct absolute path -- twiddle the relative path we received */
    if (!filename || filename[0] == '\0') return 0;

    /* take absolute paths without searching */
    if (!g_path_is_absolute (filename))
        fullname = gncFindFile (filename);
    else
        fullname = g_strdup (filename);

    if (!fullname) return 0;

    /* Open file: */
    fd = g_open( fullname, O_RDONLY, 0 );

    g_free(fullname);
    fullname = NULL;

    if ( fd == -1 )
    {
        int norr = errno;
        PERR ("file %s: (%d) %s \n", filename, norr, strerror(norr));
        return 0;
    }

    /* Find size: */
    size = lseek( fd, 0, SEEK_END );
    lseek( fd, 0, SEEK_SET );

    /* Allocate memory */
    buf = g_new(char, size + 1);

    /* read in file */
    if ( read(fd, buf, size) == -1 )
    {
        g_free(buf);
        buf = NULL;
    }
    else
    {
        buf[size] = '\0';
    }

    close(fd);
    *data = buf;

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