Diff between 217169ef49c638b8352e8c053e392c8b701a02bf and ad610c8397ca887244a39e7c5578bda95d1eb1ff

Changed Files

File Additions Deletions Status
obexd/plugins/pbap.c +6 -19 modified
obexd/plugins/phonebook-dummy.c +7 -3 modified
obexd/plugins/phonebook-ebook.c +54 -20 modified
obexd/plugins/phonebook.h +2 -2 modified

Full Patch

diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index 88f4769..3381f4b 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
@@ -218,13 +218,6 @@ static void cache_clear(struct cache *cache)
 	cache->entries = NULL;
 }
 
-static void set_folder(struct pbap_session *pbap, const gchar *new_folder)
-{
-	g_free(pbap->folder);
-
-	pbap->folder = new_folder ? g_strdup(new_folder) : NULL;
-}
-
 static void phonebook_size_result(const gchar *buffer, size_t bufsize,
 				gint vcards, gint missed, gpointer user_data)
 {
@@ -499,7 +492,7 @@ static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 	const gchar *name;
 	guint8 *nonhdr;
 	gchar *fullname;
-	int ret;
+	int err;
 
 	if (OBEX_ObjectGetNonHdrData(obj, &nonhdr) != 2) {
 		error("Set path failed: flag and constants not found!");
@@ -508,16 +501,12 @@ static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 
 	name = obex_get_name(os);
 
-	ret = phonebook_set_folder(pbap->folder, name, nonhdr[0]);
-	if (ret < 0)
-		return ret;
-
-	if (!pbap->folder)
-		fullname = g_strdup(name);
-	else
-		fullname = g_build_filename(pbap->folder, name, NULL);
+	fullname = phonebook_set_folder(pbap->folder, name, nonhdr[0], &err);
+	if (err < 0)
+		return err;
 
-	set_folder(pbap, fullname);
+	g_free(pbap->folder);
+	pbap->folder = fullname;
 
 	/*
 	 * FIXME: Define a criteria to mark the cache as invalid
@@ -526,8 +515,6 @@ static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
 	pbap->cache.index = 0;
 	cache_clear(&pbap->cache);
 
-	g_free(fullname);
-
 	return 0;
 }
 
diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index 02edf2a..5acbf69 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
@@ -26,6 +26,7 @@
 #include <config.h>
 #endif
 
+#include <errno.h>
 #include <string.h>
 #include <glib.h>
 
@@ -64,10 +65,13 @@ static gboolean dummy_result(gpointer data)
 	return FALSE;
 }
 
-int phonebook_set_folder(const gchar *current_folder, const gchar *new_folder,
-								guint8 flags)
+gchar *phonebook_set_folder(const gchar *current_folder,
+		const gchar *new_folder, guint8 flags, int *err)
 {
-	return 0;
+	if (err)
+		*err = -EINVAL;
+
+	return NULL;
 }
 
 int phonebook_pull(const gchar *name, const struct apparam_field *params,
diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c
index dc82580..4d29994 100644
--- a/obexd/plugins/phonebook-ebook.c
+++ b/obexd/plugins/phonebook-ebook.c
@@ -294,54 +294,88 @@ void phonebook_exit(void)
 		g_object_unref(ebook);
 }
 
-int phonebook_set_folder(const gchar *current_folder,
-		const gchar *new_folder, guint8 flags)
+gchar *phonebook_set_folder(const gchar *current_folder,
+		const gchar *new_folder, guint8 flags, int *err)
 {
 	gboolean root, child;
-	int ret;
+	gchar *fullname = NULL, *tmp1, *tmp2, *base;
+	int ret = 0, len;
 
 	root = (g_strcmp0("/", current_folder) == 0);
 	child = (new_folder && strlen(new_folder) != 0);
 
 	/* Evolution back-end will support telecom/pb folder only */
+
 	switch (flags) {
 	case 0x02:
 		/* Go back to root */
-		if (!child)
-			return 0;
+		if (!child) {
+			fullname = g_strdup("/");
+			goto done;
+		}
 
 		/* Go down 1 level */
-		if (root)
-			ret = (strcmp("telecom", new_folder) != 0) ? -EBADR: 0;
-		else if (strcmp("/telecom", current_folder) == 0)
-			ret = (strcmp("pb", new_folder) != 0) ? -EBADR: 0;
-		else
+		fullname = g_build_filename(current_folder, new_folder, NULL);
+		if (strcmp("/telecom", fullname) != 0 &&
+				strcmp("/telecom/pb", fullname) != 0) {
+			g_free(fullname);
+			fullname = NULL;
 			ret = -EBADR;
+		}
 
 		break;
 	case 0x03:
 		/* Go up 1 level */
-		if (root)
+		if (root) {
 			/* Already root */
-			return -EBADR;
+			ret = -EBADR;
+			goto done;
+		}
 
-		if (!child)
-			return 0;
+		/*
+		 * 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);
 
-		/* /telecom or /telecom/pb */
-		if (strcmp("/telecom", current_folder) == 0)
-			ret = (strcmp("telecom", new_folder) != 0) ? -EBADR : 0;
-		else if (strcmp("/telecom/pb", current_folder) == 0)
-			ret = (strcmp("pb", new_folder) != 0) ? -EBADR : 0;
+		g_free(tmp1);
+
+		if (len == 0)
+			base = g_strdup("/");
 		else
+			base = g_strndup(current_folder, len);
+
+		/* Return one level only */
+		if (!child) {
+			fullname = base;
+			goto done;
+		}
+
+		fullname = g_build_filename(base, new_folder, NULL);
+		if (strcmp(fullname, "/telecom") != 0 &&
+				strcmp(fullname, "/telecom/pb") != 0) {
+			g_free(fullname);
+			fullname = NULL;
 			ret = -EBADR;
+		}
+
+		g_free(base);
+
 		break;
 	default:
 		ret = -EBADR;
 		break;
 	}
 
-	return ret;
+done:
+	if (err)
+		*err = ret;
+
+	return fullname;
 }
 
 gint phonebook_pull(const gchar *name, const struct apparam_field *params,
diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h
index 5d3e33d..0f4f228 100644
--- a/obexd/plugins/phonebook.h
+++ b/obexd/plugins/phonebook.h
@@ -69,8 +69,8 @@ typedef void (*phonebook_cache_ready_cb) (gpointer user_data);
 int phonebook_init(void);
 void phonebook_exit(void);
 
-int phonebook_set_folder(const gchar *current_folder,
-		const gchar *new_folder, guint8 flags);
+gchar *phonebook_set_folder(const gchar *current_folder,
+		const gchar *new_folder, guint8 flags, int *err);
 
 /*
  * PullPhoneBook never use cached entries. PCE use this