예제 #1
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 );
	}
}
예제 #2
0
static void
skypeweb_xfer_send_connect_cb(gpointer user_data, PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
{
	SkypeWebFileTransfer *swft = user_data;
	SkypeWebAccount *sa = swft->sa;
	PurpleXfer *xfer = swft->xfer;
	gchar *headers;
	
	headers = g_strdup_printf("PUT /v1/objects/%s/content/original HTTP/1.0\r\n"
			"Connection: close\r\n"
			"Authorization: skype_token %s\r\n" //slightly different to normal!
			"Host: " SKYPEWEB_XFER_HOST "\r\n"
			"Content-Length: %d\r\n"
			"Content-Type: application/json\r\n"
			"\r\n\r\n",
			purple_url_encode(swft->id),
			sa->skype_token, 
			purple_xfer_get_size(xfer));
	
	purple_ssl_write(ssl_connection, headers, strlen(headers));
	
	swft->conn = ssl_connection;
	purple_xfer_ref(xfer);
	purple_xfer_start(xfer, ssl_connection->fd, NULL, 0);
	
	//TODO add input watcher that calls this repeatedly
	purple_xfer_prpl_ready(xfer);
	//purple_ssl_input_add(
			
	g_free(headers);
}
예제 #3
0
파일: filexfer.c 프로젝트: Lilitana/Pidgin
/*------------------------------------------------------------------------
 * 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 );
	}
}
예제 #4
0
static void
send_file_cb(MsnSlpCall *slpcall)
{
	MsnSlpMessage *slpmsg;
	PurpleXfer *xfer;

	xfer = (PurpleXfer *)slpcall->xfer;
	if (purple_xfer_get_status(xfer) >= PURPLE_XFER_STATUS_STARTED)
		return;

	purple_xfer_ref(xfer);
	purple_xfer_start(xfer, -1, NULL, 0);
	if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_STARTED) {
		purple_xfer_unref(xfer);
		return;
	}
	purple_xfer_unref(xfer);

	slpmsg = msn_slpmsg_new(slpcall->slplink);
	slpmsg->slpcall = slpcall;
	slpmsg->flags = 0x1000030;
	slpmsg->info = "SLP FILE";
	slpmsg->size = purple_xfer_get_size(xfer);

	msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);
}
예제 #5
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);
}
예제 #6
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;
}
예제 #7
0
void FiletransferRepeater::registerXfer(PurpleXfer *xfer) {
	m_xfer = xfer;
	purple_xfer_ref(m_xfer);

	if (m_size != -1)
		purple_xfer_set_size(xfer, m_size);

	m_xfer->ui_data = this;
}
예제 #8
0
void
purple_pn_xfer_got_invite(struct pn_peer_call *call,
                          const char *branch,
                          const char *context)
{
    PurpleAccount *account;
    PurpleXfer *xfer;
    char *bin;
    gsize bin_len;
    guint32 file_size;
    char *file_name;
    gunichar2 *uni_name;

    account = msn_session_get_user_data (pn_peer_link_get_session (call->link));

    call->cb = xfer_completed_cb;
    call->end_cb = xfer_end_cb;
    call->progress_cb = xfer_progress_cb;
    call->branch = g_strdup(branch);

    call->pending = TRUE;

    xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
                           pn_peer_link_get_passport (call->link));
    if (xfer)
    {
        bin = (char *)purple_base64_decode(context, &bin_len);
        file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8));

        uni_name = (gunichar2 *)(bin + 20);
        while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
            *uni_name = GUINT16_FROM_LE(*uni_name);
            uni_name++;
        }

        file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1,
                                    NULL, NULL, NULL);

        g_free(bin);

        purple_xfer_set_filename(xfer, file_name);
        purple_xfer_set_size(xfer, file_size);
        purple_xfer_set_init_fnc(xfer, xfer_init);
        purple_xfer_set_request_denied_fnc(xfer, xfer_cancel);
        purple_xfer_set_cancel_recv_fnc(xfer, xfer_cancel);

        call->xfer = xfer;
        purple_xfer_ref(call->xfer);

        xfer->data = call;

        purple_xfer_request(xfer);
    }
}
예제 #9
0
파일: slplink.c 프로젝트: Lilitana/Pidgin
static MsnSlpMessage *
init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
{
	MsnSlpMessage *slpmsg;
	guint32 session_id;

	slpmsg = msn_slpmsg_new(slplink, NULL);
	slpmsg->id = msn_p2p_info_get_id(info);
	session_id = msn_p2p_info_get_session_id(info);
	slpmsg->size = msn_p2p_info_get_total_size(info);
	msn_p2p_info_init_first(slpmsg->p2p_info, info);

	if (session_id)
	{
		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
		if (slpmsg->slpcall != NULL)
		{
			if (msn_p2p_msg_is_data(info))
			{
				PurpleXfer *xfer = slpmsg->slpcall->xfer;
				if (xfer != NULL)
				{
					slpmsg->ft = TRUE;
					slpmsg->slpcall->xfer_msg = slpmsg;

					purple_xfer_ref(xfer);
					purple_xfer_start(xfer,	-1, NULL, 0);

					if (xfer->data == NULL) {
						purple_xfer_unref(xfer);
						msn_slpmsg_destroy(slpmsg);
						g_return_val_if_reached(NULL);
					} else {
						purple_xfer_unref(xfer);
					}
				}
			}
		}
	}
	if (!slpmsg->ft && slpmsg->size)
	{
		slpmsg->buffer = g_try_malloc(slpmsg->size);
		if (slpmsg->buffer == NULL)
		{
			purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
			msn_slpmsg_destroy(slpmsg);
			return NULL;
		}
	}

	return slpmsg;
}
예제 #10
0
static void
skypeweb_xfer_send_init(PurpleXfer *xfer)
{
	PurpleConnection *pc = purple_account_get_connection(purple_xfer_get_account(xfer));
	SkypeWebAccount *sa = purple_connection_get_protocol_data(pc);
	gchar *basename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
	gchar *id, *post, *headers;
	SkypeWebFileTransfer *swft = purple_xfer_get_protocol_data(xfer);
	JsonObject *obj = json_object_new();
	JsonObject *permissions = json_object_new();
	JsonArray *userpermissions = json_array_new();
	
	purple_xfer_set_filename(xfer, basename);
	purple_xfer_ref(xfer);
	
	json_object_set_string_member(obj, "type", "sharing/file");
	json_object_set_string_member(obj, "filename", basename);
	
	if (SKYPEWEB_BUDDY_IS_MSN(swft->from)) {
		id = g_strconcat("1:", swft->from, NULL);
	} else {
		id = g_strconcat("8:", swft->from, NULL);
	}
	json_array_add_string_element(userpermissions, "read");
	json_object_set_array_member(permissions, id, userpermissions);
	json_object_set_object_member(obj, "permissions", permissions);
	
	post = skypeweb_jsonobj_to_string(obj);
	//POST to api.asm.skype.com  /v1/objects
	//{"type":"sharing/file","permissions":{"8:eionrobb":["read"]},"filename":"GiantLobsterMoose.txt"}
	
	headers = g_strdup_printf("POST /v1/objects HTTP/1.0\r\n"
			"Connection: close\r\n"
			"Authorization: skype_token %s\r\n" //slightly different to normal!
			"Host: " SKYPEWEB_XFER_HOST "\r\n"
			"Content-Length: %d\r\n"
			"Content-Type: application/json\r\n"
			"\r\n\r\n%s",
			sa->skype_token, 
			strlen(post), post);
	
	skypeweb_fetch_url_request(sa, "https://" SKYPEWEB_XFER_HOST, TRUE, NULL, FALSE, headers, FALSE, -1, skypeweb_got_object_for_file, swft);
	
	g_free(post);
	json_object_unref(obj);
	g_free(id);
	g_free(basename);
}
예제 #11
0
/*
 * 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);
	}

}
예제 #12
0
static void tgprpl_xfer_recv_init (PurpleXfer *X) {
  debug ("tgprpl_xfer_recv_init(): receiving xfer accepted.");

  struct tgp_xfer_send_data *data = X->data;
  struct tgl_state *TLS = data->conn->TLS;
  struct tgl_message *M = data->msg;
  struct tgl_document *D = M->media.document;
  tgl_peer_t *P = NULL;

  purple_xfer_start (X, -1, NULL, 0);
  const char *who = purple_xfer_get_remote_user (X);
  P = tgp_blist_lookup_peer_get (TLS, who);
  g_return_if_fail(P);

  switch (M->media.type) {
    case tgl_message_media_document:
      tgl_do_load_document (TLS, D, tgprpl_xfer_recv_on_finished, data);
      break;

    case tgl_message_media_document_encr:
      tgl_do_load_encr_document (TLS, M->media.encr_document, tgprpl_xfer_recv_on_finished, data);
      break;

    case tgl_message_media_audio:
      tgl_do_load_audio (TLS, D, tgprpl_xfer_recv_on_finished, data);
      break;

    case tgl_message_media_video:
      tgl_do_load_video (TLS, D, tgprpl_xfer_recv_on_finished, data);
      break;

    default:
      failure ("Unknown message media type: %d, XFER not possible.", M->media.type);
      return;
  }

  // Prevent the xfer data from getting freed after cancelling to allow the file transfer to complete
  // without crashing. This is necessary cause loading the file in libtgl cannot be aborted once started.
  purple_xfer_ref (X);

  data->timer = purple_timeout_add (100, tgprpl_xfer_upload_progress, X);
  data->loading = TRUE;
}
예제 #13
0
파일: gntft.c 프로젝트: CkNoSFeRaTU/pidgin
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();
}
예제 #14
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);
	}
}
예제 #15
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_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;
	purple_xfer_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);

	xfer->data = slpcall;

	context = gen_context(xfer, fn, fp);

	msn_slpcall_invite(slpcall, MSN_FT_GUID, 2, context);

	g_free(context);
}
예제 #16
0
파일: slplink.c 프로젝트: bf4/pidgin-mac
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);
}
예제 #17
0
static void
purple_xfer_choose_file_ok_cb(void *user_data, const char *filename)
{
	PurpleXfer *xfer;
	PurpleXferType type;
	struct stat st;
	gchar *dir;

	xfer = (PurpleXfer *)user_data;
	type = purple_xfer_get_type(xfer);

	if (g_stat(filename, &st) != 0) {
		/* File not found. */
		if (type == PURPLE_XFER_RECEIVE) {
#ifndef _WIN32
			int mode = W_OK;
#else
			int mode = F_OK;
#endif
			dir = g_path_get_dirname(filename);

			if (g_access(dir, mode) == 0) {
				purple_xfer_request_accepted(xfer, filename);
			} else {
				purple_xfer_ref(xfer);
				purple_notify_message(
					NULL, PURPLE_NOTIFY_MSG_ERROR, NULL,
					_("Directory is not writable."), NULL,
					(PurpleNotifyCloseCallback)purple_xfer_choose_file, xfer);
			}

			g_free(dir);
		}
		else {
			purple_xfer_show_file_error(xfer, filename);
			purple_xfer_cancel_local(xfer);
		}
	}
	else if ((type == PURPLE_XFER_SEND) && (st.st_size == 0)) {

		purple_notify_error(NULL, NULL,
						  _("Cannot send a file of 0 bytes."), NULL);

		purple_xfer_cancel_local(xfer);
	}
	else if ((type == PURPLE_XFER_SEND) && S_ISDIR(st.st_mode)) {
		/*
		 * XXX - Sending a directory should be valid for some protocols.
		 */
		purple_notify_error(NULL, NULL,
						  _("Cannot send a directory."), NULL);

		purple_xfer_cancel_local(xfer);
	}
	else if ((type == PURPLE_XFER_RECEIVE) && S_ISDIR(st.st_mode)) {
		char *msg, *utf8;
		utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
		msg = g_strdup_printf(
					_("%s is not a regular file. Cowardly refusing to overwrite it.\n"), utf8);
		g_free(utf8);
		purple_notify_error(NULL, NULL, msg, NULL);
		g_free(msg);
		purple_xfer_request_denied(xfer);
	}
	else if (type == PURPLE_XFER_SEND) {
#ifndef _WIN32
		int mode = R_OK;
#else
		int mode = F_OK;
#endif

		if (g_access(filename, mode) == 0) {
			purple_xfer_request_accepted(xfer, filename);
		} else {
			purple_xfer_ref(xfer);
			purple_notify_message(
				NULL, PURPLE_NOTIFY_MSG_ERROR, NULL,
				_("File is not readable."), NULL,
				(PurpleNotifyCloseCallback)purple_xfer_choose_file, xfer);
		}
	}
	else {
		purple_xfer_request_accepted(xfer, filename);
	}

	purple_xfer_unref(xfer);
}
예제 #18
0
void
msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *data, gsize len)
{
	MsnSlpMessage *slpmsg;
	guint64 offset;
	PurpleXfer *xfer = NULL;

	if (header->total_size < header->length)
	{
		purple_debug_error("msn", "This can't be good\n");
		g_return_if_reached();
	}

	offset = header->offset;

	if (offset == 0)
	{
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->id = header->id;
		slpmsg->session_id = header->session_id;
		slpmsg->size = header->total_size;
		slpmsg->flags = header->flags;

		if (slpmsg->session_id)
		{
			if (slpmsg->slpcall == NULL)
				slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);

			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->flags == 0x20 ||
				    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
				{
					xfer = slpmsg->slpcall->xfer;
					if (xfer != NULL)
					{
						slpmsg->ft = TRUE;
						slpmsg->slpcall->xfer_msg = slpmsg;

						purple_xfer_ref(xfer);
						purple_xfer_start(xfer,	-1, NULL, 0);

						if (xfer->data == NULL) {
							purple_xfer_unref(xfer);
							msn_slpmsg_destroy(slpmsg);
							g_return_if_reached();
						} else {
							purple_xfer_unref(xfer);
						}
					}
				}
			}
		}
		if (!slpmsg->ft && slpmsg->size)
		{
			slpmsg->buffer = g_try_malloc(slpmsg->size);
			if (slpmsg->buffer == NULL)
			{
				purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
				msn_slpmsg_destroy(slpmsg);
				return;
			}
		}
	}
	else
	{
		slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
		if (slpmsg == NULL)
		{
			/* Probably the transfer was canceled */
			purple_debug_error("msn", "Couldn't find slpmsg\n");
			return;
		}
	}

	if (slpmsg->ft)
	{
		xfer = slpmsg->slpcall->xfer;
		slpmsg->slpcall->u.incoming_data =
				g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len);
		purple_xfer_prpl_ready(xfer);
	}
	else if (slpmsg->size && slpmsg->buffer)
	{
		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size || slpmsg->offset != offset)
		{
			purple_debug_error("msn",
				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
				slpmsg->size, offset, len);
			g_return_if_reached();
		} else {
			memcpy(slpmsg->buffer + offset, data, len);
			slpmsg->offset += len;
		}
	}

	if ((slpmsg->flags == 0x20 ||
	     slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, offset);
		}
	}

