コード例 #1
0
ファイル: fb_connection.c プロジェクト: bf4/pidgin-mac
static void fb_ssl_connection_error(PurpleSslConnection *ssl,
		PurpleSslErrorType errortype, gpointer data)
{
	FacebookConnection *fbconn = data;
	PurpleConnection *pc = fbconn->fba->pc;

	fbconn->ssl_conn = NULL;
	fb_connection_destroy(fbconn);
	purple_connection_ssl_error(pc, errortype);
}
コード例 #2
0
ファイル: fb_connection.c プロジェクト: bf4/pidgin-mac
static void fb_fatal_connection_cb(FacebookConnection *fbconn)
{
	PurpleConnection *pc = fbconn->fba->pc;

	purple_debug_error("facebook", "fatal connection error\n");

	fb_connection_destroy(fbconn);

	/* We died.  Do not pass Go.  Do not collect $200 */
	/* In all seriousness, don't attempt to call the normal callback here.
	 * That may lead to the wrong error message being displayed */
	purple_connection_error_reason(pc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				_("Server closed the connection."));

}
コード例 #3
0
static void fb_close(PurpleConnection *pc)
{
	FacebookAccount *fba;
	gchar *postdata;
	GSList *buddies;

	purple_debug_info("facebook", "disconnecting account\n");

	g_return_if_fail(pc != NULL);
	g_return_if_fail(pc->proto_data != NULL);
	
	fba = pc->proto_data;

	if ( fba == NULL )		//VOXOX - JRT - 2009.10.12 - Prevent crash when network is lost or resuming from hibernation.
		return;

	purple_debug_info("facebook", "unloading plugin\n");

	/* destroy blist subsystem */
	fb_blist_destroy(fba);

	/* destroy conversation subsystem */
	fb_conversation_destroy(fba);
	buddies = purple_find_buddies(fba->account, NULL);
	while(buddies) {
		PurpleBuddy *b = buddies->data;
		fb_buddy_free(b);
		buddies = g_slist_delete_link(buddies, buddies);
	}

	/* Tell Facebook that we've logged out. */
	/*
	 * TODO
	 * This doesn't actually work because the request is non-blocking
	 * and we're in the process of logging out.  So we start making a
	 * connection but then libpurple immediately cancels the attempt
	 * and frees everything.
	 *
	 * There are two ways to fix this:
	 * 1. We could make this request, but not pass in fba or reference
	 *    any other data.  The request could complete normally even
	 *    after this account has logged out, since it really doesn't
	 *    need access to the PurpleConnection or the FacebookAccount.
	 *
	 * 2. The close prpl callback could be changed in libpurple so that
	 *    protocol plugins can have a chance to make network requests
	 *    and do other long cleanup operations.  So the call to
	 *    prpl->close() would become asynchronous.  It tells the
	 *    protocol plugin to begin the shutdown sequence, and the
	 *    protocol plugin tells the core when it's finished.
	 */
	if (fba->post_form_id)
		postdata = g_strdup_printf(
				"visibility=false&post_form_id=%s&"
				"fb_dtsg=%s&post_form_id_source=AsyncRequest&"
				"__a=1",
				fba->post_form_id, fba->dtsg);
	else
		postdata = g_strdup("visibility=false");
	fb_post_or_get(fba, FB_METHOD_POST, NULL, "/ajax/chat/settings.php",
			postdata, NULL, NULL, FALSE);
	g_free(postdata);

	if (fba->friend_request_timer) {
		purple_timeout_remove(fba->friend_request_timer);
	}
	if (fba->notifications_timer) {
		purple_timeout_remove(fba->notifications_timer);
	}
	if (fba->new_messages_check_timer) {
		purple_timeout_remove(fba->new_messages_check_timer);
	}
	if (fba->perpetual_messages_timer) {
		purple_timeout_remove(fba->perpetual_messages_timer);
	}

	purple_debug_info("facebook", "destroying %d incomplete connections\n",
			g_slist_length(fba->conns));

	while (fba->conns != NULL)
		fb_connection_destroy(fba->conns->data);

	while (fba->dns_queries != NULL) {
		PurpleDnsQueryData *dns_query = fba->dns_queries->data;
		purple_debug_info("facebook", "canceling dns query for %s\n",
					purple_dnsquery_get_host(dns_query));
		fba->dns_queries = g_slist_remove(fba->dns_queries, dns_query);
		purple_dnsquery_destroy(dns_query);
	}
	
	if (fba->resending_messages != NULL) {
		fb_cancel_resending_messages(fba);
	}

	//VOXOX - JRT - 2009.10.13 - I know we are deleting fba anyway, but since other threads may also be accessing this,
	//							 it helps reduce crashes due to freed memory ptrs.  (There is no thread syncing to control this better).
	g_hash_table_destroy(fba->cookie_table);

	g_hash_table_destroy(fba->hostname_ip_cache);

	g_hash_table_destroy(fba->auth_buddies);

	g_free(fba->post_form_id);
	g_free(fba->dtsg);
	g_free(fba->channel_number);
	g_free(fba->last_status_message);
	g_free(fba->extra_challenge);
	g_free(fba->captcha_session);
	g_free(fba->persist_data);
	g_free(fba);

}
コード例 #4
0
ファイル: fb_connection.c プロジェクト: bf4/pidgin-mac
static void fb_post_or_get_readdata_cb(gpointer data, gint source,
		PurpleInputCondition cond)
{
	FacebookConnection *fbconn;
	gchar buf[4096];
	ssize_t len;

	fbconn = data;

	if (fbconn->method & FB_METHOD_SSL) {
		len = purple_ssl_read(fbconn->ssl_conn,
				buf, sizeof(buf) - 1);
	} else {
		len = recv(fbconn->fd, buf, sizeof(buf) - 1, 0);
	}

	if (len < 0)
	{
		if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
			/* Try again later */
			return;
		}

		if (fbconn->method & FB_METHOD_SSL && fbconn->rx_len > 0) {
			/*
			 * This is a slightly hacky workaround for a bug in either
			 * GNU TLS or in the SSL implementation on Facebook's web
			 * servers.  The sequence of events is:
			 * 1. We attempt to read the first time and successfully read
			 *    the server's response.
			 * 2. We attempt to read a second time and libpurple's call
			 *    to gnutls_record_recv() returns the error
			 *    GNUTLS_E_UNEXPECTED_PACKET_LENGTH, or
			 *    "A TLS packet with unexpected length was received."
			 *
			 * Normally the server would have closed the connection
			 * cleanly and this second read() request would have returned
			 * 0.  Or maybe it's normal for SSL connections to be severed
			 * in this manner?  In any case, this differs from the behavior
			 * of the standard recv() system call.
			 */
			purple_debug_warning("facebook",
				"ssl error, but data received.  attempting to continue\n");
		} else {
			/* TODO: Is this a regular occurrence?  If so then maybe resend the request? */
			fb_fatal_connection_cb(fbconn);
			return;
		}
	}

	if (len > 0)
	{
		buf[len] = '\0';

		fbconn->rx_buf = g_realloc(fbconn->rx_buf,
				fbconn->rx_len + len + 1);
		memcpy(fbconn->rx_buf + fbconn->rx_len, buf, len + 1);
		fbconn->rx_len += len;

		/* Wait for more data before processing */
		return;
	}

	/* The server closed the connection, let's parse the data */
	fb_connection_process_data(fbconn);

	fb_connection_destroy(fbconn);
}