2012-03-09 07:06:32

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd v3 1/3] MAP/dummy: Actual code for folder listing retrieval

---
v3: Corrected wrong value passed to strerror after v2 fixes
plugins/messages-dummy.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index db15a75..cfb24e2 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <string.h>

+#include "log.h"
+
#include "messages.h"

static char *root_folder = NULL;
@@ -50,9 +52,68 @@ struct folder_listing_data {
void *user_data;
};

+static char *get_next_subdir(DIR *dp, char *path)
+{
+ struct dirent *ep;
+ char *abs, *name;
+
+ for (;;) {
+ if ((ep = readdir(dp)) == NULL)
+ return NULL;
+
+ if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+ continue;
+
+ abs = g_build_filename(path, ep->d_name, NULL);
+
+ if (g_file_test(abs, G_FILE_TEST_IS_DIR)) {
+ g_free(abs);
+ break;
+ }
+
+ g_free(abs);
+ }
+
+ name = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL);
+
+ if (name == NULL) {
+ DBG("g_filename_to_utf8(): invalid filename");
+ return NULL;
+ }
+
+ return name;
+}
+
static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
{
- return 0;
+ DIR *dp;
+ char *path, *name;
+ size_t n;
+
+ path = g_build_filename(fld->session->cwd_absolute, fld->name, NULL);
+ dp = opendir(path);
+
+ if (dp == NULL) {
+ int err = -errno;
+
+ DBG("opendir(): %d, %s", -err, strerror(-err));
+ g_free(path);
+
+ return err;
+ }
+
+ n = 0;
+
+ while ((name = get_next_subdir(dp, path)) != NULL) {
+ n++;
+ if (fld->max > 0)
+ *list = g_slist_prepend(*list, name);
+ }
+
+ closedir(dp);
+ g_free(path);
+
+ return n;
}

static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
--
1.7.4.1



2012-03-09 07:06:34

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd v3 3/3] MAP/dummy: Add sorting of folder listing

---
plugins/messages-dummy.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index 00cca59..97c0682 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -52,6 +52,36 @@ struct folder_listing_data {
void *user_data;
};

+/* NOTE: Neither IrOBEX nor MAP specs says that folder listing needs to
+ * be sorted (in IrOBEX examples it is not). However existing implementations
+ * seem to follow the fig. 3-2 from MAP specification v1.0, and I've seen a
+ * test suite requiring folder listing to be in that order.
+ */
+static gint folder_names_cmp(gconstpointer a, gconstpointer b,
+ gpointer user_data)
+{
+ static const char *order[] = {
+ "inbox", "outbox", "sent", "deleted", "draft", NULL
+ };
+ struct session *session = user_data;
+ int ia, ib;
+
+ if (g_strcmp0(session->cwd, "telecom/msg") == 0) {
+ for (ia = 0; order[ia]; ++ia) {
+ if (g_strcmp0(a, order[ia]) == 0)
+ break;
+ }
+ for (ib = 0; order[ib]; ++ib) {
+ if (g_strcmp0(b, order[ib]) == 0)
+ break;
+ }
+ if (ia != ib)
+ return ia - ib;
+ }
+
+ return g_strcmp0(a, b);
+}
+
static char *get_next_subdir(DIR *dp, char *path)
{
struct dirent *ep;
@@ -113,6 +143,8 @@ static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
closedir(dp);
g_free(path);

+ *list = g_slist_sort_with_data(*list, folder_names_cmp, fld->session);
+
return n;
}

--
1.7.4.1


2012-03-09 07:06:33

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd v3 2/3] MAP/dummy: Code for returning folder listing

---
plugins/messages-dummy.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index cfb24e2..00cca59 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -119,6 +119,28 @@ static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
{
struct session *session = fld->session;
+ GSList *cur;
+ uint16_t n = 0;
+ uint16_t o = 0;
+
+ /* XXX: This isn't really documented for MAP. I need to take a look how
+ * other implementations choose to deal with parent folder.
+ */
+ if (session->cwd[0] != 0 && fld->offset == 0) {
+ ++n;
+ fld->callback(session, -EAGAIN, 0, "..", fld->user_data);
+ } else {
+ ++o;
+ }
+
+ for (cur = list; o < fld->offset; ++o) {
+ cur = cur->next;
+ if (cur == NULL)
+ break;
+ }
+
+ for (; cur != NULL && n < fld->max; cur = cur->next, ++n)
+ fld->callback(session, -EAGAIN, 0, cur->data, fld->user_data);

fld->callback(session, 0, 0, NULL, fld->user_data);
}
--
1.7.4.1