This email list is read-only.  Emails sent to this list will be discarded
----------------------------------
 client/main.c      |    6 +-
 client/session.c   |  326 +++++++++++++++++++++++++++++++++++++++++-----------
 client/session.h   |    8 +-
 doc/client-api.txt |    7 +-
 gwobex/obex-priv.c |    2 +-
 5 files changed, 273 insertions(+), 76 deletions(-)

New commits:
commit fb3586f04163444e71f75d9a843793de49b15e9d
Author: Johan Hedberg <[EMAIL PROTECTED]>
Date:   Fri Oct 31 08:45:35 2008 +0200

    Improve the dc_cb/xfer callback workaround
    
    It's in anycase not safe to call these two callbacks at the same time here, 
but
    in case some code does use the dc_cb for calling gw_obex_close (which is 
quite
    a rational thing to do in this case) give it a chance to work.

commit 69af00a3b4be37a4ca9f6cffd3fc9d26eac14bb9
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Thu Oct 30 19:01:33 2008 -0300

    Removes a memory leak

commit 5a8c40db8a2f42272a8a0269042784eb79b9e713
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Thu Oct 30 17:11:08 2008 -0300

    Stores the transfer object path in session_data too

commit 7dbf3689490a181ca61af409d5a0ff1cc76dc692
Merge: 4e8bdccf6cdbfe3d2e71f84e073d110a781fe8cc 
aeaad6db3a940a46e4cfc75d52f6d8466509e686
Author: Marcel Holtmann <[EMAIL PROTECTED]>
Date:   Fri Oct 31 00:36:21 2008 +0100

    Merge branch 'devel' of git://git.infradead.org/users/cktakahasi/obexd

commit 4e8bdccf6cdbfe3d2e71f84e073d110a781fe8cc
Author: Johan Hedberg <[EMAIL PROTECTED]>
Date:   Fri Oct 31 00:05:24 2008 +0200

    Change xfer callback and dc_cb order in the event of a disconnection
    
    This is mainly working around a bug in the gwobex API. Since it doesn't have
    proper refcounting the xfer callback can free the gwobex ctx and so the 
second
    callback fails. It could of course happen in the other direction too (dc_cb
    calls gw_obex_close) but since no known code is using dc_cb it's at least a
    little safer this way.

commit aeaad6db3a940a46e4cfc75d52f6d8466509e686
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date:   Thu Oct 30 18:19:06 2008 -0300

    Return an array of dictionary for ListFolder

commit 9609bfce78af37ab36ebb13387cb81c4f46038f2
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date:   Wed Oct 29 10:45:54 2008 -0300

    Added ListFolder method skeleton

commit 3ec6df0774857b6b4dc9ec970367431e825198de
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date:   Tue Oct 28 16:14:50 2008 -0300

    Removed folder parameter from ListFolder method

commit 9d2f21e9a8ef81adc8a291a41677c7f89e4b0a48
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Wed Oct 29 11:54:17 2008 -0300

    Removes the agent watch if the agent is released

commit 040e85e23fe70612deb300f82b33e4abfdd7a004
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Wed Oct 29 11:51:48 2008 -0300

    Do not register the transfer interface if it was already registered

commit 1ffa8da5efc31bae16d8260be3dd25c3586c874b
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Wed Oct 29 11:11:27 2008 -0300

    Only try to send messages to the agent if there's one registered

commit fc73d2abe5b85145774d4ef8e94228866863137a
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Wed Oct 29 10:36:45 2008 -0300

    Removes the disconnect watch when the session is freed

commit 4329b1bee58626cc30bd1ab9f2c08faaf9510eca
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Wed Oct 29 10:32:16 2008 -0300

    Implements FTP PutFile

commit 05cd48181ed1e255e8eb9727172c5ce3f38f11e9
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date:   Tue Oct 28 19:43:24 2008 -0300

    Support changing the filename that will be sent in the OBEX header


Diff in this email is a maximum of 400 lines.
diff --git a/client/main.c b/client/main.c
index ce55227..e20eafc 100644
--- a/client/main.c
+++ b/client/main.c
@@ -73,8 +73,10 @@ static void create_callback(struct session_data *session, 
void *user_data)
        session_set_agent(session, data->sender, data->agent);
 
        for (i = 0; i < data->files->len; i++) {
-               if (session_send(session,
-                               g_ptr_array_index(data->files, i)) < 0)
+               const gchar *filename = g_ptr_array_index(data->files, i);
+
+               if (session_send(session, filename,
+                               g_path_get_basename(filename)) < 0)
                        break;
        }
 
