# HG changeset patch # User Elliott Sales de Andrade # Date 1258677330 0 # Node ID 19e400679e6174730612e58e40ad23527b4e354d # Parent 923681c5406e35f5d8397d3cf531df1cbdba7813# Parent 59b0c556f787a161a2cffbd6345b953e304c6861 propagate from branch 'im.pidgin.pidgin' (head a878de35a8972daab016ed05e7af50043bd856ca) to branch 'im.pidgin.cpw.darkrain42.msn.ft' (head f7212b36cc13bdbaf77b2c3a8dbcde9cb395c4f8) diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slp.c --- a/libpurple/protocols/msn/slp.c Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slp.c Fri Nov 20 00:35:30 2009 +0000 @@ -96,6 +96,8 @@ g_free(content); msn_slplink_send_queued_slpmsgs(slpcall->slplink); + + purple_xfer_start(xfer, -1, NULL, 0); } void @@ -131,6 +133,54 @@ } } +gssize +msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer) +{ + MsnSlpCall *slpcall; + + g_return_val_if_fail(xfer != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + g_return_val_if_fail(len > 0, -1); + + g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1); + + slpcall = xfer->data; + /* Not sure I trust it'll be there */ + g_return_val_if_fail(slpcall != NULL, -1); + + g_return_val_if_fail(slpcall->xfer_msg != NULL, -1); + + slpcall->u.outgoing.len = len; + slpcall->u.outgoing.data = data; + msn_slplink_send_msgpart(slpcall->slplink, slpcall->xfer_msg); + return MIN(1202, len); +} + +gssize +msn_xfer_read(guchar **data, PurpleXfer *xfer) +{ + MsnSlpCall *slpcall; + gsize len; + + g_return_val_if_fail(xfer != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + + g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1); + + slpcall = xfer->data; + /* Not sure I trust it'll be there */ + g_return_val_if_fail(slpcall != NULL, -1); + + /* Just pass up the whole GByteArray. We'll make another. */ + *data = slpcall->u.incoming_data->data; + len = slpcall->u.incoming_data->len; + + g_byte_array_free(slpcall->u.incoming_data, FALSE); + slpcall->u.incoming_data = g_byte_array_new(); + + return len; +} + void msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset) { @@ -332,9 +382,7 @@ account = slpcall->slplink->session->account; - slpcall->cb = msn_xfer_completed_cb; slpcall->end_cb = msn_xfer_end_cb; - slpcall->progress_cb = msn_xfer_progress_cb; slpcall->branch = g_strdup(branch); slpcall->pending = TRUE; @@ -357,6 +405,10 @@ purple_xfer_set_init_fnc(xfer, msn_xfer_init); purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); + purple_xfer_set_read_fnc(xfer, msn_xfer_read); + purple_xfer_set_write_fnc(xfer, msn_xfer_write); + + slpcall->u.incoming_data = g_byte_array_new(); slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slp.h --- a/libpurple/protocols/msn/slp.h Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slp.h Fri Nov 20 00:35:30 2009 +0000 @@ -41,6 +41,9 @@ const guchar *body, gsize size); void msn_xfer_cancel(PurpleXfer *xfer); +gssize msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer); +gssize msn_xfer_read(guchar **data, PurpleXfer *xfer); + void msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session); void msn_queue_buddy_icon_request(MsnUser *user); diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slpcall.c --- a/libpurple/protocols/msn/slpcall.c Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slpcall.c Fri Nov 20 00:35:30 2009 +0000 @@ -105,10 +105,13 @@ slpcall->end_cb(slpcall, slpcall->slplink->session); if (slpcall->xfer != NULL) { + if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE) + g_byte_array_free(slpcall->u.incoming_data, TRUE); slpcall->xfer->data = NULL; purple_xfer_unref(slpcall->xfer); } + msn_slplink_remove_slpcall(slpcall->slplink, slpcall); g_free(slpcall->id); @@ -272,7 +275,8 @@ slpcall->timer = 0; } - slpcall->cb(slpcall, body, body_len); + if (slpcall->cb) + slpcall->cb(slpcall, body, body_len); slpcall->wasted = TRUE; } diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slpcall.h --- a/libpurple/protocols/msn/slpcall.h Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slpcall.h Fri Nov 20 00:35:30 2009 +0000 @@ -72,6 +72,14 @@ char *data_info; PurpleXfer *xfer; + union { + GByteArray *incoming_data; + struct { + gsize len; + const guchar *data; + } outgoing; + } u; + MsnSlpMessage *xfer_msg; /* A dirty hack */ MsnSlpCb cb; void (*end_cb)(MsnSlpCall *slpcall, MsnSession *session); diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slplink.c --- a/libpurple/protocols/msn/slplink.c Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slplink.c Fri Nov 20 00:35:30 2009 +0000 @@ -232,7 +232,7 @@ } } -static void +void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { MsnMessage *msg; @@ -247,7 +247,13 @@ if (slpmsg->offset < real_size) { - if (slpmsg->fp) + if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND && + purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) + { + len = MIN(1202, slpmsg->slpcall->u.outgoing.len); + msn_message_set_bin_data(msg, slpmsg->slpcall->u.outgoing.data, len); + } + else if (slpmsg->fp) { char data[1202]; len = fread(data, 1, sizeof(data), slpmsg->fp); @@ -309,7 +315,13 @@ if (slpmsg->offset < real_size) { - msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); + if (slpmsg->slpcall->xfer) + { + slpmsg->slpcall->xfer_msg = slpmsg; + purple_xfer_prpl_ready(slpmsg->slpcall->xfer); + } + else + msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); } else { @@ -458,10 +470,10 @@ xfer = (PurpleXfer *)slpcall->xfer; purple_xfer_start(slpcall->xfer, -1, NULL, 0); - slpmsg->fp = xfer->dest_fp; if (g_stat(purple_xfer_get_local_filename(xfer), &st) == 0) slpmsg->size = st.st_size; - xfer->dest_fp = NULL; /* Disable double fclose() */ + else if (purple_xfer_get_size(xfer)) + slpmsg->size = purple_xfer_get_size(xfer); msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); } @@ -489,6 +501,7 @@ const char *data; guint64 offset; gsize len; + PurpleXfer *xfer = NULL; if (purple_debug_is_verbose()) msn_slpmsg_show(msg); @@ -525,12 +538,12 @@ if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) { - PurpleXfer *xfer; - xfer = slpmsg->slpcall->xfer; - if (xfer != NULL) { + slpmsg->ft = TRUE; + slpmsg->slpcall->xfer_msg = slpmsg; + purple_xfer_ref(xfer); purple_xfer_start(xfer, -1, NULL, 0); @@ -540,14 +553,12 @@ g_return_if_reached(); } else { purple_xfer_unref(xfer); - slpmsg->fp = xfer->dest_fp; - xfer->dest_fp = NULL; /* Disable double fclose() */ } } } } } - if (!slpmsg->fp && slpmsg->size) + if (!slpmsg->fp && !slpmsg->ft && slpmsg->size) { slpmsg->buffer = g_try_malloc(slpmsg->size); if (slpmsg->buffer == NULL) @@ -574,6 +585,13 @@ /* fseek(slpmsg->fp, offset, SEEK_SET); */ len = fwrite(data, 1, len, slpmsg->fp); } + else if (slpmsg->ft) + { + xfer = slpmsg->slpcall->xfer; + slpmsg->slpcall->u.incoming_data = + g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len); + purple_xfer_prpl_ready(xfer); + } else if (slpmsg->size && slpmsg->buffer) { if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size) @@ -732,7 +750,6 @@ slpcall->session_init_cb = send_file_cb; slpcall->end_cb = msn_xfer_end_cb; - slpcall->progress_cb = msn_xfer_progress_cb; slpcall->cb = msn_xfer_completed_cb; slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); @@ -740,6 +757,8 @@ slpcall->pending = TRUE; purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); + purple_xfer_set_read_fnc(xfer, msn_xfer_read); + purple_xfer_set_write_fnc(xfer, msn_xfer_write); xfer->data = slpcall; diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slplink.h --- a/libpurple/protocols/msn/slplink.h Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slplink.h Fri Nov 20 00:35:30 2009 +0000 @@ -84,6 +84,9 @@ void msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg); void msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer); +/* Only exported for msn_xfer_write */ +void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); + void msn_slplink_request_object(MsnSlpLink *slplink, const char *info, MsnSlpCb cb, diff -r 923681c5406e -r 19e400679e61 libpurple/protocols/msn/slpmsg.h --- a/libpurple/protocols/msn/slpmsg.h Tue Nov 17 21:34:28 2009 +0000 +++ b/libpurple/protocols/msn/slpmsg.h Fri Nov 20 00:35:30 2009 +0000 @@ -55,6 +55,7 @@ long flags; FILE *fp; + gboolean ft; PurpleStoredImage *img; guchar *buffer; long long offset;