Beispiel #1
0
void
purple_xfer_cancel_local(PurpleXfer *xfer)
{
	PurpleXferUiOps *ui_ops;
	char *msg = NULL;

	g_return_if_fail(xfer != NULL);

	purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_LOCAL);
	xfer->end_time = time(NULL);

	if (purple_xfer_get_filename(xfer) != NULL)
	{
		msg = g_strdup_printf(_("You cancelled the transfer of %s"),
							  purple_xfer_get_filename(xfer));
	}
	else
	{
		msg = g_strdup(_("File transfer cancelled"));
	}
	purple_xfer_conversation_write(xfer, msg, FALSE);
	g_free(msg);

	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
	{
		if (xfer->ops.cancel_send != NULL)
			xfer->ops.cancel_send(xfer);
	}
	else
	{
		if (xfer->ops.cancel_recv != NULL)
			xfer->ops.cancel_recv(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;
	}

	ui_ops = purple_xfer_get_ui_ops(xfer);

	if (ui_ops != NULL && ui_ops->cancel_local != NULL)
		ui_ops->cancel_local(xfer);

	xfer->bytes_remaining = 0;

	purple_xfer_unref(xfer);
}
Beispiel #2
0
static void
purple_xfer_ask_recv(PurpleXfer *xfer)
{
	char *buf, *size_buf;
	size_t size;
	gconstpointer thumb;
	gsize thumb_size;

	/* If we have already accepted the request, ask the destination file
	   name directly */
	if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_ACCEPTED) {
		PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who);

		if (purple_xfer_get_filename(xfer) != NULL)
		{
			size = purple_xfer_get_size(xfer);
			size_buf = purple_str_size_to_units(size);
			buf = g_strdup_printf(_("%s wants to send you %s (%s)"),
						  buddy ? purple_buddy_get_alias(buddy) : xfer->who,
						  purple_xfer_get_filename(xfer), size_buf);
			g_free(size_buf);
		}
		else
		{
			buf = g_strdup_printf(_("%s wants to send you a file"),
						buddy ? purple_buddy_get_alias(buddy) : xfer->who);
		}

		if (xfer->message != NULL)
			serv_got_im(purple_account_get_connection(xfer->account),
								 xfer->who, xfer->message, 0, time(NULL));

		if ((thumb = purple_xfer_get_thumbnail(xfer, &thumb_size))) {
			purple_request_accept_cancel_with_icon(xfer, NULL, buf, NULL,
				PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL,
				thumb, thumb_size, xfer,
				G_CALLBACK(purple_xfer_choose_file),
				G_CALLBACK(cancel_recv_cb));
		} else {
			purple_request_accept_cancel(xfer, NULL, buf, NULL,
				PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL,
				xfer, G_CALLBACK(purple_xfer_choose_file),
				G_CALLBACK(cancel_recv_cb));
		}
			
		g_free(buf);
	} else
		purple_xfer_choose_file(xfer);
}
Beispiel #3
0
void
purple_pn_xfer_invite(PurpleXfer *xfer)
{
    struct pn_peer_link *link;
    struct pn_peer_call *call;
    char *context;
    const char *fn;
    const char *fp;

    fn = purple_xfer_get_filename(xfer);
    fp = purple_xfer_get_local_filename(xfer);

    link = xfer->data;
    call = pn_peer_call_new(link);

    call->init_cb = send_file_cb;
    call->end_cb = xfer_end_cb;
    call->progress_cb = xfer_progress_cb;
    call->cb = xfer_completed_cb;
    call->xfer = xfer;
    purple_xfer_ref(call->xfer);

    call->pending = TRUE;

    purple_xfer_set_cancel_send_fnc(xfer, xfer_cancel);

    xfer->data = call;

    context = gen_context(fn, fp);

    pn_sip_send_invite(call, "5D3E02AB-6190-11D3-BBBB-00C04F795683", 2,
                       context);

    g_free(context);
}
Beispiel #4
0
static void tgprpl_xfer_send_init (PurpleXfer *X) {
  struct tgp_xfer_send_data *data = X->data;
  
  purple_xfer_start (X, -1, NULL, 0);
  
  const char *file = purple_xfer_get_filename (X);
  const char *localfile = purple_xfer_get_local_filename (X);
  const char *who = purple_xfer_get_remote_user (X);
  debug ("xfer_on_init (file=%s, local=%s, who=%s)", file, localfile, who);
  
  tgl_peer_t *P = find_peer_by_name (data->conn->TLS, who);
  if (P) {
    if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) {
      tgl_do_send_document (data->conn->TLS, P->id, (char*) localfile, NULL,
                            0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, tgprpl_xfer_on_finished, data);
    }
    else {
      purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, "Not supported",
                             "Sorry, sending documents to encrypted chats not yet supported.",
                             NULL, NULL, NULL);
    }
  }
  
  data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X);
}
Beispiel #5
0
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;
}
Beispiel #6
0
static void
ft_outgoing_init(PurpleXfer *xfer)
{
	sipe_core_ft_outgoing_init(PURPLE_XFER_TO_SIPE_FILE_TRANSFER,
				   purple_xfer_get_filename(xfer),
				   purple_xfer_get_size(xfer),
				   xfer->who);
}
Beispiel #7
0
void
purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed)
{
	PurpleXferUiOps *ui_ops;

	g_return_if_fail(xfer != NULL);

	if (completed == TRUE) {
		char *msg = NULL;
		PurpleConversation *conv;

		purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_DONE);

		if (purple_xfer_get_filename(xfer) != NULL)
		{
			char *filename = g_markup_escape_text(purple_xfer_get_filename(xfer), -1);
			if (purple_xfer_get_local_filename(xfer)
			 && purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE)
			{
				char *local = g_markup_escape_text(purple_xfer_get_local_filename(xfer), -1);
				msg = g_strdup_printf(_("Transfer of file <A HREF=\"file://%s\">%s</A> complete"),
				                      local, filename);
				g_free(local);
			}
			else
				msg = g_strdup_printf(_("Transfer of file %s complete"),
				                      filename);
			g_free(filename);
		}
		else
			msg = g_strdup(_("File transfer complete"));

		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who,
		                                             purple_xfer_get_account(xfer));

		if (conv != NULL)
			purple_conversation_write(conv, NULL, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
		g_free(msg);
	}

	ui_ops = purple_xfer_get_ui_ops(xfer);

	if (ui_ops != NULL && ui_ops->update_progress != NULL)
		ui_ops->update_progress(xfer, purple_xfer_get_progress(xfer));
}
std::string FiletransferRepeater::requestFT() {
// 	purple_xfer_request_accepted(xfer, std::string(filename).c_str());
	std::string filename(purple_xfer_get_filename(m_xfer));
	m_sid = m_main->ft->requestFT(m_to, filename, purple_xfer_get_size(m_xfer), EmptyString, EmptyString, EmptyString, EmptyString, SIProfileFT::FTTypeAll, m_from);
	m_main->ftManager->m_info[m_sid].filename = filename;
	m_main->ftManager->m_info[m_sid].size = purple_xfer_get_size(m_xfer);
	m_main->ftManager->m_info[m_sid].straight = true;
	return m_sid;
}
Beispiel #9
0
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);
	}
}
Beispiel #10
0
static int
purple_xfer_choose_file(PurpleXfer *xfer)
{
	purple_request_file(xfer, NULL, purple_xfer_get_filename(xfer),
					  (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE),
					  G_CALLBACK(purple_xfer_choose_file_ok_cb),
					  G_CALLBACK(purple_xfer_choose_file_cancel_cb),
					  purple_xfer_get_account(xfer), xfer->who, NULL,
					  xfer);

	return 0;
}
Beispiel #11
0
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);
}
Beispiel #12
0
static void ggp_edisc_xfer_send_init(PurpleXfer *xfer)
{
	ggp_edisc_xfer *edisc_xfer = purple_xfer_get_protocol_data(xfer);

	purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_NOT_STARTED);

	edisc_xfer->filename = g_strdup(purple_xfer_get_filename(xfer));
	g_strcanon(edisc_xfer->filename, GGP_EDISC_FNAME_ALLOWED, '_');

	ggp_ggdrive_auth(edisc_xfer->gc, ggp_edisc_xfer_send_init_authenticated,
		xfer);
}
Beispiel #13
0
void waprpl_xfer_init(PurpleXfer * xfer)
{
	purple_debug_info(WHATSAPP_ID, "File xfer init...\n");
	wa_file_upload *xinfo = (wa_file_upload *) xfer->data;
	whatsapp_connection *wconn = xinfo->wconn;

	size_t fs = purple_xfer_get_size(xfer);
	const char *fn = purple_xfer_get_filename(xfer);
	const char *fp = purple_xfer_get_local_filename(xfer);

	wa_file_upload *xfer_info = (wa_file_upload *) xfer->data;
	purple_xfer_set_size(xfer, fs);

	xfer_info->ref_id = waAPI_sendimage(wconn->waAPI, xinfo->to, 100, 100, fs, fp);
	purple_debug_info(WHATSAPP_ID, "Transfer file %s at %s with size %zu (given ref %d)\n", fn, fp, fs, xfer_info->ref_id);

	waprpl_check_output(xinfo->gc);
}
Beispiel #14
0
static void tgprpl_xfer_send_init (PurpleXfer *X) {
  struct tgp_xfer_send_data *data = X->data;
  
  purple_xfer_start (X, -1, NULL, 0);
  
  const char *file = purple_xfer_get_filename (X);
  const char *localfile = purple_xfer_get_local_filename (X);
  const char *who = purple_xfer_get_remote_user (X);
  debug ("xfer_on_init (file=%s, local=%s, who=%s)", file, localfile, who);
  
  tgl_peer_t *P = find_peer_by_name (data->conn->TLS, who);
  if (P) {
      tgl_do_send_document (data->conn->TLS, P->id, (char*) localfile, NULL,
                            0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, tgprpl_xfer_on_finished, data);
  }
  
  data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X);
}
Beispiel #15
0
void
finch_xfer_dialog_add_xfer(PurpleXfer *xfer)
{
	PurpleGntXferUiData *data;
	PurpleXferType type;
	char *size_str, *remaining_str;
	char *lfilename, *utf8;

	g_return_if_fail(xfer_dialog != NULL);
	g_return_if_fail(xfer != NULL);

	purple_xfer_ref(xfer);

	data = FINCHXFER(xfer);
	data->in_list = TRUE;

	finch_xfer_dialog_show();

	data->last_updated_time = 0;

	type = purple_xfer_get_type(xfer);

	size_str      = purple_str_size_to_units(purple_xfer_get_size(xfer));
	remaining_str = purple_str_size_to_units(purple_xfer_get_bytes_remaining(xfer));

	lfilename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
	utf8 = g_filename_to_utf8(lfilename, -1, NULL, NULL, NULL);
	g_free(lfilename);
	lfilename = utf8;
	gnt_tree_add_row_last(GNT_TREE(xfer_dialog->tree), xfer,
		gnt_tree_create_row(GNT_TREE(xfer_dialog->tree),
			"0.0", (type == PURPLE_XFER_RECEIVE) ? purple_xfer_get_filename(xfer) : lfilename,
			size_str, "0.0", "",_("Waiting for transfer to begin")), NULL);
	g_free(lfilename);

	g_free(size_str);
	g_free(remaining_str);

	xfer_dialog->num_transfers++;

	update_title_progress();
}
Beispiel #16
0
void
msn_request_ft(PurpleXfer *xfer)
{
	MsnSlpCall *slpcall;
	MsnSlpLink *slplink;
	char *context;
	const char *fn;
	const char *fp;

	fn = purple_xfer_get_filename(xfer);
	fp = purple_xfer_get_local_filename(xfer);

	slplink = purple_xfer_get_protocol_data(xfer);

	g_return_if_fail(slplink != NULL);
	g_return_if_fail(fp != NULL);

	slpcall = msn_slpcall_new(slplink);
	msn_slpcall_init(slpcall, MSN_SLPCALL_DC);

	slpcall->session_init_cb = send_file_cb;
	slpcall->end_cb = msn_xfer_end_cb;
	slpcall->cb = msn_xfer_completed_cb;
	slpcall->xfer = xfer;
	g_object_ref(slpcall->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);

	purple_xfer_set_protocol_data(xfer, slpcall);

	context = gen_context(xfer, fn, fp);

	msn_slpcall_invite(slpcall, MSN_FT_GUID, P2P_APPID_FILE, context);
	msn_slplink_unref(slplink);

	g_free(context);
}
Beispiel #17
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;
}
Beispiel #18
0
void
msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer)
{
	MsnSlpCall *slpcall;
	char *context;
	const char *fn;
	const char *fp;

	fn = purple_xfer_get_filename(xfer);
	fp = purple_xfer_get_local_filename(xfer);

	g_return_if_fail(slplink != NULL);
	g_return_if_fail(fp != NULL);

	slpcall = msn_slp_call_new(slplink);
	msn_slp_call_init(slpcall, MSN_SLPCALL_DC);

	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);

	slpcall->pending = TRUE;

	purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel);

	xfer->data = slpcall;

	context = gen_context(fn, fp);

	msn_slp_call_invite(slpcall, "5D3E02AB-6190-11D3-BBBB-00C04F795683", 2,
						context);

	g_free(context);
}
Beispiel #19
0
static void ggp_edisc_xfer_recv_start(PurpleXfer *xfer)
{
	ggp_edisc_session_data *sdata;
	ggp_edisc_xfer *edisc_xfer;
	gchar *upload_url;
	PurpleHttpRequest *req;

	g_return_if_fail(xfer != NULL);
	edisc_xfer = purple_xfer_get_protocol_data(xfer);
	g_return_if_fail(edisc_xfer != NULL);
	sdata = ggp_edisc_get_sdata(edisc_xfer->gc);
	g_return_if_fail(sdata != NULL);

	upload_url = g_strdup_printf("https://drive.mpa.gg.pl/me/file/inbox/"
		"%s,%s?api_version=%s&security_token=%s",
		edisc_xfer->ticket_id, purple_url_encode(purple_xfer_get_filename(xfer)),
		GGP_EDISC_API, sdata->security_token);
	req = purple_http_request_new(upload_url);
	g_free(upload_url);

	purple_http_request_set_timeout(req, -1);

	ggp_edisc_set_defaults(req);
	purple_http_request_set_max_len(req, purple_xfer_get_size(xfer) + 1);
	purple_http_request_set_cookie_jar(req, sdata->cookies);

	purple_http_request_set_response_writer(req, ggp_edisc_xfer_recv_writer,
		xfer);

	edisc_xfer->hc = purple_http_request(edisc_xfer->gc, req,
		ggp_edisc_xfer_recv_done, xfer);
	purple_http_request_unref(req);

	purple_http_conn_set_progress_watcher(edisc_xfer->hc,
		ggp_edisc_xfer_progress_watcher, xfer, 250000);
}
Beispiel #20
0
void
purple_xfer_cancel_remote(PurpleXfer *xfer)
{
	PurpleXferUiOps *ui_ops;
	gchar *msg;
	PurpleAccount *account;
	PurpleBuddy *buddy;

	g_return_if_fail(xfer != NULL);

	purple_request_close_with_handle(xfer);
	purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_REMOTE);
	xfer->end_time = time(NULL);

	account = purple_xfer_get_account(xfer);
	buddy = purple_find_buddy(account, xfer->who);

	if (purple_xfer_get_filename(xfer) != NULL)
	{
		msg = g_strdup_printf(_("%s cancelled the transfer of %s"),
				buddy ? purple_buddy_get_alias(buddy) : xfer->who, purple_xfer_get_filename(xfer));
	}
	else
	{
		msg = g_strdup_printf(_("%s cancelled the file transfer"),
				buddy ? purple_buddy_get_alias(buddy) : xfer->who);
	}
	purple_xfer_conversation_write(xfer, msg, TRUE);
	purple_xfer_error(purple_xfer_get_type(xfer), account, xfer->who, msg);
	g_free(msg);

	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
	{
		if (xfer->ops.cancel_send != NULL)
			xfer->ops.cancel_send(xfer);
	}
	else
	{
		if (xfer->ops.cancel_recv != NULL)
			xfer->ops.cancel_recv(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;
	}

	ui_ops = purple_xfer_get_ui_ops(xfer);

	if (ui_ops != NULL && ui_ops->cancel_remote != NULL)
		ui_ops->cancel_remote(xfer);

	xfer->bytes_remaining = 0;

	purple_xfer_unref(xfer);
}
Beispiel #21
0
void
pidgin_xfer_dialog_add_xfer(PidginXferDialog *dialog, PurpleXfer *xfer)
{
	PidginXferUiData *data;
	PurpleXferType type;
	GdkPixbuf *pixbuf;
	char *size_str, *remaining_str;
	char *lfilename, *utf8;

	g_return_if_fail(dialog != NULL);
	g_return_if_fail(xfer != NULL);

	purple_xfer_ref(xfer);

	data = PIDGINXFER(xfer);
	data->in_list = TRUE;

	pidgin_xfer_dialog_show(dialog);

	data->last_updated_time = 0;

	type = purple_xfer_get_type(xfer);

	size_str      = purple_str_size_to_units(purple_xfer_get_size(xfer));
	remaining_str = purple_str_size_to_units(purple_xfer_get_bytes_remaining(xfer));

	pixbuf = gtk_widget_render_icon(dialog->window,
									(type == PURPLE_XFER_RECEIVE
									 ? PIDGIN_STOCK_DOWNLOAD
									 : PIDGIN_STOCK_UPLOAD),
									GTK_ICON_SIZE_MENU, NULL);

	gtk_list_store_append(dialog->model, &data->iter);
	lfilename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
	utf8 = g_filename_to_utf8(lfilename, -1, NULL, NULL, NULL);
	g_free(lfilename);
	lfilename = utf8;
	gtk_list_store_set(dialog->model, &data->iter,
					   COLUMN_STATUS, pixbuf,
					   COLUMN_PROGRESS, 0.0,
					   COLUMN_FILENAME, (type == PURPLE_XFER_RECEIVE)
					                     ? purple_xfer_get_filename(xfer)
							     : lfilename,
					   COLUMN_SIZE, size_str,
					   COLUMN_REMAINING, _("Waiting for transfer to begin"),
					   COLUMN_DATA, xfer,
					   -1);
	g_free(lfilename);

	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(dialog->tree));

	g_object_unref(pixbuf);

	g_free(size_str);
	g_free(remaining_str);

	dialog->num_transfers++;

	ensure_row_selected(dialog);
	update_title_progress(dialog);
}
static void
xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
{
	PurpleXmlNode *si_node, *feature, *field, *file, *x;
	XepIq *iq;
	XepXfer *xf = purple_xfer_get_protocol_data(xfer);
	BonjourData *bd = NULL;
	char buf[32];

	if(!xf)
		return;

	bd = xf->data;
	if(!bd)
		return;

	purple_debug_info("bonjour", "xep file transfer stream initialization offer-id=%d.\n", next_id);

	/* Assign stream id. */
	g_free(xf->iq_id);
	xf->iq_id = g_strdup_printf("%u", next_id++);
	iq = xep_iq_new(xf->data, XEP_IQ_SET, to, bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
	if(iq == NULL)
		return;

	/*Construct Stream initialization offer message.*/
	si_node = purple_xmlnode_new_child(iq->node, "si");
	purple_xmlnode_set_namespace(si_node, "http://jabber.org/protocol/si");
	purple_xmlnode_set_attrib(si_node, "profile", "http://jabber.org/protocol/si/profile/file-transfer");
	g_free(xf->sid);
	xf->sid = g_strdup(xf->iq_id);
	purple_xmlnode_set_attrib(si_node, "id", xf->sid);

	file = purple_xmlnode_new_child(si_node, "file");
	purple_xmlnode_set_namespace(file, "http://jabber.org/protocol/si/profile/file-transfer");
	purple_xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
	g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
	purple_xmlnode_set_attrib(file, "size", buf);

	feature = purple_xmlnode_new_child(si_node, "feature");
	purple_xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");

	x = purple_xmlnode_new_child(feature, "x");
	purple_xmlnode_set_namespace(x, "jabber:x:data");
	purple_xmlnode_set_attrib(x, "type", "form");

	field = purple_xmlnode_new_child(x, "field");
	purple_xmlnode_set_attrib(field, "var", "stream-method");
	purple_xmlnode_set_attrib(field, "type", "list-single");

	if (xf->mode & XEP_BYTESTREAMS) {
		PurpleXmlNode *option = purple_xmlnode_new_child(field, "option");
		PurpleXmlNode *value = purple_xmlnode_new_child(option, "value");
		purple_xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);
	}
	if (xf->mode & XEP_IBB) {
		PurpleXmlNode *option = purple_xmlnode_new_child(field, "option");
		PurpleXmlNode *value = purple_xmlnode_new_child(option, "value");
		purple_xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1);
	}

	xep_iq_send_and_free(iq);
}
Beispiel #23
0
static void
got_file_send_progress(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;
	JsonParser *parser;
	JsonNode *node;
	JsonObject *obj;
	
	sa->url_datas = g_slist_remove(sa->url_datas, url_data);
	
	//{"content_length":0,"content_full_length":0,"view_length":0,"content_state":"no content","view_state":"none","view_location":"https://nus1-api.asm.skype.com/v1/objects/0-cus-d1-61121cfae8cf601944627a66afdb77ad/views/original","status_location":"https://nus1-api.asm.skype.com/v1/objects/0-cus-d1-61121cfae8cf601944627a66afdb77ad/views/original/status"}
	parser = json_parser_new();
	if (!json_parser_load_from_data(parser, url_text, len, NULL)) {
		//probably bad
		poll_file_send_progress(swft);
		return;
	}
	node = json_parser_get_root(parser);
	if (node == NULL || json_node_get_node_type(node) != JSON_NODE_OBJECT) {
		//probably bad
		poll_file_send_progress(swft);
		return;
	}
	obj = json_node_get_object(node);
	
	
	if (json_object_has_member(obj, "status_location")) {
		g_free(swft->url);
		swft->url = g_strdup(json_object_get_string_member(obj, "status_location"));
	}
	
	if (json_object_has_member(obj, "content_state") && g_str_equal(json_object_get_string_member(obj, "content_state"), "ready")) {
		xmlnode *uriobject = xmlnode_new("URIObject");
		xmlnode *title = xmlnode_new_child(uriobject, "Title");
		xmlnode *description = xmlnode_new_child(uriobject, "Description");
		xmlnode *anchor = xmlnode_new_child(uriobject, "a");
		xmlnode *originalname = xmlnode_new_child(uriobject, "OriginalName");
		xmlnode *filesize = xmlnode_new_child(uriobject, "FileSize");
		gchar *message, *temp;
		//We finally did it!
		// May the pesants rejoyce
		purple_xfer_set_completed(xfer, TRUE);
		
		// Don't forget to let the other end know about it
		
		xmlnode_set_attrib(uriobject, "type", "File.1");
		temp = g_strconcat("https://" SKYPEWEB_XFER_HOST "/v1/objects/", purple_url_encode(swft->id), NULL);
		xmlnode_set_attrib(uriobject, "uri", temp);
		g_free(temp);
		temp = g_strconcat("https://" SKYPEWEB_XFER_HOST "/v1/objects/", purple_url_encode(swft->id), "/views/thumbnail", NULL);
		xmlnode_set_attrib(uriobject, "url_thumbnail", temp);
		g_free(temp);
		xmlnode_insert_data(title, purple_xfer_get_filename(xfer), -1);
		xmlnode_insert_data(description, "Description: ", -1);
		temp = g_strconcat("https://login.skype.com/login/sso?go=webclient.xmm&docid=", purple_url_encode(swft->id), NULL);
		xmlnode_set_attrib(anchor, "href", temp);
		xmlnode_insert_data(anchor, temp, -1);
		g_free(temp);
		xmlnode_set_attrib(originalname, "v", purple_xfer_get_filename(xfer));
		temp = g_strdup_printf("%d", purple_xfer_get_size(xfer));
		xmlnode_set_attrib(filesize, "v", temp);
		g_free(temp);
		
		message = xmlnode_to_str(uriobject, NULL);
		skypeweb_send_im(sa->pc, swft->from, message, PURPLE_MESSAGE_SEND);
		g_free(message);
		
		skypeweb_free_xfer(xfer);
		purple_xfer_unref(xfer);
		
		xmlnode_free(uriobject);
		g_object_unref(parser);
		return;
	}
	
	
	g_object_unref(parser);
	
	// probably good
	poll_file_send_progress(swft);
}
std::string FiletransferRepeater::requestFT() {
	std::string filename(m_xfer ? purple_xfer_get_filename(m_xfer) : "");
	m_sid = Transport::instance()->requestFT(m_to, filename, purple_xfer_get_size(m_xfer), EmptyString, EmptyString, EmptyString, EmptyString, SIProfileFT::FTTypeAll, m_from);
	return m_sid;
}
Beispiel #25
0
static void
update_detailed_info(PidginXferDialog *dialog, PurpleXfer *xfer)
{
	PidginXferUiData *data;
	char *kbsec, *time_elapsed, *time_remaining;
	char *status, *utf8;

	if (dialog == NULL || xfer == NULL)
		return;

	data = PIDGINXFER(xfer);

	get_xfer_info_strings(xfer, &kbsec, &time_elapsed, &time_remaining);

	status = g_strdup_printf("%d%% (%" G_GSIZE_FORMAT " of %" G_GSIZE_FORMAT " bytes)",
							 (int)(purple_xfer_get_progress(xfer)*100),
							 purple_xfer_get_bytes_sent(xfer),
							 purple_xfer_get_size(xfer));

	if (purple_xfer_is_completed(xfer)) {

		GdkPixbuf *pixbuf = NULL;

		pixbuf = gtk_widget_render_icon(xfer_dialog->window,
										PIDGIN_STOCK_FILE_DONE,
										GTK_ICON_SIZE_MENU, NULL);

		gtk_list_store_set(GTK_LIST_STORE(xfer_dialog->model), &data->iter,
						   COLUMN_STATUS, pixbuf,
						   -1);

		g_object_unref(pixbuf);
	}

	if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
		gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label),
							 _("<b>Receiving As:</b>"));
		gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label),
							 _("<b>Receiving From:</b>"));
	}
	else {
		gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label),
							 _("<b>Sending To:</b>"));
		gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label),
							 _("<b>Sending As:</b>"));
	}

	gtk_label_set_text(GTK_LABEL(dialog->local_user_label),
								 purple_account_get_username(xfer->account));
	gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), xfer->who);
	gtk_label_set_text(GTK_LABEL(dialog->protocol_label),
								 purple_account_get_protocol_name(xfer->account));

	if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
		gtk_label_set_text(GTK_LABEL(dialog->filename_label),
					   purple_xfer_get_filename(xfer));
	} else {
		char *tmp;

		tmp = g_path_get_basename(purple_xfer_get_local_filename(xfer));
		utf8 = g_filename_to_utf8(tmp, -1, NULL, NULL, NULL);
		g_free(tmp);

		gtk_label_set_text(GTK_LABEL(dialog->filename_label), utf8);
		g_free(utf8);
	}

	utf8 = g_filename_to_utf8((purple_xfer_get_local_filename(xfer)), -1, NULL, NULL, NULL);
	gtk_label_set_text(GTK_LABEL(dialog->localfile_label), utf8);
	g_free(utf8);

	gtk_label_set_text(GTK_LABEL(dialog->status_label), status);

	gtk_label_set_text(GTK_LABEL(dialog->speed_label), kbsec);
	gtk_label_set_text(GTK_LABEL(dialog->time_elapsed_label), time_elapsed);
	gtk_label_set_text(GTK_LABEL(dialog->time_remaining_label),
					   time_remaining);

	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress),
								  purple_xfer_get_progress(xfer));

	g_free(kbsec);
	g_free(time_elapsed);
	g_free(time_remaining);
	g_free(status);
}
Beispiel #26
0
/* send a file to udp channel with QQ_FILE_DATA_PACKET_TAG */
static void _qq_send_file_data_packet(PurpleConnection *gc, guint16 packet_type, guint8 sub_type,
		guint32 fragment_index, guint16 seq, guint8 *data, gint len)
{
	guint8 *raw_data, filename_md5[QQ_KEY_LENGTH], file_md5[QQ_KEY_LENGTH];
	gint bytes;
	guint32 fragment_size = 1000;
	const char *filename;
	gint filename_len, filesize;
	qq_data *qd;
	ft_info *info;

	qd = (qq_data *) gc->proto_data;
	info = (ft_info *) qd->xfer->data;

	filename = purple_xfer_get_filename(qd->xfer);
	filesize = purple_xfer_get_size(qd->xfer);

	raw_data = g_newa(guint8, MAX_PACKET_SIZE);
	bytes = 0;

	bytes += qq_put8(raw_data + bytes, 0x00);
	bytes += qq_put16(raw_data + bytes, packet_type);
	switch (packet_type) {
		case QQ_FILE_BASIC_INFO:
		case QQ_FILE_DATA_INFO:
		case QQ_FILE_EOF:
			bytes += qq_put16(raw_data + bytes, 0x0000);
			bytes += qq_put8(raw_data + bytes, 0x00);
			break;
		case QQ_FILE_CMD_FILE_OP:
			switch(sub_type)
			{
				case QQ_FILE_BASIC_INFO:
					filename_len = strlen(filename);
					qq_get_md5(filename_md5, sizeof(filename_md5), (guint8 *)filename, filename_len);
					_fill_file_md5(purple_xfer_get_local_filename(qd->xfer),
							purple_xfer_get_size(qd->xfer),
							file_md5);

					info->fragment_num = (filesize - 1) / QQ_FILE_FRAGMENT_MAXLEN + 1;
					info->fragment_len = QQ_FILE_FRAGMENT_MAXLEN;

					purple_debug_info("QQ",
							"start transfering data, %d fragments with %d length each\n",
							info->fragment_num, info->fragment_len);
					/* Unknown */
					bytes += qq_put16(raw_data  + bytes, 0x0000);
					/* Sub-operation type */
					bytes += qq_put8(raw_data + bytes, sub_type);
					/* Length of file */
					bytes += qq_put32(raw_data + bytes, filesize);
					/* Number of fragments */
					bytes += qq_put32(raw_data + bytes, info->fragment_num);
					/* Length of a single fragment */
					bytes += qq_put32(raw_data + bytes, info->fragment_len);
					bytes += qq_putdata(raw_data + bytes, file_md5, 16);
					bytes += qq_putdata(raw_data + bytes, filename_md5, 16);
					/* Length of filename */
					bytes += qq_put16(raw_data + bytes, filename_len);
					/* 8 unknown bytes */
					bytes += qq_put32(raw_data + bytes, 0x00000000);
					bytes += qq_put32(raw_data + bytes, 0x00000000);
					/* filename */
					bytes += qq_putdata(raw_data + bytes, (guint8 *) filename,
							filename_len);
					break;
				case QQ_FILE_DATA_INFO:
					purple_debug_info("QQ",
							"sending %dth fragment with length %d, offset %d\n",
							fragment_index, len, (fragment_index-1)*fragment_size);
					/* bytes += qq_put16(raw_data + bytes, ++(qd->send_seq)); */
					bytes += qq_put16(raw_data + bytes, info->send_seq);
					bytes += qq_put8(raw_data + bytes, sub_type);
					/* bytes += qq_put32(raw_data + bytes, fragment_index); */
					bytes += qq_put32(raw_data + bytes, fragment_index - 1);
					bytes += qq_put32(raw_data + bytes, (fragment_index - 1) * fragment_size);
					bytes += qq_put16(raw_data + bytes, len);
					bytes += qq_putdata(raw_data + bytes, data, len);
					break;
				case QQ_FILE_EOF:
					purple_debug_info("QQ", "end of sending data\n");
					/* bytes += qq_put16(raw_data + bytes, info->fragment_num + 1); */
					bytes += qq_put16(raw_data + bytes, info->fragment_num);
					bytes += qq_put8(raw_data + bytes, sub_type);
					/* purple_xfer_set_completed(qd->xfer, TRUE); */
			}
			break;
		case QQ_FILE_CMD_FILE_OP_ACK:
			switch (sub_type)
			{
				case QQ_FILE_BASIC_INFO:
					bytes += qq_put16(raw_data + bytes, 0x0000);
					bytes += qq_put8(raw_data + bytes, sub_type);
					bytes += qq_put32(raw_data + bytes, 0x00000000);
					break;
				case QQ_FILE_DATA_INFO:
					bytes += qq_put16(raw_data + bytes, seq);
					bytes += qq_put8(raw_data + bytes, sub_type);
					bytes += qq_put32(raw_data + bytes, fragment_index);
					break;
				case QQ_FILE_EOF:
					bytes += qq_put16(raw_data + bytes, filesize / QQ_FILE_FRAGMENT_MAXLEN + 2);
					bytes += qq_put8(raw_data + bytes, sub_type);
					break;
			}
	}
	purple_debug_info("QQ", "<== send %s packet\n", qq_get_file_cmd_desc(packet_type));
	_qq_send_file(gc, raw_data, bytes, QQ_FILE_DATA_PACKET_TAG, info->to_uid);
}
void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *pkt)
{
	char *url = NULL;
	long val_249 = 0;
	long val_66 = 0;
	PurpleXfer *xfer;
	YahooData *yd;
	struct yahoo_xfer_data *xfer_data;
	char *xfer_peer_idstring = NULL;
	char *xfer_idstring_for_relay = NULL;
	GSList *l;
	struct yahoo_packet *pkt_to_send;

	yd = purple_connection_get_protocol_data(gc);

	for (l = pkt->hash; l; l = l->next) {
		struct yahoo_pair *pair = l->data;

		switch (pair->key) {
		case 4: /* from */
			break;
		case 5: /* to */
			break;
		case 265:
			if (g_utf8_validate(pair->value, -1, NULL)) {
				xfer_peer_idstring = pair->value;
			} else {
				purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
						"got non-UTF-8 string for key %d\n", pair->key);
			}
			break;
		case 27: /* filename */
			break;
		case 66:
			val_66 = strtol(pair->value, NULL, 10);
			break;
		case 249:
			val_249 = strtol(pair->value, NULL, 10);
			/* 249 has value 1 or 2 when doing p2p transfer and value 3 when relaying through yahoo server */
			break;
		case 250:
			if (g_utf8_validate(pair->value, -1, NULL)) {
				url = pair->value; /* TODO: rename to host? what about non-relay? */
			} else {
				purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
						"got non-UTF-8 string for key %d\n", pair->key);
			}
			break;
		case 251:
			if (g_utf8_validate(pair->value, -1, NULL)) {
				xfer_idstring_for_relay = pair->value;
			} else {
				purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
						"got non-UTF-8 string for key %d\n", pair->key);
			}
			break;
		}
	}

	if(!xfer_peer_idstring)
		return;

	xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map, xfer_peer_idstring);

	if(!xfer) return;

	if(val_66==-1)
	{
		purple_xfer_cancel_remote(xfer);
		return;
	}

	xfer_data = purple_xfer_get_protocol_data(xfer);

	xfer_data->info_val_249 = val_249;
	xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
	if(val_249 == 1 || val_249 == 3) {
		PurpleHttpRequest *req;
		PurpleAccount *account;

		xfer_data->is_relay = (val_249 == 3);

		if (!xfer_data->is_relay) {
			purple_debug_error("yahoo", "Non-relay FT aren't tested yet.\n");
			purple_notify_error(gc, NULL, _("File Transfer Failed"),
				_("Unsupported method"),
				purple_request_cpar_from_connection(gc));
			purple_xfer_cancel_remote(xfer);
		}

		account = purple_connection_get_account(xfer_data->gc);

		xfer_data->url = yahoo_ft_url_gen(xfer, url);

		pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
			YAHOO_STATUS_AVAILABLE, yd->session_id);
		yahoo_packet_hash(pkt_to_send, "ssssis",
			1, purple_normalize(account, purple_account_get_username(account)),
			5, purple_xfer_get_remote_user(xfer),
			265, xfer_data->xfer_peer_idstring,
			27, purple_xfer_get_filename(xfer),
			249, xfer_data->info_val_249,
			251, xfer_data->xfer_idstring_for_relay);

		yahoo_packet_send_and_free(pkt_to_send, yd);

		req = yahoo_ft_new_req(xfer_data);
		purple_http_request_set_method(req, "HEAD");
		xfer_data->hc = purple_http_request(gc, req, yahoo_process_filetrans_info_15_got, xfer);
		purple_http_request_unref(req);
	}
	else if (val_249 == 2)
		purple_debug_error("yahoo", "p2p file transfers are not supported yet\n");
}
Beispiel #28
0
void* IMInvoker::purpeNotifyMessage(PurpleNotifyMsgType type, const char *title, const char *primary, const char *secondary, PurpleRequestCommonParameters *cpar) {
#else
void* IMInvoker::purpeNotifyMessage(PurpleNotifyMsgType type, const char *title, const char *primary, const char *secondary) {
#endif
	return NULL;
}
void* IMInvoker::purpeNotifyEmail(PurpleConnection *gc, const char *subject, const char *from, const char *to, const char *url) {
	return NULL;
}
void* IMInvoker::purpeNotifyEmails(PurpleConnection *gc, size_t count, gboolean detailed, const char **subjects, const char **froms, const char **tos, const char **urls) {
	return NULL;
}
void* IMInvoker::purpeNotifyFormatted(const char *title, const char *primary, const char *secondary, const char *text) {
	return NULL;
}
void* IMInvoker::purpeNotifySearchResults(PurpleConnection *gc, const char *title, const char *primary, const char *secondary, PurpleNotifySearchResults *results, gpointer user_data) {
	return NULL;
}
void IMInvoker::purpeNotifySearchResultsNewRows(PurpleConnection *gc, PurpleNotifySearchResults *results, void *data) {}
void* IMInvoker::purpeNotifyUserInfo(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) {
	return NULL;
}
void* IMInvoker::purpeNotifyURI(const char *uri) {
	return NULL;
}
void IMInvoker::purpeNotifyClose(PurpleNotifyType type, void *ui_handle) {}

// privacy ui operations
void IMInvoker::purplePermitAdded(PurpleAccount *account, const char *name) {}
void IMInvoker::purplePermitRemoved(PurpleAccount *account, const char *name) {}
void IMInvoker::purpleDebyAdded(PurpleAccount *account, const char *name) {}
void IMInvoker::purpleDenyRemoved(PurpleAccount *account, const char *name) {}


// request ui operations
#if LIBPURPLE_VERSION_MAJOR >= 3

void* IMInvoker::purpleRequestInput(const char *title, const char *primary,
                                    const char *secondary, const char *default_value,
                                    gboolean multiline, gboolean masked, gchar *hint,
                                    const char *ok_text, GCallback ok_cb,
                                    const char *cancel_text, GCallback cancel_cb,
                                    PurpleRequestCommonParameters *cpar, void *user_data) {
	return NULL;
}
void* IMInvoker::purpleRequestChoice(const char *title, const char *primary,
                                     const char *secondary, gpointer default_value,
                                     const char *ok_text, GCallback ok_cb, const char *cancel_text,
                                     GCallback cancel_cb , PurpleRequestCommonParameters *cpar,
                                     void *user_data, va_list choices) {
	return NULL;
}
void* IMInvoker::purpleRequestAction(const char *title, const char *primary,
                                     const char *secondary, int default_action,
                                     PurpleRequestCommonParameters *cpar, void *user_data,
                                     size_t action_count, va_list actions) {
	return NULL;
}

void* IMInvoker::purpleRequestWait(const char *title, const char *primary,
                                   const char *secondary, gboolean with_progress,
                                   PurpleRequestCancelCb cancel_cb,
                                   PurpleRequestCommonParameters *cpar, void *user_data) {
	return NULL;
}

void IMInvoker::purpleRequestWaitUpdate(void *ui_handle, gboolean pulse, gfloat fraction) {
}

void* IMInvoker::purpleRequestFields(const char *title, const char *primary,
                                     const char *secondary, PurpleRequestFields *fields,
                                     const char *ok_text, GCallback ok_cb,
                                     const char *cancel_text, GCallback cancel_cb,
                                     PurpleRequestCommonParameters *cpar, void *user_data) {
	return NULL;
}
void* IMInvoker::purpleRequestFile(const char *title, const char *filename,
                                   gboolean savedialog, GCallback ok_cb, GCallback cancel_cb,
                                   PurpleRequestCommonParameters *cpar, void *user_data) {
	// click ok
	PurpleXfer *xfer = (PurpleXfer *)user_data;
	PurpleXferType xferType = purple_xfer_get_xfer_type(xfer);
	if (xferType == PURPLE_XFER_TYPE_RECEIVE) {
		((PurpleRequestFileCb)ok_cb)(user_data, filename);
	} else if (xferType == PURPLE_XFER_TYPE_SEND) {
		if (purple_xfer_get_local_filename(xfer) != NULL && purple_xfer_get_filename(xfer) != NULL) {
			((PurpleRequestFileCb)ok_cb)(user_data, purple_xfer_get_local_filename(xfer));
		} else {
			((PurpleRequestFileCb)cancel_cb)(user_data, purple_xfer_get_local_filename(xfer));
		}
	}
	return NULL;
}