diff --git a/client/session.c b/client/session.c
index 47902fc..b7a059d 100644
--- a/client/session.c
+++ b/client/session.c
@@ -72,6 +72,9 @@ static void session_unref(struct session_data *session)
        if (g_atomic_int_dec_and_test(&session->refcount) == FALSE)
                return;
 
+       if (session->agent_watch)
+               g_dbus_remove_watch(session->conn, session->agent_watch);
+
        if (session->agent_name != NULL) {
                DBusMessage *message;
 
@@ -99,14 +102,15 @@ static void session_unref(struct session_data *session)
                close(session->sock);
 
        if (session->conn) {
-               if (session->path)
+               if (session->transfer_path)
                        g_dbus_unregister_interface(session->conn,
-                                       session->path, TRANSFER_INTERFACE);
+                                       session->transfer_path, 
TRANSFER_INTERFACE);
 
                dbus_connection_unref(session->conn);
        }
 
        g_free(session->path);
+       g_free(session->transfer_path);
        g_free(session->name);
        g_free(session->filename);
        g_free(session->agent_name);
@@ -423,7 +427,7 @@ static void abort_transfer(struct session_data *session)
                        session->agent_path, AGENT_INTERFACE, "Complete");
 
        dbus_message_append_args(message,
-                       DBUS_TYPE_OBJECT_PATH, &session->path,
+                       DBUS_TYPE_OBJECT_PATH, &session->transfer_path,
                                                DBUS_TYPE_INVALID);
 
        g_dbus_send_message(session->conn, message);
@@ -439,20 +443,23 @@ static void abort_transfer(struct session_data *session)
        g_free(session->name);
        session->name = NULL;
 
-       if (session->path) {
+       if (session->transfer_path) {
                g_dbus_unregister_interface(session->conn,
-                               session->path, TRANSFER_INTERFACE);
-               g_free(session->path);
-               session->path = NULL;
+                               session->transfer_path, TRANSFER_INTERFACE);
+               g_free(session->transfer_path);
+               session->transfer_path = NULL;
        }
 
        if (session->pending->len > 0) {
                gchar *filename;
+               gchar *basename;
                filename = g_ptr_array_index(session->pending, 0);
                g_ptr_array_remove(session->pending, filename);
 
-               session_send(session, filename);
+               basename = g_path_get_basename(filename);
+               session_send(session, filename, basename);
                g_free(filename);
+               g_free(basename);
        }
 
        session_unref(session);
