示例#1
0
static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
{
	gssize len;
	struct yahoo_xfer_data *xd = xfer->data;

	if (!xd)
		return -1;

	if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND) {
		return -1;
	}

	len = write(xfer->fd, buffer, size);

	if (len == -1) {
		if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))
			purple_xfer_set_completed(xfer, TRUE);
		if ((errno != EAGAIN) && (errno != EINTR))
			return -1;
		return 0;
	}

	if ((purple_xfer_get_bytes_sent(xfer) + len) >= purple_xfer_get_size(xfer))
		purple_xfer_set_completed(xfer, TRUE);

	return len;
}
示例#2
0
static void tgprpl_xfer_recv_on_finished (struct tgl_state *TLS, void *_data, int success, const char *filename) {
  debug ("tgprpl_xfer_recv_on_finished()");
  struct tgp_xfer_send_data *data = _data;
  char *selected = g_strdup (purple_xfer_get_local_filename (data->xfer));

  if (success) {
    debug ("purple_xfer_set_completed");

    // always completed the file transfer to avoid a warning dialogue when closing (Adium)
    purple_xfer_set_bytes_sent (data->xfer, purple_xfer_get_size (data->xfer));
    purple_xfer_set_completed (data->xfer, TRUE);

    if (! purple_xfer_is_canceled (data->xfer)) {
      purple_xfer_end (data->xfer);
    }
  } else {
    tgp_notify_on_error_gw (TLS, NULL, success);
    if (! purple_xfer_is_canceled (data->xfer)) {
      purple_xfer_cancel_remote (data->xfer);
    }
    failure ("recv xfer failed");
  }

  data->loading = FALSE;

  data->xfer->data = NULL;
  purple_xfer_unref (data->xfer);
  tgprpl_xfer_free_data (data);

  debug ("moving transferred file from tgl directory %s to selected target %s", selected, filename);
  g_unlink (selected);
  g_rename (filename, selected);
  g_free (selected);
}
示例#3
0
static void ggp_edisc_xfer_recv_done(PurpleHttpConnection *hc,
	PurpleHttpResponse *response, gpointer _xfer)
{
	PurpleXfer *xfer = _xfer;
	ggp_edisc_xfer *edisc_xfer = purple_xfer_get_protocol_data(xfer);

	if (purple_xfer_is_cancelled(xfer))
		return;

	g_return_if_fail(edisc_xfer != NULL);

	edisc_xfer->hc = NULL;

	if (!purple_http_response_is_successful(response)) {
		ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
		return;
	}

	if (purple_xfer_get_bytes_remaining(xfer) == 0) {
		purple_xfer_set_completed(xfer, TRUE);
		purple_xfer_end(xfer);
		ggp_edisc_xfer_free(xfer);
	} else {
		purple_debug_warning("gg", "ggp_edisc_xfer_recv_done: didn't "
			"received everything\n");
		ggp_edisc_xfer_error(xfer, _("Error while receiving a file"));
	}
}
示例#4
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;
	struct mxitxfer*	mx		= 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 ) {
		mx = xfer->data;

		/* this is the transfer we have been looking for */
		purple_xfer_ref( xfer );
		purple_xfer_start( xfer, -1, NULL, 0 );
		fwrite( data, datalen, 1, xfer->dest_fp );
		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 transfer not found */
		mxit_send_file_received( session, fileid, RECV_STATUS_BAD_ID );
	}
}
示例#5
0
static void tgprpl_xfer_send_on_finished (struct tgl_state *TLS, void *_data, int success, struct tgl_message *M) {
  debug ("tgprpl_xfer_on_finished()");
  struct tgp_xfer_send_data *data = _data;

  if (success) {
    if (! purple_xfer_is_canceled (data->xfer)) {
      debug ("purple_xfer_set_completed");
      purple_xfer_set_bytes_sent (data->xfer, purple_xfer_get_size (data->xfer));
      purple_xfer_set_completed (data->xfer, TRUE);
      purple_xfer_end (data->xfer);
    }
    write_secret_chat_file (TLS);
  } else {
    tgp_notify_on_error_gw (TLS, NULL, success);
    if (! purple_xfer_is_canceled (data->xfer)) {
      purple_xfer_cancel_remote (data->xfer);
    }
    failure ("send xfer failed");
  }

  data->loading = FALSE;

  data->xfer->data = NULL;
  purple_xfer_unref (data->xfer);
  tgprpl_xfer_free_data (data);
}
示例#6
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 );
	}
}
示例#7
0
文件: slp.c 项目: deadcow/msn-pecan
void
msn_xfer_completed_cb(MsnSlpCall *slpcall, const guchar *body,
					  gsize size)
{
	PurpleXfer *xfer = slpcall->xfer;
	purple_xfer_set_completed(xfer, TRUE);
	purple_xfer_end(xfer);
}
示例#8
0
static void
xfer_completed_cb(struct pn_peer_call *call,
                  const guchar *body,
                  gsize size)
{
    PurpleXfer *xfer = call->xfer;
    purple_xfer_set_completed(xfer, TRUE);
    purple_xfer_end(xfer);
}
示例#9
0
static void _qq_update_send_progess(PurpleConnection *gc, guint32 fragment_index)
{
	guint32 mask;
	guint8 *buffer;
	gint readbytes;
	qq_data *qd = (qq_data *) gc->proto_data;
	PurpleXfer *xfer = qd->xfer;
	ft_info *info = (ft_info *) xfer->data;

	purple_debug_info("QQ",
			"receiving %dth fragment ack, slide window status %o, max_fragment_index %d\n",
			fragment_index, info->window, info->max_fragment_index);
	if (fragment_index < info->max_fragment_index ||
			fragment_index >= info->max_fragment_index + sizeof(info->window)) {
		purple_debug_info("QQ", "duplicate %dth fragment, drop it!\n", fragment_index+1);
		return;
	}
	mask = 0x1 << (fragment_index % sizeof(info->window));
	if ((info->window & mask) == 0)
	{
		info->window |= mask;
		if (fragment_index + 1 != info->fragment_num) {
			xfer->bytes_sent += info->fragment_len;
		} else {
			xfer->bytes_sent += purple_xfer_get_size(xfer) % info->fragment_len;
		}
		xfer->bytes_remaining = purple_xfer_get_size(xfer) - purple_xfer_get_bytes_sent(xfer);
		purple_xfer_update_progress(xfer);
		if (purple_xfer_get_bytes_remaining(xfer) <= 0) {
			/* We have finished sending the file */
			purple_xfer_set_completed(xfer, TRUE);
			return;
		}
		mask = 0x1 << (info->max_fragment_index % sizeof(info->window));
		while (info->window & mask)
		{
			/* move the slide window */
			info->window &= ~mask;

			buffer = g_newa(guint8, info->fragment_len);
			readbytes = _qq_xfer_read_file(buffer, info->max_fragment_index + sizeof(info->window),
					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 + sizeof(info->window) + 1, 0, buffer, readbytes);

			info->max_fragment_index ++;
			if (mask & 0x8000) mask = 0x0001;
			else mask = mask << 1;
		}
	}
	purple_debug_info("QQ",
			"procceed %dth fragment ack, slide window status %o, max_fragment_index %d\n",
			fragment_index, info->window, info->max_fragment_index);
}
示例#10
0
static gssize
tftp_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
{
	gssize bytes_written = sipe_core_tftp_write(PURPLE_XFER_TO_SIPE_FILE_TRANSFER,
						    buffer, size);

	if ((xfer->bytes_remaining - bytes_written) == 0)
		purple_xfer_set_completed(xfer, TRUE);

	return bytes_written;
}
示例#11
0
/* just in case you were wondering, this is why DCC is gay */
static void irc_dccsend_send_read(gpointer data, int source, PurpleInputCondition cond)
{
    PurpleXfer *xfer = data;
    struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
    char buffer[64];
    int len;

    len = read(source, buffer, sizeof(buffer));

    if (len < 0 && errno == EAGAIN)
        return;
    else if (len <= 0) {
        /* XXX: Shouldn't this be canceling the transfer? */
        purple_input_remove(xd->inpa);
        xd->inpa = 0;
        return;
    }

    xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);
    memcpy(xd->rxqueue + xd->rxlen, buffer, len);
    xd->rxlen += len;

    while (1) {
        gint32 val;
        size_t acked;

        if (xd->rxlen < 4)
            break;

        memcpy(&val, xd->rxqueue, sizeof(val));
        acked = ntohl(val);

        xd->rxlen -= 4;
        if (xd->rxlen) {
            unsigned char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen);
            g_free(xd->rxqueue);
            xd->rxqueue = tmp;
        } else {
            g_free(xd->rxqueue);
            xd->rxqueue = NULL;
        }

        if ((goffset)acked >= purple_xfer_get_size(xfer)) {
            purple_input_remove(xd->inpa);
            xd->inpa = 0;
            purple_xfer_set_completed(xfer, TRUE);
            purple_xfer_end(xfer);
            return;
        }
    }
}
示例#12
0
文件: ft.c 项目: lawm/pidgin-lwqq
static void send_offline_file_receipt(LwqqAsyncEvent* ev,PurpleXfer* xfer)
{
    int errno = lwqq_async_event_get_result(ev);
    qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
    LwqqMsgOffFile* file = xfer->data;

    if(errno == 0){
        qq_sys_msg_write(ac, LWQQ_MT_BUDDY_MSG, file->to, "发送离线文件成功", PURPLE_MESSAGE_SYSTEM, time(NULL));
    }else{
        qq_sys_msg_write(ac, LWQQ_MT_BUDDY_MSG, file->to, "发送离线文件失败", PURPLE_MESSAGE_ERROR, time(NULL));
    }
    lwqq_msg_offfile_free(file);
    purple_xfer_set_completed(xfer,1);
}
示例#13
0
static void waprpl_check_complete_uploads(PurpleConnection * gc) {
	whatsapp_connection *wconn = purple_connection_get_protocol_data(gc);
	
	GList *xfers = purple_xfers_get_all();
	while (xfers) {
		PurpleXfer *xfer = xfers->data;
		wa_file_upload *xinfo = (wa_file_upload *) xfer->data;
		if (!xinfo->done && xinfo->started && waAPI_fileuploadcomplete(wconn->waAPI, xinfo->ref_id)) {
			purple_debug_info("waprpl", "Upload complete\n");
			purple_xfer_set_completed(xfer, TRUE);
			xinfo->done = 1;
		}
		xfers = g_list_next(xfers);
	}
}
示例#14
0
static void
skypeweb_init_vm_download(PurpleXfer *xfer)
{
	JsonObject *file = xfer->data;
	gint64 fileSize;
	const gchar *url;

	fileSize = json_object_get_int_member(file, "fileSize");
	url = json_object_get_string_member(file, "url");
	
	purple_xfer_set_completed(xfer, FALSE);
	purple_util_fetch_url_request(xfer->account, url, TRUE, NULL, FALSE, NULL, FALSE, fileSize, skypeweb_got_vm_file, xfer);
	
	json_object_unref(file);
}
示例#15
0
文件: ft.c 项目: 5rather/pidgin-lwqq
static void send_file(LwqqAsyncEvent* event,PurpleXfer *xfer)
{
	//now xfer is not valid.
	if(event->failcode != LWQQ_CALLBACK_VALID && event->failcode != LWQQ_CALLBACK_FAILED) return;

	qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
	LwqqClient* lc = ac->qq;
	long err = 0;
	if(event->failcode==LWQQ_CALLBACK_FAILED){
		lwqq_msg_free((LwqqMsg*)xfer->data);
		purple_xfer_set_completed(xfer, 1);
		return;
	}
	err = lwqq_async_event_get_result(event);
	LwqqMsgOffFile* file = xfer->data;
	if(err) {
		qq_sys_msg_write(ac,LWQQ_MS_BUDDY_MSG, file->super.to,_("Send offline file failed"),PURPLE_MESSAGE_ERROR,time(NULL));
		lwqq_msg_free((LwqqMsg*)file);
		purple_xfer_set_completed(xfer,1);
	} else {
		LwqqAsyncEvent* ev = lwqq_msg_send_offfile(lc,file);
		lwqq_async_add_event_listener(ev,_C_(2p,send_offline_file_receipt,ev,xfer));
	}
}
示例#16
0
文件: ft.c 项目: 5rather/pidgin-lwqq
static void send_offline_file_receipt(LwqqAsyncEvent* ev,PurpleXfer* xfer)
{
	int err = lwqq_async_event_get_result(ev);
	qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
	LwqqMsgOffFile* file = xfer->data;

	if(err == 0){
		qq_sys_msg_write(ac, LWQQ_MS_BUDDY_MSG, file->super.to, _("Send offline file successful"), PURPLE_MESSAGE_SYSTEM, time(NULL));
	}else{
		char buf[512];
		snprintf(buf,sizeof(buf),_("Send offline file failed,Error Code:%d"),err);
		qq_sys_msg_write(ac, LWQQ_MS_BUDDY_MSG, file->super.to, buf, PURPLE_MESSAGE_ERROR, time(NULL));
	}
	lwqq_msg_free((LwqqMsg*)file);
	purple_xfer_set_completed(xfer,1);
}
示例#17
0
static void recv_file_complete(PurpleXfer* xfer,LwqqAsyncEvent* ev)
{
    if(ev->failcode == LWQQ_CALLBACK_CANCELED) return;
    qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
    LwqqMsgFileMessage* file = xfer->data;
    char buf[512];
    const char* extra = NULL;
    if(ev->result) {
        snprintf(buf,sizeof(buf),"传输失败,错误号:%d\n",ev->result);
        if(ev->result == 102)
            extra = "对方是用webqq发送的吧.\n让对方发离线文件或邮件吧.";
        else extra = NULL;
        purple_notify_error(ac->gc,"文件传输",buf,extra);
    }
    purple_xfer_set_completed(xfer,1);
    lwqq_msg_free((LwqqMsg*)file);
}
示例#18
0
static void
skypeweb_init_vm_download(PurpleXfer *xfer)
{
	SkypeWebAccount *sa;
	JsonObject *file = xfer->data;
	gint64 fileSize;
	const gchar *url;

	fileSize = json_object_get_int_member(file, "fileSize");
	url = json_object_get_string_member(file, "url");
	
	purple_xfer_set_completed(xfer, FALSE);
	sa = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
	skypeweb_fetch_url_request(sa, url, TRUE, NULL, FALSE, NULL, FALSE, fileSize, skypeweb_got_vm_file, xfer);
	
	json_object_unref(file);
}
示例#19
0
文件: ft.c 项目: 5rather/pidgin-lwqq
static void recv_file_complete(PurpleXfer* xfer,LwqqAsyncEvent* ev)
{
	if(ev->failcode == LWQQ_CALLBACK_CANCELED) return;
	qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
	LwqqMsgFileMessage* file = xfer->data;
	char buf[512];
	const char* extra = NULL;
	if(ev->result){
		snprintf(buf,sizeof(buf),_("Transport Failed,Error Code:%d\n"),ev->result);
		if(ev->result == 102)
			extra = _("Other may send via webqq.\nPlease call him send via email or offline file.");
		else extra = NULL;
		purple_notify_error(ac->gc,_("File Transport"),buf,extra);
	}
	purple_xfer_set_completed(xfer,1);
	lwqq_msg_free((LwqqMsg*)file);
}
示例#20
0
static void tgprpl_xfer_on_finished (struct tgl_state *TLS, void *_data, int success, struct tgl_message *M) {
  debug ("tgprpl_xfer_on_finished()");
  struct tgp_xfer_send_data *data = _data;
  
  if (success) {
    if (!data->done) {
      debug ("purple_xfer_set_completed");
      purple_xfer_set_bytes_sent (data->xfer, purple_xfer_get_size (data->xfer));
      purple_xfer_set_completed (data->xfer, TRUE);
      purple_xfer_end(data->xfer);
    }
  } else {
    failure ("ERROR xfer failed");
  }
  
  data->xfer->data = NULL;
  tgprpl_xfer_free_data (data);
}
示例#21
0
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);
}
示例#22
0
文件: ft.c 项目: lawm/pidgin-lwqq
static void send_file(LwqqAsyncEvent* event,PurpleXfer *xfer)
{
    qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account));
    LwqqClient* lc = ac->qq;
    long errno = 0;
    if(lwqq_async_event_get_code(event)==LWQQ_CALLBACK_FAILED){
        s_free(xfer->data);
        return;
    }
    errno = lwqq_async_event_get_result(event);
    LwqqMsgOffFile* file = xfer->data;
    //purple_xfer_unref(xfer);
    if(errno) {
        qq_sys_msg_write(ac,LWQQ_MT_BUDDY_MSG, file->to,"上传空间不足",PURPLE_MESSAGE_ERROR,time(NULL));
        lwqq_msg_offfile_free(file);
        s_free(xfer->data);
        purple_xfer_set_completed(xfer,1);
    } else {
        LwqqAsyncEvent* ev = lwqq_msg_send_offfile(lc,file);
        lwqq_async_add_event_listener(ev,_C_(2p,send_offline_file_receipt,ev,xfer));
    }
}
示例#23
0
static void tgprpl_xfer_recv_on_finished (struct tgl_state *TLS, void *_data, int success, const char *filename) {
  debug ("tgprpl_xfer_recv_on_finished()");
  struct tgp_xfer_send_data *data = _data;

  if (success) {
    if (!data->done) {
      debug ("purple_xfer_set_completed");
      purple_xfer_set_bytes_sent (data->xfer, purple_xfer_get_size (data->xfer));
      purple_xfer_set_completed (data->xfer, TRUE);
      purple_xfer_end (data->xfer);
    }
    
    g_unlink (purple_xfer_get_local_filename (data->xfer));
    g_rename (filename, purple_xfer_get_local_filename (data->xfer));

  } else {
    failure ("ERROR xfer failed");
  }

  data->xfer->data = NULL;
  tgprpl_xfer_free_data (data);
}
示例#24
0
/* Checks if the WA protocol has data to output and schedules a write handler */
void waprpl_check_ssl_output(PurpleConnection * gc)
{
	whatsapp_connection *wconn = purple_connection_get_protocol_data(gc);
	if (wconn->sslfd < 0)
		return;

	int r = waAPI_sslhasoutdata(wconn->waAPI);
	if (r > 0) {
		/* Need to watch for output data (if we are not doing it already) */
		if (wconn->sslwh == 0)
			wconn->sslwh = purple_input_add(wconn->sslfd, PURPLE_INPUT_WRITE, waprpl_ssl_output_cb, gc);
	} else if (r < 0) {
		waprpl_ssl_cerr_cb(0, 0, gc);	/* Finished the connection! */
	} else {
		if (wconn->sslwh != 0)
			purple_input_remove(wconn->sslwh);

		wconn->sslwh = 0;
	}

	/* Update transfer status */
	int rid, bytes_sent;
	if (waAPI_fileuploadprogress(wconn->waAPI, &rid, &bytes_sent)) {
		GList *xfers = purple_xfers_get_all();
		while (xfers) {
			PurpleXfer *xfer = xfers->data;
			wa_file_upload *xinfo = (wa_file_upload *) xfer->data;
			if (xinfo->ref_id == rid) {
				purple_debug_info("waprpl", "Upload progress %d bytes done\n", bytes_sent);
				purple_xfer_set_bytes_sent(xfer, bytes_sent);
				purple_xfer_update_progress(xfer);
				if (bytes_sent >= (signed)purple_xfer_get_size(xfer))
					purple_xfer_set_completed(xfer, TRUE);
				break;
			}
			xfers = g_list_next(xfers);
		}
	}
}
示例#25
0
gssize
purple_xfer_write(PurpleXfer *xfer, const guchar *buffer, gsize size)
{
	gssize r, s;

	g_return_val_if_fail(xfer   != NULL, 0);
	g_return_val_if_fail(buffer != NULL, 0);
	g_return_val_if_fail(size   != 0,    0);

	s = MIN(purple_xfer_get_bytes_remaining(xfer), size);

	if (xfer->ops.write != NULL) {
		r = (xfer->ops.write)(buffer, s, xfer);
	} else {
		r = write(xfer->fd, buffer, s);
		if (r < 0 && errno == EAGAIN)
			r = 0;
		if ((purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer))
			purple_xfer_set_completed(xfer, TRUE);
	}

	return r;
}
示例#26
0
/*------------------------------------------------------------------------
 * Send the file data.
 *
 *  @param buffer		The data to sent
 *  @param size			The length of the data to send
 *  @param xfer			The file transfer object
 *  @return				The amount of data actually sent
 */