#if 0
	if (slpmsg->buffer == NULL)
		return;
#endif

	if (header->offset + header->length >= header->total_size)
	{
		/* All the pieces of the slpmsg have been received */
		MsnSlpCall *slpcall;

		slpcall = msn_slp_process_msg(slplink, slpmsg);

		if (slpcall == NULL) {
			msn_slpmsg_destroy(slpmsg);
			return;
		}

		purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");

		if (/* !slpcall->wasted && */ slpmsg->flags == 0x100)
		{
#if 0
			MsnDirectConn *directconn;

			directconn = slplink->directconn;
			if (!directconn->acked)
				msn_directconn_send_handshake(directconn);
#endif
		}
		else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 ||
		         slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
		         slpmsg->flags == 0x1000030)
		{
			/* Release all the messages and send the ACK */

			if (slpcall->wait_for_socket) {
				/*
				 * Save ack for later because we have to send
				 * a 200 OK message to the previous direct connect
				 * invitation before ACK but the listening socket isn't
				 * created yet.
				 */
				purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");

				slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header);
			} else if (!slpcall->wasted) {
				purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");

				msn_slplink_send_ack(slplink, header);
				msn_slplink_send_queued_slpmsgs(slplink);
			}
		}

		msn_slpmsg_destroy(slpmsg);

		if (!slpcall->wait_for_socket && slpcall->wasted)
			msn_slpcall_destroy(slpcall);
	}
}
예제 #19
0
파일: gtkft.c 프로젝트: bf4/pidgin-mac
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);
}
예제 #20
0
파일: slplink.c 프로젝트: bf4/pidgin-mac
void
msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg)
{
	MsnSlpMessage *slpmsg;
	const char *data;
	gsize offset;
	gsize len;

#ifdef MSN_DEBUG_SLP
	msn_slpmsg_show(msg);
#endif

#ifdef MSN_DEBUG_SLP_FILES
	debug_msg_to_file(msg, FALSE);
#endif

	if (msg->msnslp_header.total_size < msg->msnslp_header.length)
	{
		purple_debug_error("msn", "This can't be good\n");
		g_return_if_reached();
	}

	slpmsg = NULL;
	data = msn_message_get_bin_data(msg, &len);

	/*
		OVERHEAD!
		if (msg->msnslp_header.length < msg->msnslp_header.total_size)
	 */

	offset = msg->msnslp_header.offset;

	if (offset == 0)
	{
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->id = msg->msnslp_header.id;
		slpmsg->session_id = msg->msnslp_header.session_id;
		slpmsg->size = msg->msnslp_header.total_size;
		slpmsg->flags = msg->msnslp_header.flags;

		if (slpmsg->session_id)
		{
			if (slpmsg->slpcall == NULL)
				slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);

			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030)
				{
					PurpleXfer *xfer;

					xfer = slpmsg->slpcall->xfer;

					if (xfer != NULL)
					{
						purple_xfer_ref(xfer);
						purple_xfer_start(xfer,	0, NULL, 0);

						if (xfer->data == NULL) {
							purple_xfer_unref(xfer);
							return;
						} else {
							purple_xfer_unref(xfer);
							slpmsg->fp = xfer->dest_fp;
							xfer->dest_fp = NULL; /* Disable double fclose() */
						}
					}
				}
			}
		}
		if (!slpmsg->fp && slpmsg->size)
		{
			slpmsg->buffer = g_try_malloc(slpmsg->size);
			if (slpmsg->buffer == NULL)
			{
				purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
				return;
			}
		}
	}
	else
	{
		slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id);
	}

	if (slpmsg == NULL)
	{
		/* Probably the transfer was canceled */
		purple_debug_error("msn", "Couldn't find slpmsg\n");
		return;
	}

	if (slpmsg->fp)
	{
		/* fseek(slpmsg->fp, offset, SEEK_SET); */
		len = fwrite(data, 1, len, slpmsg->fp);
	}
	else if (slpmsg->size)
	{
		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
		{
			purple_debug_error("msn", "Oversized slpmsg\n");
			g_return_if_reached();
		}
		else
			memcpy(slpmsg->buffer + offset, data, len);
	}

	if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, offset);
		}
	}

