From 5929aea1edf700486babbcf6294cf3e7927eef09 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 9 Apr 2010 14:30:04 -0300 Subject: [PATCH] obexd: Add SetPhoneBook function for dummy back-end Current PBAP dummy implementation has a fixed root folder: $HOME/phonebook. It doesn't follow the fixed PBAP virtual folder architecture, it only checks if the folder exists in the file system. --- obexd/plugins/phonebook-dummy.c | 98 ++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c index 5acbf6923..60b4450ab 100644 --- a/obexd/plugins/phonebook-dummy.c +++ b/obexd/plugins/phonebook-dummy.c @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include "logging.h" #include "phonebook.h" @@ -47,13 +51,19 @@ struct dummy_data { const struct apparam_field *apparams; }; +static gchar *root_folder = NULL; + int phonebook_init(void) { + /* FIXME: It should NOT be hard-coded */ + root_folder = g_build_filename(getenv("HOME"), "phonebook", NULL); + return 0; } void phonebook_exit(void) { + g_free(root_folder); } static gboolean dummy_result(gpointer data) @@ -65,13 +75,97 @@ static gboolean dummy_result(gpointer data) return FALSE; } +static gboolean is_dir(const gchar *dir) +{ + struct stat st; + + if (stat(dir, &st) < 0) + return FALSE; + + return S_ISDIR(st.st_mode); +} + gchar *phonebook_set_folder(const gchar *current_folder, const gchar *new_folder, guint8 flags, int *err) { + gboolean root, child; + gchar *tmp1, *tmp2, *base, *absolute, *relative = NULL; + int ret, len; + + root = (g_strcmp0("/", current_folder) == 0); + child = (new_folder && strlen(new_folder) != 0); + + switch (flags) { + case 0x02: + /* Go back to root */ + if (!child) { + relative = g_strdup("/"); + goto done; + } + + relative = g_build_filename(current_folder, new_folder, NULL); + break; + case 0x03: + /* Go up 1 level */ + if (root) { + /* Already root */ + ret = -EBADR; + goto done; + } + + /* + * Removing one level of the current folder. Current folder + * contains AT LEAST one level since it is not at root folder. + * Use glib utility functions to handle invalid chars in the + * folder path properly. + */ + tmp1 = g_path_get_basename(current_folder); + tmp2 = g_strrstr(current_folder, tmp1); + len = tmp2 - (current_folder + 1); + + g_free(tmp1); + + if (len == 0) + base = g_strdup("/"); + else + base = g_strndup(current_folder, len); + + /* Return: one level only */ + if (!child) { + relative = base; + goto done; + } + + relative = g_build_filename(base, new_folder, NULL); + g_free(base); + + break; + default: + ret = -EBADR; + break; + } + +done: + if (!relative) { + if (err) + *err = ret; + + return NULL; + } + + absolute = g_build_filename(root_folder, relative, NULL); + if (!is_dir(absolute)) { + ret = -EBADR; + g_free(relative); + relative = NULL; + } + + g_free(absolute); + if (err) - *err = -EINVAL; + *err = ret; - return NULL; + return relative; } int phonebook_pull(const gchar *name, const struct apparam_field *params, -- 2.47.3