static void skypeweb_got_object_for_file(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebFileTransfer *swft = user_data; SkypeWebAccount *sa = swft->sa; PurpleXfer *xfer = swft->xfer; JsonParser *parser; JsonNode *node; JsonObject *obj; gchar *id; sa->url_datas = g_slist_remove(sa->url_datas, url_data); //Get back {"id": "0-cus-d3-deadbeefdeadbeef012345678"} parser = json_parser_new(); if (!json_parser_load_from_data(parser, url_text, len, NULL)) { g_free(swft->from); g_free(swft); g_object_unref(parser); return; } node = json_parser_get_root(parser); if (node == NULL || json_node_get_node_type(node) != JSON_NODE_OBJECT) { g_free(swft->from); g_free(swft); g_object_unref(parser); purple_xfer_cancel_local(xfer); return; } obj = json_node_get_object(node); if (!json_object_has_member(obj, "id")) { g_free(swft->from); g_free(swft); g_object_unref(parser); purple_xfer_cancel_local(xfer); return; } swft->id = g_strdup(json_object_get_string_member(obj, "id")); swft->url = g_strconcat("https://" SKYPEWEB_XFER_HOST "/v1/objects/", purple_url_encode(swft->id), "/views/original/status", NULL); g_object_unref(parser); //Send the data //can't use fetch_url_request because it doesn't handle binary data //TODO make an error handler callback func purple_ssl_connect(sa->account, SKYPEWEB_XFER_HOST, 443, skypeweb_xfer_send_connect_cb, NULL, swft); //poll swft->url for progress purple_timeout_add_seconds(1, poll_file_send_progress, swft); }
/*------------------------------------------------------------------------ * Start the file transfer. * * @param xfer The file transfer object */ static void mxit_xfer_start( PurpleXfer* xfer ) { goffset filesize; unsigned char* buffer; int wrote; purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_start\n" ); if ( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND ) { /* * the user wants to send a file to one of his contacts. we need to create * a buffer and copy the file data into memory and then we can send it to * the contact. we will send the whole file with one go. */ filesize = purple_xfer_get_bytes_remaining( xfer ); buffer = g_malloc( filesize ); if ( fread( buffer, filesize, 1, xfer->dest_fp ) > 0 ) { /* send data */ wrote = purple_xfer_write( xfer, buffer, filesize ); if ( wrote > 0 ) purple_xfer_set_bytes_sent( xfer, wrote ); } else { /* file read error */ purple_xfer_error( purple_xfer_get_type( xfer ), purple_xfer_get_account( xfer ), purple_xfer_get_remote_user( xfer ), _( "Unable to access the local file" ) ); purple_xfer_cancel_local( xfer ); } /* free the buffer */ g_free( buffer ); buffer = NULL; } }
void tgprpl_xfer_free_all (connection_data *conn) { GList *xfers = purple_xfers_get_all (); while (xfers) { PurpleXfer *xfer = xfers->data; if (purple_xfer_get_account (xfer) == conn->pa) { debug ("xfer: %s", xfer->filename); // cancel all non-completed file tranfsers to avoid them from being called // in future sessions, as they still contain references to already freed data. if (! purple_xfer_is_canceled (xfer) && ! purple_xfer_is_completed (xfer)) { purple_xfer_cancel_local (xfer); } // if a file transfer is still running while going offline, it will be canceled when // cleaning up libtgl memory. Since canceled file transfers are being kept (see // tgprpl_xfer_canceled() and tgprpl_xfer_recv_init()) those need to be freed now. struct tgp_xfer_send_data *data = xfer->data; if (data) { if (data->loading) { tgprpl_xfer_free_data (data); xfer->data = NULL; purple_xfer_unref (xfer); } else { g_warn_if_reached(); } } } xfers = g_list_next(xfers); } }
static void _qq_send_file_progess(PurpleConnection *gc) { qq_data *qd = (qq_data *) gc->proto_data; PurpleXfer *xfer = qd->xfer; ft_info *info = (ft_info *) xfer->data; guint32 mask; guint8 *buffer; guint i; gint readbytes; if (purple_xfer_get_bytes_remaining(xfer) <= 0) return; if (info->window == 0 && info->max_fragment_index == 0) { if (_qq_xfer_open_file(purple_xfer_get_local_filename(xfer), "rb", xfer) == -1) { purple_xfer_cancel_local(xfer); return; } } buffer = g_newa(guint8, info->fragment_len); mask = 0x1 << (info->max_fragment_index % sizeof(info->window)); for (i = 0; i < sizeof(info->window); i++) { if ((info->window & mask) == 0) { readbytes = _qq_xfer_read_file(buffer, info->max_fragment_index + i, info->fragment_len, xfer); if (readbytes > 0) _qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP, QQ_FILE_DATA_INFO, info->max_fragment_index + i + 1, 0, buffer, readbytes); } if (mask & 0x8000) mask = 0x0001; else mask = mask << 1; } }
/*------------------------------------------------------------------------ * Initialise a new file transfer. * * @param xfer The file transfer object */ static void mxit_xfer_init( PurpleXfer* xfer ) { struct mxitxfer* mx = (struct mxitxfer*) xfer->data; purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_init\n" ); if ( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND ) { /* we are trying to send a file to MXit */ if ( purple_xfer_get_size( xfer ) > CP_MAX_FILESIZE ) { /* the file is too big */ purple_xfer_error( xfer->type, xfer->account, xfer->who, _( "The file you are trying to send is too large!" ) ); purple_xfer_cancel_local( xfer ); return; } /* start the file transfer */ purple_xfer_start( xfer, -1, NULL, 0 ); } else { /* * we have just accepted a file transfer request from MXit. send a confirmation * to the MXit server so that can send us the file */ mxit_send_file_accept( mx->session, mx->fileid, purple_xfer_get_size( xfer ), 0 ); } }
static void begin_transfer(PurpleXfer *xfer, PurpleInputCondition cond) { PurpleXferType type = purple_xfer_get_type(xfer); PurpleXferUiOps *ui_ops = purple_xfer_get_ui_ops(xfer); if (xfer->start_time != 0) { purple_debug_error("xfer", "Transfer is being started multiple times\n"); g_return_if_reached(); } if (ui_ops == NULL || (ui_ops->ui_read == NULL && ui_ops->ui_write == NULL)) { xfer->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer), type == PURPLE_XFER_RECEIVE ? "wb" : "rb"); if (xfer->dest_fp == NULL) { purple_xfer_show_file_error(xfer, purple_xfer_get_local_filename(xfer)); purple_xfer_cancel_local(xfer); return; } fseek(xfer->dest_fp, xfer->bytes_sent, SEEK_SET); } if (xfer->fd != -1) xfer->watcher = purple_input_add(xfer->fd, cond, transfer_cb, xfer); xfer->start_time = time(NULL); if (xfer->ops.start != NULL) xfer->ops.start(xfer); }
static void purple_xfer_destroy(PurpleXfer *xfer) { PurpleXferUiOps *ui_ops; g_return_if_fail(xfer != NULL); if (purple_debug_is_verbose()) purple_debug_info("xfer", "destroyed %p [%d]\n", xfer, xfer->ref); /* Close the file browser, if it's open */ purple_request_close_with_handle(xfer); if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_STARTED) purple_xfer_cancel_local(xfer); ui_ops = purple_xfer_get_ui_ops(xfer); if (ui_ops != NULL && ui_ops->destroy != NULL) ui_ops->destroy(xfer); g_free(xfer->who); g_free(xfer->filename); g_free(xfer->remote_ip); g_free(xfer->local_filename); g_hash_table_remove(xfers_data, xfer); PURPLE_DBUS_UNREGISTER_POINTER(xfer); xfers = g_list_remove(xfers, xfer); g_free(xfer); }
void purple_xfer_end(PurpleXfer *xfer) { g_return_if_fail(xfer != NULL); /* See if we are actually trying to cancel this. */ if (!purple_xfer_is_completed(xfer)) { purple_xfer_cancel_local(xfer); return; } xfer->end_time = time(NULL); if (xfer->ops.end != NULL) xfer->ops.end(xfer); if (xfer->watcher != 0) { purple_input_remove(xfer->watcher); xfer->watcher = 0; } if (xfer->fd != -1) close(xfer->fd); if (xfer->dest_fp != NULL) { fclose(xfer->dest_fp); xfer->dest_fp = NULL; } purple_xfer_unref(xfer); }
static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) { JabberOOBXfer *jox = xfer->data; char test[2048]; char *tmp, *lenstr; int len; if((len = read(xfer->fd, test, sizeof(test))) > 0) { jox->headers = g_string_append_len(jox->headers, test, len); if((tmp = strstr(jox->headers->str, "\r\n\r\n"))) { *tmp = '\0'; lenstr = strstr(jox->headers->str, "Content-Length: "); if(lenstr) { int size; sscanf(lenstr, "Content-Length: %d", &size); purple_xfer_set_size(xfer, size); } purple_xfer_set_read_fnc(xfer, NULL); tmp += 4; *buffer = (unsigned char*) g_strdup(tmp); return strlen(tmp); } return 0; } else if (errno != EAGAIN) { purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Read error on oob xfer!\n"); purple_xfer_cancel_local(xfer); } return 0; }
/*------------------------------------------------------------------------ * A file has been received from the MXit server. * * @param session The MXit session object * @param fileid A unique ID that identifies this file * @param data The file data * @param datalen The size of the data */ void mxit_xfer_rx_file( struct MXitSession* session, const char* fileid, const char* data, int datalen ) { PurpleXfer* xfer = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_rx_file: (size=%i)\n", datalen ); /* find the file-transfer object */ xfer = find_mxit_xfer( session, fileid ); if ( xfer ) { /* this is the transfer we have been looking for */ purple_xfer_ref( xfer ); purple_xfer_start( xfer, -1, NULL, 0 ); if ( fwrite( data, datalen, 1, xfer->dest_fp ) > 0 ) { purple_xfer_unref( xfer ); purple_xfer_set_completed( xfer, TRUE ); purple_xfer_end( xfer ); /* inform MXit that file was successfully received */ mxit_send_file_received( session, fileid, RECV_STATUS_SUCCESS ); } else { /* file write error */ purple_xfer_error( purple_xfer_get_type( xfer ), purple_xfer_get_account( xfer ), purple_xfer_get_remote_user( xfer ), _( "Unable to save the file" ) ); purple_xfer_cancel_local( xfer ); } } else { /* file transfer not found */ mxit_send_file_received( session, fileid, RECV_STATUS_BAD_ID ); } }
static void tgprpl_xfer_send_init (PurpleXfer *X) { debug ("tgprpl_xfer_send_init(): sending xfer accepted."); struct tgp_xfer_send_data *data; const char *file, *localfile, *who; tgl_peer_t *P; data = X->data; purple_xfer_start (X, -1, NULL, 0); file = purple_xfer_get_filename (X); localfile = purple_xfer_get_local_filename (X); who = purple_xfer_get_remote_user (X); debug ("xfer_on_init (file=%s, local=%s, who=%s)", file, localfile, who); P = tgp_blist_lookup_peer_get (data->conn->TLS, who); g_return_if_fail (P); if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT) { purple_xfer_error (PURPLE_XFER_SEND, data->conn->pa, who, _("Sorry, sending documents to encrypted chats not yet supported.")); purple_xfer_cancel_local (X); return; } tgl_do_send_document (data->conn->TLS, P->id, (char*) localfile, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, tgprpl_xfer_send_on_finished, data); // see comment in tgprpl_xfer_recv_init() purple_xfer_ref (X); data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X); data->loading = TRUE; }
static void bonjour_bytestreams_connect(PurpleXfer *xfer) { PurpleBuddy *pb; PurpleAccount *account = NULL; PurpleHash *hash; XepXfer *xf; char dstaddr[41]; const gchar *name = NULL; unsigned char hashval[20]; char *p; int i; if(xfer == NULL) return; purple_debug_info("bonjour", "bonjour-bytestreams-connect.\n"); xf = purple_xfer_get_protocol_data(xfer); if(!xf) return; pb = xf->pb; name = purple_buddy_get_name(pb); account = purple_buddy_get_account(pb); p = g_strdup_printf("%s%s%s", xf->sid, name, bonjour_get_jid(account)); hash = purple_sha1_hash_new(); purple_hash_append(hash, (guchar *)p, strlen(p)); purple_hash_digest(hash, hashval, sizeof(hashval)); g_object_unref(G_OBJECT(hash)); g_free(p); memset(dstaddr, 0, 41); p = dstaddr; for(i = 0; i < 20; i++, p += 2) snprintf(p, 3, "%02x", hashval[i]); xf->proxy_info = purple_proxy_info_new(); purple_proxy_info_set_proxy_type(xf->proxy_info, PURPLE_PROXY_SOCKS5); purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host); purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port); xf->proxy_connection = purple_proxy_connect_socks5_account( purple_account_get_connection(account), account, xf->proxy_info, dstaddr, 0, bonjour_bytestreams_connect_cb, xfer); if(xf->proxy_connection == NULL) { xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); /* Cancel the connection */ purple_xfer_cancel_local(xfer); } }
static void irc_dccsend_network_listen_cb(int sock, gpointer data) { PurpleXfer *xfer = data; struct irc_xfer_send_data *xd; PurpleConnection *gc; struct irc_conn *irc; const char *arg[2]; char *tmp; struct in_addr addr; unsigned short int port; xd = purple_xfer_get_protocol_data(xfer); xd->listen_data = NULL; if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL || purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_REMOTE) { g_object_unref(xfer); return; } xd = purple_xfer_get_protocol_data(xfer); gc = purple_account_get_connection(purple_xfer_get_account(xfer)); irc = purple_connection_get_protocol_data(gc); g_object_unref(xfer); if (sock < 0) { purple_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to open a listening port."), purple_request_cpar_from_connection(gc)); purple_xfer_cancel_local(xfer); return; } xd->fd = sock; port = purple_network_get_port_from_fd(sock); purple_debug_misc("irc", "port is %hu\n", port); /* Monitor the listening socket */ purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ, irc_dccsend_send_connected, xfer)); /* Send the intended recipient the DCC request */ arg[0] = purple_xfer_get_remote_user(xfer); inet_aton(purple_network_get_my_ip(irc->fd), &addr); arg[1] = tmp = g_strdup_printf("\001DCC SEND \"%s\" %u %hu %" G_GOFFSET_FORMAT "\001", purple_xfer_get_filename(xfer), ntohl(addr.s_addr), port, purple_xfer_get_size(xfer)); irc_cmd_privmsg(purple_connection_get_protocol_data(gc), "msg", NULL, arg); g_free(tmp); }
static void connect_cb(gpointer data, gint fd, SIPE_UNUSED_PARAMETER const gchar *error_message) { struct sipe_file_transfer *ft = data; if (fd < 0) { purple_xfer_cancel_local(PURPLE_XFER); return; } purple_xfer_start(PURPLE_XFER, fd, NULL, 0); }
void tgprpl_xfer_free_all (connection_data *conn) { GList *xfers = purple_xfers_get_all(); while (xfers) { PurpleXfer *xfer = xfers->data; struct tgp_xfer_send_data *data = xfer->data; if (data) { purple_xfer_cancel_local (xfer); } xfers = g_list_next(xfers); } }
static void purple_xfer_choose_file_cancel_cb(void *user_data, const char *filename) { PurpleXfer *xfer = (PurpleXfer *)user_data; purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_LOCAL); if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) purple_xfer_cancel_local(xfer); else purple_xfer_request_denied(xfer); purple_xfer_unref(xfer); }
static void connect_cb(gpointer data, gint source, const gchar *error_message) { PurpleXfer *xfer = (PurpleXfer *)data; if (source < 0) { purple_xfer_cancel_local(xfer); return; } xfer->fd = source; begin_transfer(xfer, PURPLE_INPUT_READ); }
static void stop_button_cb(GntButton *button) { PurpleXfer *selected_xfer = gnt_tree_get_selection_data(GNT_TREE(xfer_dialog->tree)); PurpleXferStatusType status; if (!selected_xfer) return; status = purple_xfer_get_status(selected_xfer); if (status != PURPLE_XFER_STATUS_CANCEL_LOCAL && status != PURPLE_XFER_STATUS_CANCEL_REMOTE && status != PURPLE_XFER_STATUS_DONE) purple_xfer_cancel_local(selected_xfer); }
static gboolean peer_connection_destroy_cb(gpointer data) { PeerConnection *conn; conn = data; purple_request_close_with_handle(conn); peer_connection_close(conn); if (conn->checksum_data != NULL) peer_oft_checksum_destroy(conn->checksum_data); if (conn->xfer != NULL) { PurpleXferStatusType status; conn->xfer->data = NULL; status = purple_xfer_get_status(conn->xfer); if ((status != PURPLE_XFER_STATUS_DONE) && (status != PURPLE_XFER_STATUS_CANCEL_LOCAL) && (status != PURPLE_XFER_STATUS_CANCEL_REMOTE)) { if ((conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) || (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_REFUSED)) purple_xfer_cancel_remote(conn->xfer); else purple_xfer_cancel_local(conn->xfer); } purple_xfer_unref(conn->xfer); conn->xfer = NULL; } g_free(conn->bn); g_free(conn->error_message); g_free(conn->proxyip); g_free(conn->clientip); g_free(conn->verifiedip); g_free(conn->xferdata.name); purple_circ_buffer_destroy(conn->buffer_outgoing); conn->od->peer_connections = g_slist_remove(conn->od->peer_connections, conn); g_free(conn); return FALSE; }
static void bonjour_bytestreams_init(PurpleXfer *xfer) { XepXfer *xf; if(xfer == NULL) return; purple_debug_info("bonjour", "Bonjour-bytestreams-init.\n"); xf = purple_xfer_get_protocol_data(xfer); xf->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, FALSE, bonjour_bytestreams_listen, xfer); if (xf->listen_data == NULL) purple_xfer_cancel_local(xfer); return; }
static void recv_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; LwqqMsgFileMessage* file = xfer->data; const char* filename = purple_xfer_get_local_filename(xfer); xfer->start_time = time(NULL); LwqqAsyncEvent* ev = lwqq_msg_accept_file(lc,file,filename); if(ev == NULL){ lwqq_puts("file trans error "); purple_xfer_error(PURPLE_XFER_RECEIVE, ac->account, purple_xfer_get_remote_user(xfer), "接受文件失败"); purple_xfer_cancel_local(xfer); return; } lwqq_async_event_set_progress(ev,file_trans_on_progress,xfer); lwqq_async_add_event_listener(ev,_C_(p,recv_file_complete,xfer)); }
static void recv_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; LwqqMsgFileMessage* file = xfer->data; const char* filename = purple_xfer_get_local_filename(xfer); xfer->start_time = time(NULL); LwqqAsyncEvent* ev = lwqq_msg_accept_file(lc,file,filename); if(ev == NULL){ lwqq_puts("file trans error "); purple_xfer_error(PURPLE_XFER_RECEIVE, ac->account, purple_xfer_get_remote_user(xfer), _("Receive file failed")); purple_xfer_cancel_local(xfer); return; } LwqqHttpRequest* req = lwqq_async_event_get_conn(ev); lwqq_http_on_progress(req, file_trans_on_progress, xfer); lwqq_http_set_option(req, LWQQ_HTTP_CANCELABLE,1L); lwqq_async_add_event_listener(ev,_C_(2p,recv_file_complete,xfer,ev)); }
static void bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) { PurpleXfer *xfer = data; XepXfer *xf = xfer->data; XepIq *iq; xmlnode *q_node, *tmp_node; BonjourData *bd; gboolean ret = FALSE; xf->proxy_connection = NULL; if(source < 0) { purple_debug_error("bonjour", "Error connecting via SOCKS5 to %s - %s\n", xf->proxy_host, error_message ? error_message : "(null)"); tmp_node = xmlnode_get_next_twin(xf->streamhost); ret = __xep_bytestreams_parse(xf->pb, xfer, tmp_node, xf->iq_id); if (!ret) { xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); /* Cancel the connection */ purple_xfer_cancel_local(xfer); } return; } purple_debug_info("bonjour", "Connected successfully via SOCKS5, starting transfer.\n"); bd = xf->data; /* Here, start the file transfer.*/ /* Notify Initiator of Connection */ iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->iq_id); q_node = xmlnode_new_child(iq->node, "query"); xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams"); tmp_node = xmlnode_new_child(q_node, "streamhost-used"); xmlnode_set_attrib(tmp_node, "jid", xf->jid); xep_iq_send_and_free(iq); purple_xfer_start(xfer, source, NULL, -1); }
static void bonjour_bytestreams_init(PurpleXfer *xfer) { XepXfer *xf; if(xfer == NULL) return; purple_debug_info("bonjour", "Bonjour-bytestreams-init.\n"); xf = xfer->data; purple_network_listen_map_external(FALSE); xf->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM, bonjour_bytestreams_listen, xfer); purple_network_listen_map_external(TRUE); if (xf->listen_data == NULL) purple_xfer_cancel_local(xfer); return; }
/* * This function is called after the user has selected a file to send. */ static void irc_dccsend_send_init(PurpleXfer *xfer) { PurpleConnection *gc = purple_account_get_connection(purple_xfer_get_account(xfer)); struct irc_xfer_send_data *xd = xfer->data; xfer->filename = g_path_get_basename(xfer->local_filename); purple_xfer_ref(xfer); /* Create a listening socket */ xd->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM, irc_dccsend_network_listen_cb, xfer); if (xd->listen_data == NULL) { purple_xfer_unref(xfer); purple_notify_error(gc, NULL, _("File Transfer Failed"), _("Could not open a listening port.")); purple_xfer_cancel_local(xfer); } }
static void _qq_recv_file_progess(PurpleConnection *gc, guint8 *buffer, guint16 len, guint32 index, guint32 offset) { qq_data *qd = (qq_data *) gc->proto_data; PurpleXfer *xfer = qd->xfer; ft_info *info = (ft_info *) xfer->data; guint32 mask; purple_debug_info("QQ", "receiving %dth fragment with length %d, slide window status %o, max_fragment_index %d\n", index, len, info->window, info->max_fragment_index); if (info->window == 0 && info->max_fragment_index == 0) { if (_qq_xfer_open_file(purple_xfer_get_local_filename(xfer), "wb", xfer) == -1) { purple_xfer_cancel_local(xfer); return; } purple_debug_info("QQ", "object file opened for writing\n"); } mask = 0x1 << (index % sizeof(info->window)); if (index < info->max_fragment_index || (info->window & mask)) { purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", index+1); return; } info->window |= mask; _qq_xfer_write_file(buffer, index, len, xfer); xfer->bytes_sent += len; xfer->bytes_remaining -= len; purple_xfer_update_progress(xfer); mask = 0x1 << (info->max_fragment_index % sizeof(info->window)); while (info->window & mask) { info->window &= ~mask; info->max_fragment_index ++; if (mask & 0x8000) mask = 0x0001; else mask = mask << 1; } purple_debug_info("QQ", "procceed %dth fragment, slide window status %o, max_fragment_index %d\n", index, info->window, info->max_fragment_index); }
/* * This function is called after the user has selected a file to send. */ static void irc_dccsend_send_init(PurpleXfer *xfer) { PurpleConnection *gc = purple_account_get_connection(purple_xfer_get_account(xfer)); struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer); purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer))); g_object_ref(xfer); /* Create a listening socket */ xd->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, irc_dccsend_network_listen_cb, xfer); if (xd->listen_data == NULL) { g_object_unref(xfer); purple_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to open a listening port."), purple_request_cpar_from_connection(gc)); purple_xfer_cancel_local(xfer); } }
void purple_xfer_request(PurpleXfer *xfer) { g_return_if_fail(xfer != NULL); g_return_if_fail(xfer->ops.init != NULL); purple_xfer_ref(xfer); if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { purple_signal_emit(purple_xfers_get_handle(), "file-recv-request", xfer); if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) { /* The file-transfer was cancelled by a plugin */ purple_xfer_cancel_local(xfer); } else if (purple_xfer_get_filename(xfer) || purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_ACCEPTED) { gchar* message = NULL; PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who); message = g_strdup_printf(_("%s is offering to send file %s"), buddy ? purple_buddy_get_alias(buddy) : xfer->who, purple_xfer_get_filename(xfer)); purple_xfer_conversation_write_with_thumbnail(xfer, message); g_free(message); /* Ask for a filename to save to if it's not already given by a plugin */ if (xfer->local_filename == NULL) purple_xfer_ask_recv(xfer); } else { purple_xfer_ask_accept(xfer); } } else { purple_xfer_choose_file(xfer); } }
static void skypeweb_got_file(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { SkypeWebFileTransfer *swft = user_data; PurpleXfer *xfer = swft->xfer; SkypeWebAccount *sa = swft->sa; sa->url_datas = g_slist_remove(sa->url_datas, url_data); if (error_message) { purple_xfer_error(purple_xfer_get_type(xfer), sa->account, swft->from, error_message); purple_xfer_cancel_local(xfer); } else { purple_xfer_write_file(xfer, (guchar *)url_text, len); purple_xfer_set_bytes_sent(xfer, len); purple_xfer_set_completed(xfer, TRUE); } //cleanup skypeweb_free_xfer(xfer); }
static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInputCondition cond) { PurpleXfer *xfer = data; JabberOOBXfer *jox = xfer->data; int len, total_len = strlen(jox->write_buffer); len = write(xfer->fd, jox->write_buffer + jox->written_len, total_len - jox->written_len); if(len < 0 && errno == EAGAIN) return; else if(len < 0) { purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Write error on oob xfer!\n"); purple_input_remove(jox->writeh); purple_xfer_cancel_local(xfer); } jox->written_len += len; if(jox->written_len == total_len) { purple_input_remove(jox->writeh); g_free(jox->write_buffer); jox->write_buffer = NULL; } }