Diff between 5929aea1edf700486babbcf6294cf3e7927eef09 and c5cafe4a6cf06a01ade8ed65c4e4cd11f7924a30

Changed Files

File Additions Deletions Status
obexd/plugins/phonebook-dummy.c +93 -9 modified

Full Patch

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
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 
 #include "logging.h"
@@ -49,9 +50,21 @@ struct dummy_data {
 	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)
 {
@@ -64,6 +77,9 @@ int phonebook_init(void)
 void phonebook_exit(void)
 {
 	g_free(root_folder);
+
+	if (dirfd >= 0)
+		close(dirfd);
 }
 
 static gboolean dummy_result(gpointer data)
@@ -75,14 +91,54 @@ 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,
@@ -90,7 +146,7 @@ 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);
@@ -154,10 +210,17 @@ done:
 	}
 
 	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);
@@ -178,15 +241,36 @@ int phonebook_pull(const gchar *name, const struct apparam_field *params,
 	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,