changeset 27116:b58672890b3f

merge of '051b51aa2424e978f16c10511f7a4e0f45c7c5d3' and '69b3b10f3cd5853b74cace5f7247f384555cbbff'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 05 Jun 2009 04:27:53 +0000
parents 2ab648c328cc (diff) 005d20d58ac7 (current diff)
children 9c36a340fcaf c3fcdd59ab76
files
diffstat 7 files changed, 182 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Fri Jun 05 04:13:10 2009 +0000
+++ b/ChangeLog.API	Fri Jun 05 04:27:53 2009 +0000
@@ -16,9 +16,6 @@
 		* blist-node-added and blist-node-removed signals (see
 		  blist-signals.dox)
 		* Jabber plugin signals (see jabber-signals.dox)
-		* Plugins may now emit the jabber-sending-xmlnode signal in order
-		  to send stanzas; this method is preferred to the prpl send_raw
-		  function as other plugins listening to the signal see them.
 		* purple_buddy_destroy
 		* purple_buddy_get_protocol_data
 		* purple_buddy_set_protocol_data
@@ -42,6 +39,7 @@
 		* purple_network_set_turn_server
 		* purple_network_get_stun_ip
 		* purple_network_get_turn_ip
+		* purple_proxy_connect_udp
 		* purple_prpl_get_media_caps
 		* purple_prpl_got_account_actions
 		* purple_prpl_initiate_media
@@ -60,6 +58,13 @@
 		  which was completely non-deterministic.  If you want to remove
 		  the attribute with no namespace, then use NULL with
 		  xmlnode_remove_with_namespace.
+		* Plugins may now emit the jabber-sending-xmlnode signal in order
+		  to send stanzas; this method is preferred to the prpl send_raw
+		  function as other plugins listening to the signal see them.
+		* The conversation-updated signal with a PURPLE_CONV_UPDATE_TYPING
+		  update type is emitted when receiving an IM.  Previously, the
+		  typing state was modified (and the buddy-typing-stopped signal
+		  emitted), but this signal was not emitted.
 
 		Deprecated:
 		* buddy-added and buddy-removed blist signals
--- a/libpurple/conversation.c	Fri Jun 05 04:13:10 2009 +0000
+++ b/libpurple/conversation.c	Fri Jun 05 04:27:53 2009 +0000
@@ -55,7 +55,6 @@
 	im = PURPLE_CONV_IM(c);
 
 	purple_conv_im_set_typing_state(im, PURPLE_NOT_TYPING);
-	purple_conv_im_update_typing(im);
 	purple_conv_im_stop_typing_timeout(im);
 
 	return FALSE;
@@ -1050,6 +1049,8 @@
 								   "buddy-typing-stopped", im->conv->account, im->conv->name);
 				break;
 		}
+
+		purple_conv_im_update_typing(im);
 	}
 }
 
--- a/libpurple/plugins/psychic.c	Fri Jun 05 04:13:10 2009 +0000
+++ b/libpurple/plugins/psychic.c	Fri Jun 05 04:27:53 2009 +0000
@@ -74,6 +74,7 @@
 			      time(NULL));
     }
 
+    /* Necessary because we may be creating a new conversation window. */
     purple_conv_im_set_typing_state(PURPLE_CONV_IM(gconv), PURPLE_TYPING);
   }
 }
--- a/libpurple/proxy.c	Fri Jun 05 04:13:10 2009 +0000
+++ b/libpurple/proxy.c	Fri Jun 05 04:27:53 2009 +0000
@@ -47,6 +47,7 @@
 	gchar *host;
 	int port;
 	int fd;
+	int socket_type;
 	guint inpa;
 	PurpleProxyInfo *gpi;
 	PurpleDnsQueryData *query_data;
@@ -676,6 +677,68 @@
 }
 
 static void