#if 0
	if (slpmsg->buffer == NULL)
		return;
#endif

	if (msg->msnslp_header.offset + msg->msnslp_header.length
		>= msg->msnslp_header.total_size)
	{
		/* All the pieces of the slpmsg have been received */
		MsnSlpCall *slpcall;

		slpcall = msn_slp_process_msg(slplink, slpmsg);

		if (slpmsg->flags == 0x100)
		{
			MsnDirectConn *directconn;

			directconn = slplink->directconn;

			if (!directconn->acked)
				msn_directconn_send_handshake(directconn);
		}
		else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 ||
				 slpmsg->flags == 0x1000030)
		{
			/* Release all the messages and send the ACK */

			msn_slplink_send_ack(slplink, msg);
			msn_slplink_unleash(slplink);
		}

		msn_slpmsg_destroy(slpmsg);

		if (slpcall != NULL && slpcall->wasted)
			msn_slp_call_destroy(slpcall);
	}
}
예제 #21
0
파일: slp.c 프로젝트: deadcow/msn-pecan
static void
got_sessionreq(MsnSlpCall *slpcall, const char *branch,
			   const char *euf_guid, const char *context)
{
	pecan_debug ("euf_guid=[%s]", euf_guid);

	if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6"))
	{
		/* Emoticon or UserDisplay */
		char *content;
		gsize len;
		MsnSlpSession *slpsession;
		MsnSlpLink *slplink;
		MsnSlpMessage *slpmsg;
		MsnObject *obj;
		char *msnobj_data;
		PecanBuffer *image;
		int type;

		/* Send Ok */
                content = pecan_strdup_printf("SessionID: %lu\r\n\r\n",
                                              slpcall->session_id);

		send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody",
				content);

		g_free(content);

		slplink = slpcall->slplink;

		msnobj_data = (char *)purple_base64_decode(context, &len);
		obj = msn_object_new_from_string(msnobj_data);
		type = msn_object_get_type(obj);
		g_free(msnobj_data);

		if (type == MSN_OBJECT_USERTILE)
		{
			/* image is owned by a local object, not obj */
			image = msn_object_get_image(obj);
		}
#if PURPLE_VERSION_CHECK(2,5,0)
		else if (type == MSN_OBJECT_EMOTICON)
		{
			PurpleStoredImage *img;
			char *path;
			path = g_build_filename(purple_smileys_get_storing_dir(), msn_object_get_location(obj), NULL);
			img = purple_imgstore_new_from_file(path);
			image = pecan_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img),
							 purple_imgstore_get_size (img));
			purple_imgstore_unref(img);
			g_free(path);
		}