static gssize mxit_xfer_write( const guchar* buffer, size_t size, PurpleXfer* xfer )
{
	struct mxitxfer*	mx	= (struct mxitxfer*) xfer->data;

	purple_debug_info( MXIT_PLUGIN_ID, "mxit_xfer_write\n" );

	if ( !mx ) {
		purple_debug_warning( MXIT_PLUGIN_ID, "mxit_xfer_write: invalid internal mxit xfer data\n" );
		return -1;
	}
	else if ( purple_xfer_get_type( xfer ) != PURPLE_XFER_SEND ) {
		purple_debug_warning( MXIT_PLUGIN_ID, "mxit_xfer_write: wrong xfer type received\n" );
		return -1;
	}

	/* create and send the packet to MXit */
	mxit_send_file( mx->session, purple_xfer_get_remote_user( xfer ), purple_xfer_get_filename( xfer ), buffer, size );

	/* the transfer is complete */
	purple_xfer_set_completed( xfer, TRUE );

	return size;
}
示例#27
0
static void ggp_edisc_xfer_send_done(PurpleHttpConnection *hc,
	PurpleHttpResponse *response, gpointer _xfer)
{
	PurpleXfer *xfer = _xfer;
	ggp_edisc_xfer *edisc_xfer = purple_xfer_get_protocol_data(xfer);
	const gchar *data = purple_http_response_get_data(response, NULL);
	JsonParser *parser;
	JsonObject *result;
	int result_status = -1;

	if (purple_xfer_is_cancelled(xfer))
		return;

	g_return_if_fail(edisc_xfer != NULL);

	edisc_xfer->hc = NULL;

	if (!purple_http_response_is_successful(response)) {
		ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
		return;
	}

	parser = ggp_json_parse(data);
	result = json_node_get_object(json_parser_get_root(parser));
	result = json_object_get_object_member(result, "result");
	if (json_object_has_member(result, "status"))
		result_status = json_object_get_int_member(result, "status");
	g_object_unref(parser);

	if (result_status == 0) {
		purple_xfer_set_completed(xfer, TRUE);
		purple_xfer_end(xfer);
		ggp_edisc_xfer_free(xfer);
	} else
		ggp_edisc_xfer_error(xfer, _("Error while sending a file"));
}
static void
yahoo_process_filetrans_15_downloaded(PurpleHttpConnection *hc,
	PurpleHttpResponse *response, gpointer _xfer)
{
	PurpleXfer *xfer = _xfer;
	struct yahoo_xfer_data *xd;

	xd = purple_xfer_get_protocol_data(xfer);

	xd->hc = NULL;

	if (purple_xfer_is_cancelled(xfer))
		return;

	if (!purple_http_response_is_successful(response) ||
		purple_xfer_get_bytes_remaining(xfer) > 0)
	{
		purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
		purple_xfer_end(xfer);
	} else {
		purple_xfer_set_completed(xfer, TRUE);
		purple_xfer_end(xfer);
	}
}
示例#29
0
static void
do_transfer(PurpleXfer *xfer)
{
	PurpleXferUiOps *ui_ops;
	guchar *buffer = NULL;
	gssize r = 0;

	ui_ops = purple_xfer_get_ui_ops(xfer);

	if (xfer->type == PURPLE_XFER_RECEIVE) {
		r = purple_xfer_read(xfer, &buffer);
		if (r > 0) {
			size_t wc;
			if (ui_ops && ui_ops->ui_write)
				wc = ui_ops->ui_write(xfer, buffer, r);
			else
				wc = fwrite(buffer, 1, r, xfer->dest_fp);

			if (wc != r) {
				purple_debug_error("filetransfer", "Unable to write whole buffer.\n");
				purple_xfer_cancel_local(xfer);
				g_free(buffer);
				return;
			}

			if ((purple_xfer_get_size(xfer) > 0) &&
				((purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer)))
				purple_xfer_set_completed(xfer, TRUE);
		} else if(r < 0) {
			purple_xfer_cancel_remote(xfer);
			g_free(buffer);
			return;
		}
	} else if (xfer->type == PURPLE_XFER_SEND) {
		size_t result = 0;
		size_t s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size);
		PurpleXferPrivData *priv = g_hash_table_lookup(xfers_data, xfer);
		gboolean read = TRUE;

		/* this is so the prpl can keep the connection open
		   if it needs to for some odd reason. */
		if (s == 0) {
			if (xfer->watcher) {
				purple_input_remove(xfer->watcher);
				xfer->watcher = 0;
			}
			return;
		}

		if (priv->buffer) {
			if (priv->buffer->len < s) {
				s -= priv->buffer->len;
				read = TRUE;
			} else {
				read = FALSE;
			}
		}

		if (read) {
			if (ui_ops && ui_ops->ui_read) {
				gssize tmp = ui_ops->ui_read(xfer, &buffer, s);
				if (tmp == 0) {
					/*
					 * The UI claimed it was ready, but didn't have any data for
					 * us...  It will call purple_xfer_ui_ready when ready, which
					 * sets back up this watcher.
					 */
					if (xfer->watcher != 0) {
						purple_input_remove(xfer->watcher);
						xfer->watcher = 0;
					}

					/* Need to indicate the prpl is still ready... */
					priv->ready |= PURPLE_XFER_READY_PRPL;

					g_return_if_reached();
				} else if (tmp < 0) {
					purple_debug_error("filetransfer", "Unable to read whole buffer.\n");
					purple_xfer_cancel_local(xfer);
					return;
				}

				result = tmp;
			} else {
				buffer = g_malloc(s);
				result = fread(buffer, 1, s, xfer->dest_fp);
				if (result != s) {
					purple_debug_error("filetransfer", "Unable to read whole buffer.\n");
					purple_xfer_cancel_local(xfer);
					g_free(buffer);
					return;
				}
			}
		}

		if (priv->buffer) {
			g_byte_array_append(priv->buffer, buffer, result);
			g_free(buffer);
			buffer = priv->buffer->data;
			result = priv->buffer->len;
		}

		r = purple_xfer_write(xfer, buffer, result);

		if (r == -1) {
			purple_xfer_cancel_remote(xfer);
			if (!priv->buffer)
				/* We don't free buffer if priv->buffer is set, because in
				   that case buffer doesn't belong to us. */
				g_free(buffer);
			return;
		} else if (r == result) {
			/*
			 * We managed to write the entire buffer.  This means our
			 * network is fast and our buffer is too small, so make it
			 * bigger.
			 */
			purple_xfer_increase_buffer_size(xfer);
		} else {
			if (ui_ops && ui_ops->data_not_sent)
				ui_ops->data_not_sent(xfer, buffer + r, result - r);
		}

		if (priv->buffer) {
			/*
			 * Remove what we wrote
			 * If we wrote the whole buffer the byte array will be empty
			 * Otherwise we'll keep what wasn't sent for next time.
			 */
			buffer = NULL;
			g_byte_array_remove_range(priv->buffer, 0, r);
		}
	}

	if (r > 0) {
		if (purple_xfer_get_size(xfer) > 0)
			xfer->bytes_remaining -= r;

		xfer->bytes_sent += r;

		if (xfer->ops.ack != NULL)
			xfer->ops.ack(xfer, buffer, r);

		g_free(buffer);

		if (ui_ops != NULL && ui_ops->update_progress != NULL)
			ui_ops->update_progress(xfer,
				purple_xfer_get_progress(xfer));
	}

	if (purple_xfer_is_completed(xfer))
		purple_xfer_end(xfer);
}
示例#30
0
static void _qq_process_recv_file_data(PurpleConnection *gc, guint8 *data, gint len)
{
	gint bytes ;
	qq_file_header fh;
	guint16 packet_type;
	guint16 packet_seq;
	guint8 sub_type;
	guint32 fragment_index;
	guint16 fragment_len;
	guint32 fragment_offset;
	qq_data *qd = (qq_data *) gc->proto_data;
	ft_info *info = (ft_info *) qd->xfer->data;

	bytes = 0;
	bytes += _qq_get_file_header(&fh, data + bytes);

	bytes += 1; /* skip an unknown byte */
	bytes += qq_get16(&packet_type, data + bytes);
	switch(packet_type)
	{
		case QQ_FILE_CMD_FILE_OP:
			bytes += qq_get16(&packet_seq, data + bytes);
			bytes += qq_get8(&sub_type, data + bytes);
			switch (sub_type)
			{
				case QQ_FILE_BASIC_INFO:
					bytes += 4;	/* file length, we have already known it from xfer */
					bytes += qq_get32(&info->fragment_num, data + bytes);
					bytes += qq_get32(&info->fragment_len, data + bytes);

					/* FIXME: We must check the md5 here,
					 * if md5 doesn't match we will ignore
					 * the packet or send sth as error number */

					info->max_fragment_index = 0;
					info->window = 0;
					purple_debug_info("QQ",
							"start receiving data, %d fragments with %d length each\n",
							info->fragment_num, info->fragment_len);
					_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP_ACK, sub_type,
							0, 0, NULL, 0);
					break;
				case QQ_FILE_DATA_INFO:
					bytes += qq_get32(&fragment_index, data + bytes);
					bytes += qq_get32(&fragment_offset, data + bytes);
					bytes += qq_get16(&fragment_len, data + bytes);
					purple_debug_info("QQ",
							"received %dth fragment with length %d, offset %d\n",
							fragment_index, fragment_len, fragment_offset);

					_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP_ACK, sub_type,
							fragment_index, packet_seq, NULL, 0);
					_qq_recv_file_progess(gc, data + bytes, fragment_len, fragment_index, fragment_offset);
					break;
				case QQ_FILE_EOF:
					purple_debug_info("QQ", "end of receiving\n");
					_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP_ACK, sub_type,
							0, 0, NULL, 0);
					break;
			}
			break;
		case QQ_FILE_CMD_FILE_OP_ACK:
			bytes += qq_get16(&packet_seq, data + bytes);
			bytes += qq_get8(&sub_type, data + bytes);
			switch (sub_type)
			{
				case QQ_FILE_BASIC_INFO:
					info->max_fragment_index = 0;
					info->window = 0;
					/* It is ready to send file data */
					_qq_send_file_progess(gc);
					break;
				case QQ_FILE_DATA_INFO:
					bytes += qq_get32(&fragment_index, data + bytes);
					_qq_update_send_progess(gc, fragment_index);
					if (purple_xfer_is_completed(qd->xfer))
						_qq_send_file_data_packet(gc, QQ_FILE_CMD_FILE_OP, QQ_FILE_EOF, 0, 0, NULL, 0);
					/*	else
						_qq_send_file_progess(gc); */
					break;
				case QQ_FILE_EOF:
					/* FIXME: OK, we can end the connection successfully */

					_qq_send_file_data_packet(gc, QQ_FILE_EOF, 0, 0, 0, NULL, 0);
					purple_xfer_set_completed(qd->xfer, TRUE);
					break;
			}
			break;
		case QQ_FILE_EOF:
			_qq_send_file_data_packet(gc, QQ_FILE_EOF, 0, 0, 0, NULL, 0);
			purple_xfer_set_completed(qd->xfer, TRUE);
			purple_xfer_end(qd->xfer);
			break;
		case QQ_FILE_BASIC_INFO:
			purple_debug_info("QQ", "here\n");
			_qq_send_file_data_packet(gc, QQ_FILE_DATA_INFO, 0, 0, 0, NULL, 0);
			break;
		default:
			purple_debug_info("QQ", "_qq_process_recv_file_data: unknown packet type [%d]\n",
					packet_type);
			break;
	}
}