This adds drivers for MIME types needed in Message Access Profile. The
target-default driver is also kept to prevent MIME driver selection
mechanism to get to default driver from filesystem.c which would result
in allowing putting files in arbitrary locations when connected to MAP
target.
The any_open() bindings in MIME drivers are going to be successfully
replaced by appropriate calls for specific functionality.
---
plugins/mas.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 89 insertions(+), 12 deletions(-)
diff --git a/plugins/mas.c b/plugins/mas.c
index 0ef8c81..59ae0c1 100644
--- a/plugins/mas.c
+++ b/plugins/mas.c
@@ -206,13 +206,11 @@ static int mas_setpath(struct obex_session *os, obex_object_t *obj,
static void *any_open(const char *name, int oflag, mode_t mode,
void *driver_data, size_t *size, int *err)
{
- struct mas_session *mas = driver_data;
-
DBG("");
- *err = 0;
+ *err = -EINVAL;
- return mas;
+ return NULL;
}
static ssize_t any_write(void *object, const void *buf, size_t count)
@@ -260,28 +258,102 @@ static struct obex_mime_type_driver mime_map = {
.write = any_write,
};
+static struct obex_mime_type_driver mime_message = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-bt/message",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver mime_folder_listing = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-obex/folder-listing",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver mime_msg_listing = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-bt/MAP-msg-listing",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver mime_notification_registration = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-bt/MAP-NotificationRegistration",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver mime_message_status = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-bt/messageStatus",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver mime_message_update = {
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .mimetype = "x-bt/MAP-messageUpdate",
+ .open = any_open,
+ .close = any_close,
+ .read = any_read,
+ .write = any_write,
+};
+
+static struct obex_mime_type_driver *map_drivers[] = {
+ &mime_map,
+ &mime_message,
+ &mime_folder_listing,
+ &mime_msg_listing,
+ &mime_notification_registration,
+ &mime_message_status,
+ &mime_message_update,
+ NULL
+};
+
static int mas_init(void)
{
int err;
+ int i;
err = messages_init();
if (err < 0)
return err;
- err = obex_mime_type_driver_register(&mime_map);
- if (err < 0)
- goto failed_mime;
+ for (i = 0; map_drivers[i] != NULL; ++i) {
+ err = obex_mime_type_driver_register(map_drivers[i]);
+ if (err < 0)
+ goto failed;
+ }
err = obex_service_driver_register(&mas);
if (err < 0)
- goto failed_mas_reg;
+ goto failed;
return 0;
-failed_mas_reg:
- obex_mime_type_driver_unregister(&mime_map);
+failed:
+ for (--i; i >= 0; --i)
+ obex_mime_type_driver_unregister(map_drivers[i]);
-failed_mime:
messages_exit();
return err;
@@ -289,8 +361,13 @@ failed_mime:
static void mas_exit(void)
{
+ int i;
+
obex_service_driver_unregister(&mas);
- obex_mime_type_driver_unregister(&mime_map);
+
+ for (i = 0; map_drivers[i] != NULL; ++i)
+ obex_mime_type_driver_unregister(map_drivers[i]);
+
messages_exit();
}
--
1.7.4.1
Hi Slawek,
On Fri, Aug 12, 2011, Slawomir Bochenski wrote:
> This adds drivers for MIME types needed in Message Access Profile. The
> target-default driver is also kept to prevent MIME driver selection
> mechanism to get to default driver from filesystem.c which would result
> in allowing putting files in arbitrary locations when connected to MAP
> target.
>
> The any_open() bindings in MIME drivers are going to be successfully
> replaced by appropriate calls for specific functionality.
> ---
> plugins/mas.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 89 insertions(+), 12 deletions(-)
All three patches have been applied. Thanks.
Johan
---
plugins/messages-tracker.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/plugins/messages-tracker.c b/plugins/messages-tracker.c
index a9e9c6a..22d923d 100644
--- a/plugins/messages-tracker.c
+++ b/plugins/messages-tracker.c
@@ -266,7 +266,7 @@ static gboolean async_get_folder_listing(void *s) {
folder_count++, dir = g_slist_next(dir)) {
struct message_folder *dir_data = dir->data;
- if (count == FALSE && session->offset < folder_count)
+ if (count == FALSE && session->offset <= folder_count)
session->folder_list_cb(session, -EAGAIN, 0,
dir_data->name, session->user_data);
}
--
1.7.4.1
This adds a basic (lacking parsing or sending back application
parameters) handling of folder listing requests for Message Access
Profile.
---
plugins/mas.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 126 insertions(+), 2 deletions(-)
diff --git a/plugins/mas.c b/plugins/mas.c
index 59ae0c1..8af6eed 100644
--- a/plugins/mas.c
+++ b/plugins/mas.c
@@ -28,12 +28,14 @@
#include <errno.h>
#include <glib.h>
#include <openobex/obex.h>
+#include <fcntl.h>
#include "plugin.h"
#include "log.h"
#include "obex.h"
#include "service.h"
#include "mimetype.h"
+#include "filesystem.h"
#include "dbus.h"
#include "messages.h"
@@ -86,17 +88,43 @@
</attribute> \
</record>"
+#define XML_DECL "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+
+/* Building blocks for x-obex/folder-listing */
+#define FL_DTD "<!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\">"
+#define FL_BODY_BEGIN "<folder-listing version=\"1.0\">"
+#define FL_BODY_EMPTY "<folder-listing version=\"1.0\"/>"
+#define FL_PARENT_FOLDER_ELEMENT "<parent-folder/>"
+#define FL_FOLDER_ELEMENT "<folder name=\"%s\"/>"
+#define FL_BODY_END "</folder-listing>"
+
struct mas_session {
struct mas_request *request;
void *backend_data;
+ gboolean finished;
+ gboolean nth_call;
+ GString *buffer;
};
static const uint8_t MAS_TARGET[TARGET_SIZE] = {
0xbb, 0x58, 0x2b, 0x40, 0x42, 0x0c, 0x11, 0xdb,
0xb0, 0xde, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 };
+
+static void reset_request(struct mas_session *mas)
+{
+ if (mas->buffer) {
+ g_string_free(mas->buffer, TRUE);
+ mas->buffer = NULL;
+ }
+
+ mas->nth_call = FALSE;
+ mas->finished = FALSE;
+}
+
static void mas_clean(struct mas_session *mas)
{
+ reset_request(mas);
g_free(mas);
}
@@ -154,6 +182,8 @@ static int mas_get(struct obex_session *os, obex_object_t *obj, void *user_data)
return 0;
failed:
+ reset_request(mas);
+
return ret;
}
@@ -176,9 +206,64 @@ static int mas_put(struct obex_session *os, obex_object_t *obj, void *user_data)
return 0;
failed:
+ reset_request(mas);
+
return ret;
}
+/* FIXME: Preserve whitespaces */
+static void g_string_append_escaped_printf(GString *string, const gchar *format,
+ ...)
+{
+ va_list ap;
+ char *escaped;
+
+ va_start(ap, format);
+ escaped = g_markup_vprintf_escaped(format, ap);
+ g_string_append(string, escaped);
+ g_free(escaped);
+ va_end(ap);
+}
+
+static void get_folder_listing_cb(void *session, int err, uint16_t size,
+ const char *name, void *user_data)
+{
+ struct mas_session *mas = user_data;
+
+ if (err < 0 && err != -EAGAIN) {
+ obex_object_set_io_flags(mas, G_IO_ERR, err);
+ return;
+ }
+
+ if (!mas->nth_call) {
+ g_string_append(mas->buffer, XML_DECL);
+ g_string_append(mas->buffer, FL_DTD);
+ if (!name) {
+ g_string_append(mas->buffer, FL_BODY_EMPTY);
+ mas->finished = TRUE;
+ goto proceed;
+ }
+ g_string_append(mas->buffer, FL_BODY_BEGIN);
+ mas->nth_call = TRUE;
+ }
+
+ if (!name) {
+ g_string_append(mas->buffer, FL_BODY_END);
+ mas->finished = TRUE;
+ goto proceed;
+ }
+
+ if (g_strcmp0(name, "..") == 0)
+ g_string_append(mas->buffer, FL_PARENT_FOLDER_ELEMENT);
+ else
+ g_string_append_escaped_printf(mas->buffer, FL_FOLDER_ELEMENT,
+ name);
+
+proceed:
+ if (err != -EAGAIN)
+ obex_object_set_io_flags(mas, G_IO_IN, err);
+}
+
static int mas_setpath(struct obex_session *os, obex_object_t *obj,
void *user_data)
{
@@ -203,6 +288,30 @@ static int mas_setpath(struct obex_session *os, obex_object_t *obj,
return messages_set_folder(mas->backend_data, name, nonhdr[0] & 0x01);
}
+static void *folder_listing_open(const char *name, int oflag, mode_t mode,
+ void *driver_data, size_t *size, int *err)
+{
+ struct mas_session *mas = driver_data;
+
+ if (oflag != O_RDONLY) {
+ *err = -EBADR;
+ return NULL;
+ }
+
+ DBG("name = %s", name);
+
+ /* 1024 is the default when there was no MaxListCount sent */
+ *err = messages_get_folder_listing(mas->backend_data, name, 1024, 0,
+ get_folder_listing_cb, mas);
+
+ mas->buffer = g_string_new("");
+
+ if (*err < 0)
+ return NULL;
+ else
+ return mas;
+}
+
static void *any_open(const char *name, int oflag, mode_t mode,
void *driver_data, size_t *size, int *err)
{
@@ -222,15 +331,30 @@ static ssize_t any_write(void *object, const void *buf, size_t count)
static ssize_t any_read(void *obj, void *buf, size_t count)
{
+ struct mas_session *mas = obj;
+ ssize_t len;
+
DBG("");
- return 0;
+ len = string_read(mas->buffer, buf, count);
+
+ if (len == 0 && !mas->finished)
+ return -EAGAIN;
+
+ return len;
}
static int any_close(void *obj)
{
+ struct mas_session *mas = obj;
+
DBG("");
+ if (!mas->finished)
+ messages_abort(mas->backend_data);
+
+ reset_request(mas);
+
return 0;
}
@@ -272,7 +396,7 @@ static struct obex_mime_type_driver mime_folder_listing = {
.target = MAS_TARGET,
.target_size = TARGET_SIZE,
.mimetype = "x-obex/folder-listing",
- .open = any_open,
+ .open = folder_listing_open,
.close = any_close,
.read = any_read,
.write = any_write,
--
1.7.4.1