#endif /* PURPLE_VERSION_CHECK(2,5,0) */
		else
		{
			pecan_error ("Wrong object?");
			msn_object_destroy(obj);
			g_return_if_reached();
		}

		if (!image)
		{
                    pecan_error ("Wrong object");
                    msn_object_destroy (obj);
                    g_return_if_reached ();
		}

		msn_object_destroy(obj);

		{
			gchar *tmp;
			tmp = msn_object_to_string (obj);
			pecan_info ("object requested: %s", tmp);
			g_free (tmp);
		}

		slpsession = msn_slplink_find_slp_session(slplink,
												  slpcall->session_id);

		/* DATA PREP */
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->slpcall = slpcall;
		slpmsg->slpsession = slpsession;
		slpmsg->session_id = slpsession->id;
		msn_slpmsg_set_body(slpmsg, NULL, 4);
#ifdef PECAN_DEBUG_SLP
		slpmsg->info = "SLP DATA PREP";
#endif
		msn_slplink_queue_slpmsg(slplink, slpmsg);

		/* DATA */
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->slpcall = slpcall;
		slpmsg->slpsession = slpsession;
		slpmsg->flags = 0x20;
#ifdef PECAN_DEBUG_SLP
		slpmsg->info = "SLP DATA";
#endif
		msn_slpmsg_set_image (slpmsg, image);
		msn_slplink_queue_slpmsg(slplink, slpmsg);
	}
	else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683"))
	{
		/* File Transfer */
		PurpleAccount *account;
		PurpleXfer *xfer;
		char *bin;
		gsize bin_len;
		guint32 file_size;
		char *file_name;
		gunichar2 *uni_name;

		account = slpcall->slplink->session->account;

		slpcall->cb = msn_xfer_completed_cb;
		slpcall->end_cb = msn_xfer_end_cb;
		slpcall->progress_cb = msn_xfer_progress_cb;
		slpcall->branch = g_strdup(branch);

		slpcall->pending = TRUE;

		xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
							   slpcall->slplink->remote_user);
		if (xfer)
		{
			bin = (char *)purple_base64_decode(context, &bin_len);
			file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8));

			uni_name = (gunichar2 *)(bin + 20);
			while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
				*uni_name = GUINT16_FROM_LE(*uni_name);
				uni_name++;
			}

			file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1,
										NULL, NULL, NULL);

			g_free(bin);

			purple_xfer_set_filename(xfer, file_name);
			purple_xfer_set_size(xfer, file_size);
			purple_xfer_set_init_fnc(xfer, msn_xfer_init);
			purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
			purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);

			slpcall->xfer = xfer;
			purple_xfer_ref(slpcall->xfer);

			xfer->data = slpcall;

			purple_xfer_request(xfer);
		}
	}
}
예제 #22
0
파일: peer.c 프로젝트: Tasssadar/libpurple
/**
 * Someone else wants to establish a peer connection with us.
 */