@@ -598,7 +605,7 @@ static DBusMessage *assign_agent(DBusConnection *connection,
        session->agent_name = g_strdup(sender);
        session->agent_path = g_strdup(path);
 
-       g_dbus_add_disconnect_watch(connection, sender,
+       session->agent_watch = g_dbus_add_disconnect_watch(connection, sender,
                                agent_disconnected, session, NULL);
 
        return dbus_message_new_method_return(message);
@@ -632,6 +639,11 @@ static DBusMessage *release_agent(DBusConnection 
*connection,
        g_free(session->agent_path);
        session->agent_path = NULL;
 
+       if (session->agent_watch) {
+               g_dbus_remove_watch(session->conn, session->agent_watch);
+               session->agent_watch = 0;
+       }
+
        return dbus_message_new_method_return(message);
 }
 
@@ -642,6 +654,146 @@ 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)
+{
+       GMarkupParseContext *ctxt;
+       DBusMessage *reply;
+       DBusMessageIter iter;
+
+       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;
+       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 (bread == gw_obex_xfer_object_size(xfer))
+               goto complete;
+
+       gw_obex_xfer_flush(xfer, NULL);
+
+       return;
+
+complete:
+       gw_obex_xfer_close(xfer, NULL);
+       gw_obex_xfer_free(xfer);
+       callback->session->xfer = NULL;
+
+       callback->func(callback->session, callback->data);
+
+       session_unref(callback->session);
+
+       g_free(callback);
+}
+
 static DBusMessage *change_folder(DBusConnection *connection,
                                DBusMessage *message, void *user_data)
 {
@@ -673,7 +825,48 @@ static DBusMessage *create_folder(DBusConnection 
*connection,
 static DBusMessage *list_folder(DBusConnection *connection,
                                DBusMessage *message, void *user_data)
 {
-       return dbus_message_new_method_return(message);
+       struct session_data *session = user_data;
+       struct callback_data *callback;
+       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",
+                               "Not connected");
+
+       session_ref(session);
+       xfer = gw_obex_get_async(session->obex,
+                       NULL, "x-obex/folder-listing", &err);
+       if (xfer == NULL) {
+               session_unref(session);
+               return g_dbus_create_error(message,
+                               "org.openobex.Error.Failed",
+                               OBEX_ResponseToString(err));
+       }
+
+       callback = g_try_malloc0(sizeof(*callback));
+       if (callback == NULL) {
+               session_unref(session);
+               gw_obex_xfer_free(xfer);
+               return NULL;
+       }
+
+       session->msg = dbus_message_ref(message);
+       session->filled = 0;
+       callback->session = session;
+       callback->func = list_folder_callback;
+
+       gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback);
+
+       session->xfer = xfer;
+
+       return NULL;
 }
 
 static DBusMessage *get_file(DBusConnection *connection,
@@ -685,6 +878,22 @@ static DBusMessage *get_file(DBusConnection *connection,
 static DBusMessage *put_file(DBusConnection *connection,
                                DBusMessage *message, void *user_data)
 {
+       struct session_data *session = user_data;
+       gchar *sourcefile, *targetfile;
+
+       if (dbus_message_get_args(message, NULL,
+                                       DBUS_TYPE_STRING, &sourcefile,
+                                       DBUS_TYPE_STRING, &targetfile,
+                                       DBUS_TYPE_INVALID) == FALSE)
+               return g_dbus_create_error(message,
+                               "org.openobex.Error.InvalidArguments",
+                               "Invalid arguments in method call");
+
+       if (session_send(session, sourcefile, targetfile) < 0)
+               return g_dbus_create_error(message,
+                               "org.openobex.Error.Failed",
+                               "Failed");
+
        return dbus_message_new_method_return(message);
 }
 
@@ -709,7 +918,8 @@ static DBusMessage *delete(DBusConnection *connection,
 static GDBusMethodTable ftp_methods[] = {
        { "ChangeFolder",       "s", "",        change_folder   },
        { "CreateFolder",       "s", "",        create_folder   },
-       { "ListFolder",         "s", "aa{sv}",  list_folder     },
+       { "ListFolder",         "", "aa{sv}",   list_folder,
+                                               G_DBUS_METHOD_FLAG_ASYNC },
        { "GetFile",            "ss", "",       get_file        },
        { "PutFile",            "ss", "",       put_file        },
        { "CopyFile",           "ss", "",       copy_file       },
@@ -734,7 +944,8 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer 
user_data)
                                                &written, NULL) == FALSE)
                goto complete;
 
-       gw_obex_xfer_flush(xfer, NULL);
+       if (gw_obex_xfer_flush(xfer, NULL) == FALSE)
+               goto complete;
 
        session->filled = (session->filled + len) - written;
 
@@ -742,12 +953,15 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer 
user_data)
 
        session->transferred += written;
 
+       if (session->agent_name == NULL || session->agent_path == NULL)
+               return;
+
        message = dbus_message_new_method_call(session->agent_name,
                        session->agent_path, AGENT_INTERFACE, "Progress");
 
        dbus_message_set_no_reply(message, TRUE);
 
-       dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &session->path,
+       dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, 
&session->transfer_path,
                                DBUS_TYPE_UINT64, &session->transferred,
                                                        DBUS_TYPE_INVALID);
 
@@ -756,14 +970,16 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer 
user_data)
        return;
 
 complete:
-       message = dbus_message_new_method_call(session->agent_name,
+       if (session->agent_path && session->agent_name) {
+               message = dbus_message_new_method_call(session->agent_name,
                        session->agent_path, AGENT_INTERFACE, "Complete");
 
-       dbus_message_append_args(message,
-                       DBUS_TYPE_OBJECT_PATH, &session->path,
+               dbus_message_append_args(message,
+                       DBUS_TYPE_OBJECT_PATH, &session->transfer_path,
                                                DBUS_TYPE_INVALID);
 
-       g_dbus_send_message(session->conn, message);
+               g_dbus_send_message(session->conn, message);
+       }
 
        if (session->pending->len > 0) {
                gchar *filename;
@@ -780,21 +996,22 @@ complete:
                g_free(session->name);
                session->name = NULL;
 
-               if (session->path) {
+               if (session->transfer_path) {
                        g_dbus_unregister_interface(session->conn,
-                                       session->path, TRANSFER_INTERFACE);
-                       g_free(session->path);
-                       session->path = NULL;
+                                       session->transfer_path, 
TRANSFER_INTERFACE);
+                       g_free(session->transfer_path);
+                       session->transfer_path = NULL;
                }
_______________________________________________
Commits mailing list
[email protected]
https://lists.moblin.org/mailman/listinfo/commits

Reply via email to