2012-03-06 17:42:24

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing

---
plugins/messages-dummy.c | 43 ++++++++++++++++++++++++++++++++++++++++---
1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index 511857e..3ba333c 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -36,8 +36,23 @@ static char *root_folder = NULL;
struct session {
char *cwd;
char *cwd_absolute;
+ void *request;
};

+struct folder_listing_data {
+ struct session *session;
+ const char *name;
+ uint16_t max;
+ uint16_t offset;
+ messages_folder_listing_cb callback;
+ void *user_data;
+};
+
+static gboolean get_folder_listing(void *d)
+{
+ return FALSE;
+}
+
int messages_init(void)
{
char *tmp;
@@ -142,12 +157,28 @@ int messages_set_folder(void *s, const char *name, gboolean cdup)
return 0;
}

-int messages_get_folder_listing(void *session, const char *name, uint16_t max,
+int messages_get_folder_listing(void *s, const char *name, uint16_t max,
uint16_t offset,
messages_folder_listing_cb callback,
void *user_data)
{
- return -ENOSYS;
+ struct session *session = s;
+ struct folder_listing_data *fld;
+
+ fld = g_new0(struct folder_listing_data, 1);
+ fld->session = session;
+ fld->name = name;
+ fld->max = max;
+ fld->offset = offset;
+ fld->callback = callback;
+ fld->user_data = user_data;
+
+ session->request = fld;
+
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, get_folder_listing,
+ fld, g_free);
+
+ return 0;
}

int messages_get_messages_listing(void *session, const char *name,
@@ -173,6 +204,12 @@ int messages_update_inbox(void *session, messages_update_inbox_cb callback,
return -ENOSYS;
}

-void messages_abort(void *session)
+void messages_abort(void *s)
{
+ struct session *session = s;
+
+ if (session->request) {
+ g_idle_remove_by_data(session->request);
+ session->request = NULL;
+ }
}
--
1.7.5.1



2012-03-08 23:36:51

by Johan Hedberg

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

Hi Slawek,

On Tue, Mar 06, 2012, Slawomir Bochenski wrote:
> ---
> plugins/messages-dummy.c | 61 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 60 insertions(+), 1 deletions(-)

I've applied the first two in this set, but this one had some minor
stylistic issues:

> static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
> {
> - return 0;
> + DIR *dp;
> + char *path, *name;
> + size_t n = 0;

Please leave this initialization later in the function.

> + path = g_build_filename(fld->session->cwd_absolute, fld->name, NULL);
> + dp = opendir(path);
> +
> + if (dp == NULL) {
> + int err = errno;

For consistency, variables called "err" should have a negative value to
indicate error or 0 to indicate no error. So this should be:

err = -errno;

> + while ((name = get_next_subdir(dp, path)) != NULL) {
> + ++n;

When it doesn't really matter whether you use post- or pre-increment
just use post-increment since I think that's the most widely used one in
the code base.

> + if (fld->max != 0)

I'd prefer to have the test as > 0

Johan

2012-03-06 17:42:27

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd 4/5] 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 daa7ae4..b98bedc 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -117,6 +117,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.5.1


2012-03-06 17:42:28

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd 5/5] 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 b98bedc..2a4cdbc 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;
@@ -111,6 +141,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.5.1


2012-03-06 17:42:26

by Slawomir Bochenski

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

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

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index db15a75..daa7ae4 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,66 @@ 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 = 0;
+
+ 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;
+ }
+
+ 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.5.1


2012-03-06 17:42:25

by Slawomir Bochenski

[permalink] [raw]
Subject: [PATCH obexd 2/5] MAP/dummy: Add basic logic for folder listing

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

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index 3ba333c..db15a75 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -25,6 +25,8 @@
#include <config.h>
#endif

+#include <sys/types.h>
+#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -48,8 +50,39 @@ struct folder_listing_data {
void *user_data;
};

+static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
+{
+ return 0;
+}
+
+static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
+{
+ struct session *session = fld->session;
+
+ fld->callback(session, 0, 0, NULL, fld->user_data);
+}
+
static gboolean get_folder_listing(void *d)
{
+ struct folder_listing_data *fld = d;
+ ssize_t n;
+ GSList *list = NULL;
+
+ n = get_subdirs(fld, &list);
+
+ if (n < 0) {
+ fld->callback(fld->session, n, 0, NULL, fld->user_data);
+ return FALSE;
+ }
+
+ if (fld->max == 0) {
+ fld->callback(fld->session, 0, n, NULL, fld->user_data);
+ return FALSE;
+ }
+
+ return_folder_listing(fld, list);
+ g_slist_free_full(list, g_free);
+
return FALSE;
}

--
1.7.5.1