void
peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args)
{
	PurpleConnection *gc;
	PurpleAccount *account;
	PeerConnection *conn;
	gchar *buf;

	gc = od->gc;
	account = purple_connection_get_account(gc);

	/*
	 * If we have a connection with this same cookie then they are
	 * probably just telling us they weren't able to connect to us
	 * and we should try connecting to them, instead.  Or they want
	 * to go through a proxy.
	 */
	conn = peer_connection_find_by_cookie(od, bn, args->cookie);
	if ((conn != NULL) && (conn->type == args->type))
	{
		purple_debug_info("oscar", "Remote user wants to try a "
				"different connection method\n");
		g_free(conn->proxyip);
		g_free(conn->clientip);
		g_free(conn->verifiedip);
		if (args->use_proxy)
			conn->proxyip = g_strdup(args->proxyip);
		else
			conn->proxyip = NULL;
		conn->verifiedip = g_strdup(args->verifiedip);
		conn->clientip = g_strdup(args->clientip);
		conn->port = args->port;
		conn->use_proxy |= args->use_proxy;
		conn->lastrequestnumber++;
		peer_connection_trynext(conn);
		return;
	}

	/* If this is a direct IM, then close any existing session */
	if (args->type == OSCAR_CAPABILITY_DIRECTIM)
	{
		conn = peer_connection_find_by_type(od, bn, args->type);
		if (conn != NULL)
		{
			/* Close the old direct IM and start a new one */
			purple_debug_info("oscar", "Received new direct IM request "
				"from %s.  Destroying old connection.\n", bn);
			peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL);
		}
	}

	/* Check for proper arguments */
	if (args->type == OSCAR_CAPABILITY_SENDFILE)
	{
		if ((args->info.sendfile.filename == NULL) ||
			(args->info.sendfile.totsize == 0) ||
			(args->info.sendfile.totfiles == 0))
		{
			purple_debug_warning("oscar",
					"%s tried to send you a file with incomplete "
					"information.\n", bn);
			return;
		}
	}

	conn = peer_connection_new(od, args->type, bn);
	memcpy(conn->cookie, args->cookie, 8);
	if (args->use_proxy)
		conn->proxyip = g_strdup(args->proxyip);
	conn->clientip = g_strdup(args->clientip);
	conn->verifiedip = g_strdup(args->verifiedip);
	conn->port = args->port;
	conn->use_proxy |= args->use_proxy;
	conn->lastrequestnumber++;

	if (args->type == OSCAR_CAPABILITY_DIRECTIM)
	{
		buf = g_strdup_printf(_("%s has just asked to directly connect to %s"),
				bn, purple_account_get_username(account));

		purple_request_action(conn, NULL, buf,
						_("This requires a direct connection between "
						  "the two computers and is necessary for IM "
						  "Images.  Because your IP address will be "
						  "revealed, this may be considered a privacy "
						  "risk."),
						PURPLE_DEFAULT_ACTION_NONE,
						account, bn, NULL,
						conn, 2,
						_("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb),
						_("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb));
	}
	else if (args->type == OSCAR_CAPABILITY_SENDFILE)
	{
		gchar *filename;

		conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn);
		if (conn->xfer)
		{
			conn->xfer->data = conn;
			purple_xfer_ref(conn->xfer);
			purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize);

			/* Set the file name */
			if (g_utf8_validate(args->info.sendfile.filename, -1, NULL))
				filename = g_strdup(args->info.sendfile.filename);
			else
				filename = purple_utf8_salvage(args->info.sendfile.filename);

			if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR)
			{
				/*
				 * If they are sending us a directory then the last character
				 * of the file name will be an asterisk.  We don't want to
				 * save stuff to a directory named "*" so we remove the
				 * asterisk from the file name.
				 */
				char *tmp = strrchr(filename, '\\');
				if ((tmp != NULL) && (tmp[1] == '*'))
					tmp[0] = '\0';
			}
			purple_xfer_set_filename(conn->xfer, filename);
			g_free(filename);

			/*
			 * Set the message, unless this is the dummy message from an
			 * ICQ client or an empty message from an AIM client.
			 * TODO: Maybe we should strip HTML and then see if strlen>0?
			 */
			if ((message != NULL) &&
				(g_ascii_strncasecmp(message, "<ICQ_COOL_FT>", 13) != 0) &&
				(g_ascii_strcasecmp(message, "<HTML>") != 0))
			{
				purple_xfer_set_message(conn->xfer, message);
			}

			/* Setup our I/O op functions */
			purple_xfer_set_init_fnc(conn->xfer, peer_oft_recvcb_init);
			purple_xfer_set_end_fnc(conn->xfer, peer_oft_recvcb_end);
			purple_xfer_set_request_denied_fnc(conn->xfer, peer_oft_cb_generic_cancel);
			purple_xfer_set_cancel_recv_fnc(conn->xfer, peer_oft_cb_generic_cancel);
			purple_xfer_set_ack_fnc(conn->xfer, peer_oft_recvcb_ack_recv);

			/* Now perform the request */
			purple_xfer_request(conn->xfer);
		}
	}
}