static void skypeweb_xfer_send_connect_cb(gpointer user_data, PurpleSslConnection *ssl_connection, PurpleInputCondition cond) { SkypeWebFileTransfer *swft = user_data; SkypeWebAccount *sa = swft->sa; PurpleXfer *xfer = swft->xfer; gchar *headers; headers = g_strdup_printf("PUT /v1/objects/%s/content/original HTTP/1.0\r\n" "Connection: close\r\n" "Authorization: skype_token %s\r\n" //slightly different to normal! "Host: " SKYPEWEB_XFER_HOST "\r\n" "Content-Length: %d\r\n" "Content-Type: application/json\r\n" "\r\n\r\n", purple_url_encode(swft->id), sa->skype_token, purple_xfer_get_size(xfer)); purple_ssl_write(ssl_connection, headers, strlen(headers)); swft->conn = ssl_connection; purple_xfer_ref(xfer); purple_xfer_start(xfer, ssl_connection->fd, NULL, 0); //TODO add input watcher that calls this repeatedly purple_xfer_prpl_ready(xfer); //purple_ssl_input_add( g_free(headers); }
/* We have received the message ack */ static void msg_ack(MsnMessage *msg, void *data) { MsnSlpMessage *slpmsg; long long real_size; slpmsg = data; real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; slpmsg->offset += msg->msnslp_header.length; slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); if (slpmsg->offset < real_size) { if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) { slpmsg->slpcall->xfer_msg = slpmsg; msn_message_ref(msg); purple_xfer_prpl_ready(slpmsg->slpcall->xfer); } else msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); } else { /* The whole message has been sent */ if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) { if (slpmsg->slpcall != NULL) { if (slpmsg->slpcall->cb) slpmsg->slpcall->cb(slpmsg->slpcall, NULL, 0); } } } msn_message_unref(msg); }
static void slpmsg_add_part(MsnSlpMessage *slpmsg, MsnSlpMessagePart *part) { if (slpmsg->ft) { slpmsg->slpcall->u.incoming_data = g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)part->buffer, part->size); purple_xfer_prpl_ready(slpmsg->slpcall->xfer); } else if (slpmsg->size && slpmsg->buffer) { guint64 offset = msn_p2p_info_get_offset(part->info); if (G_MAXSIZE - part->size < offset || (offset + part->size) > slpmsg->size || msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) { purple_debug_error("msn", "Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n", slpmsg->size, offset, part->size); g_return_if_reached(); } else { memcpy(slpmsg->buffer + offset, part->buffer, part->size); msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size); } } }
void msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *data, gsize len) { MsnSlpMessage *slpmsg; guint64 offset; PurpleXfer *xfer = NULL; if (header->total_size < header->length) { purple_debug_error("msn", "This can't be good\n"); g_return_if_reached(); } offset = header->offset; if (offset == 0) { slpmsg = msn_slpmsg_new(slplink); slpmsg->id = header->id; slpmsg->session_id = header->session_id; slpmsg->size = header->total_size; slpmsg->flags = header->flags; if (slpmsg->session_id) { if (slpmsg->slpcall == NULL) slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); if (slpmsg->slpcall != NULL) { if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) { 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); if (xfer->data == NULL) { purple_xfer_unref(xfer); msn_slpmsg_destroy(slpmsg); g_return_if_reached(); } else { purple_xfer_unref(xfer); } } } } } if (!slpmsg->ft && slpmsg->size) { slpmsg->buffer = g_try_malloc(slpmsg->size); if (slpmsg->buffer == NULL) { purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n"); msn_slpmsg_destroy(slpmsg); return; } } } else { slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id); if (slpmsg == NULL) { /* Probably the transfer was canceled */ purple_debug_error("msn", "Couldn't find slpmsg\n"); return; } } 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 || slpmsg->offset != offset) { purple_debug_error("msn", "Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n", slpmsg->size, offset, len); g_return_if_reached(); } else { memcpy(slpmsg->buffer + offset, data, len); slpmsg->offset += len; } } if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; if (slpmsg->slpcall->progress_cb != NULL) { slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, len, offset); } } #if 0 if (slpmsg->buffer == NULL) return; #endif if (header->offset + header->length >= header->total_size) { /* All the pieces of the slpmsg have been received */ MsnSlpCall *slpcall; slpcall = msn_slp_process_msg(slplink, slpmsg); if (slpcall == NULL) { msn_slpmsg_destroy(slpmsg); return; } purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n"); if (/* !slpcall->wasted && */ slpmsg->flags == 0x100) { #if 0 MsnDirectConn *directconn; directconn = slplink->directconn; if (!directconn->acked) msn_directconn_send_handshake(directconn); #endif } else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 || slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) { /* Release all the messages and send the ACK */ if (slpcall->wait_for_socket) { /* * Save ack for later because we have to send * a 200 OK message to the previous direct connect * invitation before ACK but the listening socket isn't * created yet. */ purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n"); slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header); } else if (!slpcall->wasted) { purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n"); msn_slplink_send_ack(slplink, header); msn_slplink_send_queued_slpmsgs(slplink); } } msn_slpmsg_destroy(slpmsg); if (!slpcall->wait_for_socket && slpcall->wasted) msn_slpcall_destroy(slpcall); } }