diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index fc77538..5e06df3 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
goto fail;
}
- sscanf(name, "%u.vcf", &handle);
+ if (sscanf(name, "%u.vcf", &handle) != 1) {
+ ret = -EBADR;
+ goto fail;
+ }
+
id = cache_find(&pbap->cache, handle);
if (!id) {
ret = -ENOENT;
goto fail;
}
- ret = phonebook_get_entry(id, pbap->params, query_result, pbap);
+ ret = phonebook_get_entry(pbap->folder, id, pbap->params, query_result,
+ pbap);
if (ret < 0)
goto fail;
diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index 72bd124..e015dc7 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
};
static gchar *root_folder = NULL;
-static int folderfd = -1;
static void dummy_free(gpointer user_data)
{
void phonebook_exit(void)
{
g_free(root_folder);
-
- if (folderfd >= 0)
- close(folderfd);
}
static gboolean dummy_result(gpointer data)
return FALSE;
}
-static int open_folder(const char *folder)
+static gboolean is_dir(const char *dir)
{
struct stat st;
- int fd, err;
-
- if (stat(folder, &st) < 0) {
- err = errno;
- error("stat(): %s(%d)", strerror(err), err);
- return -err;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- error("folder %s is not a folder!", folder);
- return -EBADR;
- }
-
- debug("open_folder: %s", folder);
- fd = open(folder, O_RDONLY);
- if (fd < 0) {
- err = errno;
- error("open(): %s(%d)", strerror(err), err);
- return -err;
+ if (stat(dir, &st) < 0) {
+ int err = errno;
+ error("stat(%s): %s (%d)", dir, strerror(err), err);
+ return FALSE;
}
- return fd;
+ return S_ISDIR(st.st_mode);
}
gchar *phonebook_set_folder(const gchar *current_folder,
{
gboolean root, child;
gchar *tmp1, *tmp2, *base, *absolute, *relative = NULL;
- int ret, len, fd;
+ int ret, len;
root = (g_strcmp0("/", current_folder) == 0);
child = (new_folder && strlen(new_folder) != 0);
}
absolute = g_build_filename(root_folder, relative, NULL);
- fd = open_folder(absolute);
- if (fd < 0) {
- ret = -EBADR;
+ if (!is_dir(absolute)) {
g_free(relative);
relative = NULL;
- } else {
- /* Keep the current folderfd open */
- if (folderfd >= 0)
- close(folderfd);
-
- folderfd = fd;
+ ret = -EBADR;
}
g_free(absolute);
return 0;
}
-int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
+int phonebook_get_entry(const gchar *folder, const gchar *id,
+ const struct apparam_field *params,
phonebook_cb cb, gpointer user_data)
{
struct dummy_data *dummy;
+ char *filename;
int fd;
- if (folderfd < 0)
- return -EBADR;
+ filename = g_build_filename(root_folder, folder, id, NULL);
- fd = openat(folderfd, id, 0);
+ fd = open(filename, O_RDONLY);
if (fd < 0) {
int err = errno;
- debug("openat(): %s(%d)", strerror(err), err);
+ debug("open(): %s(%d)", strerror(err), err);
return -EBADR;
}
diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c
index a61ca83..140ca78 100644
--- a/obexd/plugins/phonebook-ebook.c
+++ b/obexd/plugins/phonebook-ebook.c
return 0;
}
-int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
+int phonebook_get_entry(const gchar *folder, const gchar *id,
+ const struct apparam_field *params,
phonebook_cb cb, gpointer user_data)
{
struct contacts_query *data;
diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h
index 324fc52..85f69a3 100644
--- a/obexd/plugins/phonebook.h
+++ b/obexd/plugins/phonebook.h
int phonebook_init(void);
void phonebook_exit(void);
+/*
+ * Changes the current folder in the phonebook back-end. The PBAP core
+ * doesn't validate or restrict the possible values for the folders,
+ * allowing non-standard backends implementation which doesn't follow
+ * the PBAP virtual folder architecture. Validate the folder's name
+ * is responsibility of the back-ends.
+*/
gchar *phonebook_set_folder(const gchar *current_folder,
const gchar *new_folder, guint8 flags, int *err);
/*
- * PullPhoneBook never use cached entries. PCE use this
- * function to get all entries of a given folder.
+ * PullPhoneBook never use cached entries. PCE use this function to get all
+ * entries of a given folder. The back-end MUST return only the content based
+ * on the application parameters requested by the client.
*/
int phonebook_pull(const gchar *name, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data);
-int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
- phonebook_cb cb, gpointer user_data);
+/*
+ * Function used to retrieve a contact from the backend. Only contacts
+ * found in the cache are requested to the back-ends. The back-end MUST
+ * return only the content based on the application parameters requested
+ * by the client.
+ */
+int phonebook_get_entry(const gchar *folder, const gchar *id,
+ const struct apparam_field *params,
+ phonebook_cb cb, gpointer user_data);
/*
* PBAP core will keep the contacts cache per folder. SetPhoneBook or
* PullvCardListing can invalidate the cache if the current folder changes.
+ * Cache will store only the necessary information required to reply to
+ * PullvCardListing request and verify if a given contact belongs to the source.
*/
int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb,
phonebook_cache_ready_cb ready_cb, gpointer user_data);