diff options
author | Elliott Sales de Andrade <qulogic@pidgin.im> | 2009-11-20 00:35:30 +0000 |
---|---|---|
committer | Elliott Sales de Andrade <qulogic@pidgin.im> | 2009-11-20 00:35:30 +0000 |
commit | acb547f79901793e261eed3817399b4711f446d6 (patch) | |
tree | bf7c0d980d365a462de59f9fd259baa2be190b4e | |
parent | ac7164ce530ec784a47326c596724f05d99baf29 (diff) | |
parent | c0f7985685359639dd0159498dc0087c9eac1b8a (diff) | |
download | pidgin-acb547f79901793e261eed3817399b4711f446d6.tar.gz |
propagate from branch 'im.pidgin.pidgin' (head 7c6adca0766f4f4ee1a0ce9a2c0680e9d1339df3)
to branch 'im.pidgin.cpw.darkrain42.msn.ft' (head 76761af122e89f59262882e9d39c289243815b01)
-rw-r--r-- | libpurple/protocols/msn/slp.c | 56 | ||||
-rw-r--r-- | libpurple/protocols/msn/slp.h | 3 | ||||
-rw-r--r-- | libpurple/protocols/msn/slpcall.c | 6 | ||||
-rw-r--r-- | libpurple/protocols/msn/slpcall.h | 8 | ||||
-rw-r--r-- | libpurple/protocols/msn/slplink.c | 43 | ||||
-rw-r--r-- | libpurple/protocols/msn/slplink.h | 3 | ||||
-rw-r--r-- | libpurple/protocols/msn/slpmsg.h | 1 |
7 files changed, 105 insertions, 15 deletions
diff --git a/libpurple/protocols/msn/slp.c b/libpurple/protocols/msn/slp.c index 39b67f3f37..4aa235fbbd 100644 --- a/libpurple/protocols/msn/slp.c +++ b/libpurple/protocols/msn/slp.c @@ -96,6 +96,8 @@ msn_xfer_init(PurpleXfer *xfer) g_free(content); msn_slplink_send_queued_slpmsgs(slpcall->slplink); + + purple_xfer_start(xfer, -1, NULL, 0); } void @@ -131,6 +133,54 @@ msn_xfer_cancel(PurpleXfer *xfer) } } +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 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch, 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 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch, 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 --git a/libpurple/protocols/msn/slp.h b/libpurple/protocols/msn/slp.h index c9cee83f18..b2de049fb0 100644 --- a/libpurple/protocols/msn/slp.h +++ b/libpurple/protocols/msn/slp.h @@ -41,6 +41,9 @@ void msn_xfer_completed_cb(MsnSlpCall *slpcall, 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 --git a/libpurple/protocols/msn/slpcall.c b/libpurple/protocols/msn/slpcall.c index 5a656cb50c..87f7ecec08 100644 --- a/libpurple/protocols/msn/slpcall.c +++ b/libpurple/protocols/msn/slpcall.c @@ -105,10 +105,13 @@ msn_slpcall_destroy(MsnSlpCall *slpcall) 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 @@ msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) slpcall->timer = 0; } - slpcall->cb(slpcall, body, body_len); + if (slpcall->cb) + slpcall->cb(slpcall, body, body_len); slpcall->wasted = TRUE; } diff --git a/libpurple/protocols/msn/slpcall.h b/libpurple/protocols/msn/slpcall.h index 445bac734b..5c7664a7da 100644 --- a/libpurple/protocols/msn/slpcall.h +++ b/libpurple/protocols/msn/slpcall.h @@ -72,6 +72,14 @@ struct _MsnSlpCall 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 --git a/libpurple/protocols/msn/slplink.c b/libpurple/protocols/msn/slplink.c index 0b921fa633..89c727065c 100644 --- a/libpurple/protocols/msn/slplink.c +++ b/libpurple/protocols/msn/slplink.c @@ -232,7 +232,7 @@ msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg) } } -static void +void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { MsnMessage *msg; @@ -247,7 +247,13 @@ msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) 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 @@ msg_ack(MsnMessage *msg, void *data) 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 @@ send_file_cb(MsnSlpCall *slpcall) 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 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) const char *data; guint64 offset; gsize len; + PurpleXfer *xfer = NULL; if (purple_debug_is_verbose()) msn_slpmsg_show(msg); @@ -525,12 +538,12 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) 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 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) 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 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) /* 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 @@ msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer) 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 @@ msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer) 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 --git a/libpurple/protocols/msn/slplink.h b/libpurple/protocols/msn/slplink.h index 2f11c97e5b..ea8ca2e5f6 100644 --- a/libpurple/protocols/msn/slplink.h +++ b/libpurple/protocols/msn/slplink.h @@ -84,6 +84,9 @@ void msn_slplink_send_queued_slpmsgs(MsnSlpLink *slplink); 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 --git a/libpurple/protocols/msn/slpmsg.h b/libpurple/protocols/msn/slpmsg.h index 6f1349aa4c..5852bcb78c 100644 --- a/libpurple/protocols/msn/slpmsg.h +++ b/libpurple/protocols/msn/slpmsg.h @@ -55,6 +55,7 @@ struct _MsnSlpMessage long flags; FILE *fp; + gboolean ft; PurpleStoredImage *img; guchar *buffer; long long offset; |