+proxy_connect_udp_none(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
+{
+	int flags;
+
+	purple_debug_info("proxy", "UDP Connecting to %s:%d with no proxy\n",
+			connect_data->host, connect_data->port);
+
+	connect_data->fd = socket(addr->sa_family, SOCK_DGRAM, 0);
+	if (connect_data->fd < 0)
+	{
+		purple_proxy_connect_data_disconnect_formatted(connect_data,
+				_("Unable to create socket:\n%s"), g_strerror(errno));
+		return;
+	}
+
+	flags = fcntl(connect_data->fd, F_GETFL);
+	fcntl(connect_data->fd, F_SETFL, flags | O_NONBLOCK);
+#ifndef _WIN32
+	fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+	if (connect(connect_data->fd, addr, addrlen) != 0)
+	{
+		if ((errno == EINPROGRESS) || (errno == EINTR))
+		{
+			purple_debug_info("proxy", "UDP Connection in progress\n");
+			connect_data->inpa = purple_input_add(connect_data->fd,
+					PURPLE_INPUT_WRITE, socket_ready_cb, connect_data);
+		}
+		else
+		{
+			purple_proxy_connect_data_disconnect(connect_data, g_strerror(errno));
+		}
+	}
+	else
+	{
+		/*
+		 * The connection happened IMMEDIATELY... strange, but whatever.
+		 */
+		int error = ETIMEDOUT;
+		int ret;
+
+		purple_debug_info("proxy", "UDP Connected immediately.\n");
+
+		ret = purple_input_get_error(connect_data->fd, &error);
+		if ((ret != 0) || (error != 0))
+		{
+			if (ret != 0)
+				error = errno;
+			purple_proxy_connect_data_disconnect(connect_data, g_strerror(error));
+			return;
+		}
+
+		/*
+		 * We want to call the "connected" callback eventually, but we
+		 * don't want to call it before we return, just in case.
+		 */
+		purple_timeout_add(10, clean_connect, connect_data);
+	}
+}
+
+static void
 proxy_connect_none(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
 {
 	int flags;
@@ -2042,6 +2105,12 @@
 #endif
 	purple_debug_info("proxy", "Attempting connection to %s\n", ipaddr);
 
+	if (connect_data->socket_type == SOCK_DGRAM) {
+		proxy_connect_udp_none(connect_data, addr, addrlen);
+		g_free(addr);
+		return;
+	}
+
 	switch (purple_proxy_info_get_type(connect_data->gpi)) {
 		case PURPLE_PROXY_NONE:
 			proxy_connect_none(connect_data, addr, addrlen);
@@ -2193,6 +2262,7 @@
 
 	connect_data = g_new0(PurpleProxyConnectData, 1);
 	connect_data->fd = -1;
+	connect_data->socket_type = SOCK_STREAM;
 	connect_data->handle = handle;
 	connect_data->connect_cb = connect_cb;
 	connect_data->data = data;
@@ -2243,6 +2313,71 @@
 	return connect_data;
 }
 
+PurpleProxyConnectData *
+purple_proxy_connect_udp(void *handle, PurpleAccount *account,
+				   const char *host, int port,
+				   PurpleProxyConnectFunction connect_cb, gpointer data)
+{
+	const char *connecthost = host;
+	int connectport = port;
+	PurpleProxyConnectData *connect_data;
+
+	g_return_val_if_fail(host       != NULL, NULL);
+	g_return_val_if_fail(port       >  0,    NULL);
+	g_return_val_if_fail(connect_cb != NULL, NULL);
+
+	connect_data = g_new0(PurpleProxyConnectData, 1);
+	connect_data->fd = -1;
+	connect_data->socket_type = SOCK_DGRAM;
+	connect_data->handle = handle;
+	connect_data->connect_cb = connect_cb;
+	connect_data->data = data;
+	connect_data->host = g_strdup(host);
+	connect_data->port = port;
+	connect_data->gpi = purple_proxy_get_setup(account);
+
+	if ((purple_proxy_info_get_type(connect_data->gpi) != PURPLE_PROXY_NONE) &&
+		(purple_proxy_info_get_host(connect_data->gpi) == NULL ||
+		 purple_proxy_info_get_port(connect_data->gpi) <= 0)) {
+
+		purple_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid."));
+		purple_proxy_connect_data_destroy(connect_data);
+		return NULL;
+	}
+
+	switch (purple_proxy_info_get_type(connect_data->gpi))
+	{
+		case PURPLE_PROXY_NONE:
+			break;
+
+		case PURPLE_PROXY_HTTP:
+		case PURPLE_PROXY_SOCKS4:
+		case PURPLE_PROXY_SOCKS5:
+		case PURPLE_PROXY_USE_ENVVAR:
+			purple_debug_info("proxy", "Ignoring Proxy type (%d) for UDP.\n",
+			                  purple_proxy_info_get_type(connect_data->gpi));
+			break;
+
+		default:
+			purple_debug_error("proxy", "Invalid Proxy type (%d) specified.\n",
+			                   purple_proxy_info_get_type(connect_data->gpi));
+			purple_proxy_connect_data_destroy(connect_data);
+			return NULL;
+	}
+
+	connect_data->query_data = purple_dnsquery_a(connecthost,
+			connectport, connection_host_resolved, connect_data);
+	if (connect_data->query_data == NULL)
+	{
+		purple_proxy_connect_data_destroy(connect_data);
+		return NULL;
+	}
+
+	handles = g_slist_prepend(handles, connect_data);
+
+	return connect_data;
+}
+
 /*
  * Combine some of this code with purple_proxy_connect()
  */
@@ -2260,6 +2395,7 @@
 
 	connect_data = g_new0(PurpleProxyConnectData, 1);
 	connect_data->fd = -1;
+	connect_data->socket_type = SOCK_STREAM;
 	connect_data->handle = handle;
 	connect_data->connect_cb = connect_cb;
 	connect_data->data = data;
--- a/libpurple/proxy.h	Fri Jun 05 04:13:10 2009 +0000
+++ b/libpurple/proxy.h	Fri Jun 05 04:27:53 2009 +0000
@@ -257,6 +257,35 @@
 			PurpleProxyConnectFunction connect_cb, gpointer data);
 
 /**
+ * Makes a connection to the specified host and port.  Note that this
+ * function name can be misleading--although it is called "proxy
+ * connect," it is used for establishing any outgoing UDP connection,
+ * whether through a proxy or not.
+ *
+ * @param handle     A handle that should be associated with this
+ *                   connection attempt.  The handle can be used
+ *                   to cancel the connection attempt using the
+ *                   purple_proxy_connect_cancel_with_handle()
+ *                   function.
+ * @param account    The account making the connection.
+ * @param host       The destination host.
+ * @param port       The destination port.
+ * @param connect_cb The function to call when the connection is
+ *                   established.  If the connection failed then
+ *                   fd will be -1 and error message will be set
+ *                   to something descriptive (hopefully).
+ * @param data       User-defined data.
+ *
+ * @return NULL if there was an error, or a reference to an
+ *         opaque data structure that can be used to cancel
+ *         the pending connection, if needed.
+ */
+PurpleProxyConnectData *purple_proxy_connect_udp(void *handle,
+			PurpleAccount *account,
+			const char *host, int port,
+			PurpleProxyConnectFunction connect_cb, gpointer data);
+
+/**
  * Makes a connection through a SOCKS5 proxy.
  *
  * @param handle     A handle that should be associated with this
--- a/libpurple/server.c	Fri Jun 05 04:13:10 2009 +0000
+++ b/libpurple/server.c	Fri Jun 05 04:27:53 2009 +0000
@@ -728,7 +728,6 @@
 		im = PURPLE_CONV_IM(conv);
 
 		purple_conv_im_set_typing_state(im, state);
-		purple_conv_im_update_typing(im);
 	} else {
 		switch (state)
 		{
@@ -766,7 +765,6 @@
 
 		purple_conv_im_stop_typing_timeout(im);
 		purple_conv_im_set_typing_state(im, PURPLE_NOT_TYPING);
-		purple_conv_im_update_typing(im);
 	}
 	else
 	{
--- a/pidgin/plugins/disco/xmppdisco.c	Fri Jun 05 04:13:10 2009 +0000
+++ b/pidgin/plugins/disco/xmppdisco.c	Fri Jun 05 04:27:53 2009 +0000
@@ -18,13 +18,15 @@
  */
 
 /* TODO list (a little bit of a brain dump):
-     * Support more actions than "register" and "add" based on context.
-	    - Subscribe to pubsub nodes (just...because?)
+	* Support more actions than "register" and "add" based on context.
+		- Subscribe to pubsub nodes (just...because?)
 		- Execute ad-hoc commands
 		- Change 'Register' to 'Unregister' if we're registered?
 		- Administer MUCs
-     * See if we can better handle the ad-hoc commands that ejabberd returns
-	   when disco'ing a server as an administrator:
+	* Enumerate pubsub node contents.
+		- PEP too? (useful development tool at times)
+	* See if we can better handle the ad-hoc commands that ejabberd returns
+	  when disco'ing a server as an administrator:
 from disco#items:
 	<item jid='darkrain42.org' node='announce' name='Announcements'/>
 disco#info: