diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index 60b4450..be37656 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <unistd.h>
#include "logging.h"
phonebook_cb cb;
gpointer user_data;
const struct apparam_field *apparams;
+ int fd;
};
static gchar *root_folder = NULL;
+static int dirfd = -1;
+
+static void dummy_free(gpointer user_data)
+{
+ struct dummy_data *dummy = user_data;
+
+ if (dummy->fd >= 0)
+ close(dummy->fd);
+
+ g_free(dummy);
+}
int phonebook_init(void)
{
void phonebook_exit(void)
{
g_free(root_folder);
+
+ if (dirfd >= 0)
+ close(dirfd);
}
static gboolean dummy_result(gpointer data)
return FALSE;
}
-static gboolean is_dir(const gchar *dir)
+static gboolean read_entry(gpointer user_data)
+{
+ struct dummy_data *dummy = user_data;
+ char buffer[1024];
+ ssize_t count;
+
+ memset(buffer, 0, sizeof(buffer));
+ count = read(dummy->fd, buffer, sizeof(buffer));
+
+ if (count < 0) {
+ int err = errno;
+ error("read(): %s(%d)", strerror(err), err);
+ count = 0;
+ }
+
+ /* FIXME: Missing vCards fields filtering */
+
+ dummy->cb(buffer, count, 1, 0, dummy->user_data);
+
+ return FALSE;
+}
+
+static int open_folder(const char *folder)
{
struct stat st;
+ int fd, err;
- if (stat(dir, &st) < 0)
- return FALSE;
+ if (stat(folder, &st) < 0) {
+ err = errno;
+ error("stat(): %s(%d)", strerror(err), err);
+ return -err;
+ }
- return S_ISDIR(st.st_mode);
+ 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;
+ }
+
+ return fd;
}
gchar *phonebook_set_folder(const gchar *current_folder,
{
gboolean root, child;
gchar *tmp1, *tmp2, *base, *absolute, *relative = NULL;
- int ret, len;
+ int ret, len, fd;
root = (g_strcmp0("/", current_folder) == 0);
child = (new_folder && strlen(new_folder) != 0);
}
absolute = g_build_filename(root_folder, relative, NULL);
- if (!is_dir(absolute)) {
+ fd = open_folder(absolute);
+ if (fd < 0) {
ret = -EBADR;
g_free(relative);
relative = NULL;
+ } else {
+ /* Keep the current dirfd open */
+ if (dirfd >= 0)
+ close(dirfd);
+
+ dirfd = fd;
}
g_free(absolute);
dummy->user_data = user_data;
dummy->apparams = params;
- g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
- dummy_result, dummy, g_free);
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, dummy_result, dummy,
+ dummy_free);
return 0;
}
int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data)
{
- return -1;
+ struct dummy_data *dummy;
+ int fd;
+
+ if (dirfd < 0)
+ return -EBADR;
+
+ fd = openat(dirfd, id, 0);
+ if (fd < 0) {
+ int err = errno;
+ debug("openat(): %s(%d)", strerror(err), err);
+ return -EBADR;
+ }
+
+ dummy = g_new0(struct dummy_data, 1);
+ dummy->cb = cb;
+ dummy->user_data = user_data;
+ dummy->apparams = params;
+ dummy->fd = fd;
+
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, read_entry, dummy, dummy_free);
+
+ return 0;
}
int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb,