Diff between 807f9b748186fa4747ad9f9d35dd38d9a3108604 and bff8882e6c4cb07def45148fb2a364d85a593994

Changed Files

File Additions Deletions Status
obexd/client/session.c +118 -9 modified
obexd/client/session.h +1 -0 modified

Full Patch

diff --git a/obexd/client/session.c b/obexd/client/session.c
index 96e9be6..87705fc 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -650,25 +650,128 @@ static GDBusMethodTable session_methods[] = {
 	{ }
 };
 
+static void append_variant(DBusMessageIter *iter, int type, void *val)
+{
+	DBusMessageIter value;
+	char sig[2] = { type, '\0' };
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
+
+	dbus_message_iter_append_basic(&value, type, val);
+
+	dbus_message_iter_close_container(iter, &value);
+}
+
+static void dict_append_entry(DBusMessageIter *dict,
+			const char *key, int type, void *val)
+{
+	DBusMessageIter entry;
+
+	if (type == DBUS_TYPE_STRING) {
+		const char *str = *((const char **) val);
+		if (str == NULL)
+			return;
+	}
+
+	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+							NULL, &entry);
+
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+	append_variant(&entry, type, val);
+
+	dbus_message_iter_close_container(dict, &entry);
+}
+
+static void xml_element(GMarkupParseContext *ctxt,
+			const gchar *element,
+			const gchar **names,
+			const gchar **values,
+			gpointer user_data,
+			GError **gerr)
+{
+	DBusMessageIter dict, *iter = user_data;
+	gchar *key;
+	gint i, dtype = DBUS_TYPE_STRING;
+
+	if (strcasecmp("folder", element) != 0 && strcasecmp("file", element) != 0)
+		return;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &element);
+
+	/* FIXME: User, Group, Other permission must be reviewed */
+
+	i = 0;
+	for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
+		key[0] = g_ascii_toupper(key[0]);
+		if (strcmp("Accessed", key) == 0 ||
+			strcmp("Created", key) == 0 ||
+			strcmp("Modified", key)== 0 ||
+			strcmp("Size", key)== 0)
+			dtype = DBUS_TYPE_UINT64;
+
+		dict_append_entry(&dict, key, dtype, &values[i]);
+	}
+
+	dbus_message_iter_close_container(iter, &dict);
+}
+
+static const GMarkupParser parser = {
+	xml_element,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 static void list_folder_callback(struct session_data *session,
 					void *user_data)
 {
-	DBusMessage *message = user_data;
+	GMarkupParseContext *ctxt;
+	DBusMessage *reply;
+	DBusMessageIter iter;
 
-	g_dbus_send_reply(session->conn, message, DBUS_TYPE_INVALID);
-	dbus_message_unref(message);
+	reply = dbus_message_new_method_return(session->msg);
+
+	if (session->filled == 0)
+		goto done;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	ctxt = g_markup_parse_context_new(&parser, 0, &iter, NULL);
+	g_markup_parse_context_parse(ctxt, session->buffer,
+					session->filled, NULL);
+	g_markup_parse_context_free(ctxt);
+
+	session->filled = 0;
+
+done:
+	g_dbus_send_message(session->conn, reply);
+	dbus_message_unref(session->msg);
+	session->msg = NULL;
 }
 
 static void get_xfer_progress(GwObexXfer *xfer, gpointer user_data)
 {
 	struct callback_data *callback = user_data;
-	char buf[1024];
-	gint len;
-
-	if (gw_obex_xfer_read(xfer, buf, sizeof(buf), &len, NULL) == FALSE)
+	struct session_data *session = callback->session;
+	gint bsize, bread;
+	gboolean ret;
+
+	/* FIXME: Check buffer overflow */
+	bsize = sizeof(session->buffer) - session->filled;
+	ret = gw_obex_xfer_read(xfer, session->buffer + session->filled,
+					bsize, &bread, NULL);
+	session->filled += bread;
+	if (ret == FALSE)
 		goto complete;
 
-	if (len == gw_obex_xfer_object_size(xfer))
+	if (bread == gw_obex_xfer_object_size(xfer))
 		goto complete;
 
 	gw_obex_xfer_flush(xfer, NULL);
@@ -723,6 +826,11 @@ static DBusMessage *list_folder(DBusConnection *connection,
 	GwObexXfer *xfer;
 	int err;
 
+	if (session->msg)
+		return g_dbus_create_error(message,
+				"org.openobex.Error.InProgress",
+				"Transfer in progress");
+
 	if (session->obex == NULL)
 		return g_dbus_create_error(message,
 				"org.openobex.Error.Failed",
@@ -745,9 +853,10 @@ static DBusMessage *list_folder(DBusConnection *connection,
 		return NULL;
 	}
 
+	session->msg = dbus_message_ref(message);
+	session->filled = 0;
 	callback->session = session;
 	callback->func = list_folder_callback;
-	callback->data = dbus_message_ref(message);
 
 	gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback);
 
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 06e0c77..86fb24d 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -40,6 +40,7 @@ struct session_data {
 	int sock;
 	int fd;
 	DBusConnection *conn;
+	DBusMessage *msg;
 	GwObex *obex;
 	GwObexXfer *xfer;
 	char buffer[4096];