# HG changeset patch # User Sadrul Habib Chowdhury # Date 1213759625 0 # Node ID 3f765f7e79d4f6bedf0f8459041cecb861fadf3e # Parent 54aaea893a890b2ca96dddec33ef84ede8094ad0# Parent 6c728443b426ec0522998b90086fc5913d61efdc merge of '500604b1f22bc5f32a818dc80bbc252bc460dc85' and '8538a2f807d6d671d1896aa0ad6be0d3a07c4035' diff -r 54aaea893a89 -r 3f765f7e79d4 configure.ac --- a/configure.ac Sat Jun 14 02:03:26 2008 +0000 +++ b/configure.ac Wed Jun 18 03:27:05 2008 +0000 @@ -2223,9 +2223,11 @@ AC_CHECK_HEADERS(termios.h) # sys/sysctl.h on OpenBSD 4.2 requires sys/param.h +# sys/sysctl.h on FreeBSD requires sys/types.h AC_CHECK_HEADERS(sys/param.h) AC_CHECK_HEADERS(sys/sysctl.h, [], [], [[ + #include #ifdef HAVE_PARAM_H # include #endif diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/blist.h --- a/libpurple/blist.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/blist.h Wed Jun 18 03:27:05 2008 +0000 @@ -31,13 +31,20 @@ #include +/** @copydoc _PurpleBuddyList */ typedef struct _PurpleBuddyList PurpleBuddyList; +/** @copydoc _PurpleBlistUiOps */ typedef struct _PurpleBlistUiOps PurpleBlistUiOps; +/** @copydoc _PurpleBlistNode */ typedef struct _PurpleBlistNode PurpleBlistNode; +/** @copydoc _PurpleChat */ typedef struct _PurpleChat PurpleChat; +/** @copydoc _PurpleGroup */ typedef struct _PurpleGroup PurpleGroup; +/** @copydoc _PurpleContact */ typedef struct _PurpleContact PurpleContact; +/** @copydoc _PurpleBuddy */ typedef struct _PurpleBuddy PurpleBuddy; /**************************************************************************/ diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/cmds.h --- a/libpurple/cmds.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/cmds.h Wed Jun 18 03:27:05 2008 +0000 @@ -30,6 +30,7 @@ /**************************************************************************/ /*@{*/ +/** The possible results of running a command with purple_cmd_do_command(). */ typedef enum _PurpleCmdStatus { PURPLE_CMD_STATUS_OK, PURPLE_CMD_STATUS_FAILED, @@ -39,16 +40,31 @@ PURPLE_CMD_STATUS_WRONG_TYPE, } PurpleCmdStatus; +/** Commands registered with the core return one of these values when run. + * Normally, a command will want to return one of the first two; in some + * unusual cases, you might want to have several functions called for a + * particular command; in this case, they should return + * #PURPLE_CMD_RET_CONTINUE to cause the core to fall through to other + * commands with the same name. + */ typedef enum _PurpleCmdRet { - PURPLE_CMD_RET_OK, /**< Everything's okay. Don't look for another command to call. */ + PURPLE_CMD_RET_OK, /**< Everything's okay; Don't look for another command to call. */ PURPLE_CMD_RET_FAILED, /**< The command failed, but stop looking.*/ PURPLE_CMD_RET_CONTINUE, /**< Continue, looking for other commands with the same name to call. */ } PurpleCmdRet; #define PURPLE_CMD_FUNC(func) ((PurpleCmdFunc)func) +/** A function implementing a command, as passed to purple_cmd_register(). + * + * @todo document the arguments to these functions. + * */ typedef PurpleCmdRet (*PurpleCmdFunc)(PurpleConversation *, const gchar *cmd, gchar **args, gchar **error, void *data); +/** A unique integer representing a command registered with + * purple_cmd_register(), which can subsequently be passed to + * purple_cmd_unregister() to unregister that command. + */ typedef guint PurpleCmdId; typedef enum _PurpleCmdPriority { diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/connection.h --- a/libpurple/connection.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/connection.h Wed Jun 18 03:27:05 2008 +0000 @@ -27,6 +27,7 @@ #ifndef _PURPLE_CONNECTION_H_ #define _PURPLE_CONNECTION_H_ +/** @copydoc _PurpleConnection */ typedef struct _PurpleConnection PurpleConnection; /** @@ -121,7 +122,7 @@ */ PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR = 15, - /** Some other error occured which fits into none of the other + /** Some other error occurred which fits into none of the other * categories. */ /* purple_connection_error_reason() in connection.c uses the fact that @@ -223,6 +224,8 @@ void (*_purple_reserved3)(void); } PurpleConnectionUiOps; + +/* Represents an active connection on an account. */ struct _PurpleConnection { PurplePlugin *prpl; /**< The protocol plugin. */ diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/conversation.h --- a/libpurple/conversation.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/conversation.h Wed Jun 18 03:27:05 2008 +0000 @@ -32,11 +32,17 @@ /**************************************************************************/ +/** @copydoc _PurpleConversationUiOps */ typedef struct _PurpleConversationUiOps PurpleConversationUiOps; +/** @copydoc _PurpleConversation */ typedef struct _PurpleConversation PurpleConversation; +/** @copydoc _PurpleConvIm */ typedef struct _PurpleConvIm PurpleConvIm; +/** @copydoc _PurpleConvChat */ typedef struct _PurpleConvChat PurpleConvChat; +/** @copydoc _PurpleConvChatBuddy */ typedef struct _PurpleConvChatBuddy PurpleConvChatBuddy; +/** @copydoc _PurpleConvMessage */ typedef struct _PurpleConvMessage PurpleConvMessage; /** diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/core.h --- a/libpurple/core.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/core.h Wed Jun 18 03:27:05 2008 +0000 @@ -1,4 +1,5 @@ /** + * @file core.h Startup and shutdown of libpurple * @defgroup core libpurple * @see @ref core-signals */ @@ -28,12 +29,36 @@ typedef struct PurpleCore PurpleCore; +/** Callbacks that fire at different points of the initialization and teardown + * of libpurple, along with a hook to return descriptive information about the + * UI. + */ typedef struct { + /** Called just after the preferences subsystem is initialized; the UI + * could use this callback to add some preferences it needs to be in + * place when other subsystems are initialized. + */ void (*ui_prefs_init)(void); - void (*debug_ui_init)(void); /* Unfortunate necessity. */ + /** Called just after the debug subsystem is initialized, but before + * just about every other component's initialization. The UI should + * use this hook to call purple_debug_set_ui_ops() so that debugging + * information for other components can be logged during their + * initialization. + */ + void (*debug_ui_init)(void); + /** Called after all of libpurple has been initialized. The UI should + * use this hook to set all other necessary UiOps structures. + * + * @see @ref ui-ops + */ void (*ui_init)(void); + /** Called after most of libpurple has been uninitialized. */ void (*quit)(void); + + /** Called by purple_core_get_ui_info(); should return the information + * documented there. + */ GHashTable* (*get_ui_info)(void); void (*_purple_reserved1)(void); @@ -64,17 +89,23 @@ void purple_core_quit(void); /** + *

* Calls purple_core_quit(). This can be used as the function * passed to purple_timeout_add() when you want to shutdown Purple * in a specified amount of time. When shutting down Purple * from a plugin, you must use this instead of purple_core_quit(); * for an immediate exit, use a timeout value of 0: - * purple_timeout_add(0, purple_core_quitcb, NULL); + *

+ * + * purple_timeout_add(0, purple_core_quitcb, NULL); + * + *

* This is ensures that code from your plugin is not being * executed when purple_core_quit() is called. If the plugin * called purple_core_quit() directly, you would get a core dump * after purple_core_quit() executes and control returns to your * plugin because purple_core_quit() frees all plugins. + *

*/ gboolean purple_core_quit_cb(gpointer unused); @@ -86,7 +117,8 @@ const char *purple_core_get_version(void); /** - * Returns the ID of the UI that is using the core. + * Returns the ID of the UI that is using the core, as passed to + * purple_core_init(). * * @return The ID of the UI that is currently using the core. */ @@ -95,7 +127,7 @@ /** * Returns a handle to the purple core. * - * This is used for such things as signals. + * This is used to connect to @ref core-signals "core signals". */ PurpleCore *purple_get_core(void); @@ -114,10 +146,10 @@ PurpleCoreUiOps *purple_core_get_ui_ops(void); /** - * Migrates from .gaim to .purple. + * Migrates from .gaim to .purple. * - * UIs MUST NOT call this if they have been told to use a custom - * user directory. + * UIs must not call this if they have been told to use a + * custom user directory. * * @return A boolean indicating success or migration failure. On failure, * the application must display an error to the user and then exit. @@ -125,20 +157,33 @@ gboolean purple_core_migrate(void); /** - * Ensures that only one instance is running. + * Ensures that only one instance is running. If libpurple is built with D-Bus + * support, this checks if another process owns the libpurple bus name and if + * so whether that process is using the same configuration directory as this + * process. * - * @return A boolean such that @c TRUE indicates that this is the first instance, - * whereas @c FALSE indicates that there is another instance running. + * @return @c TRUE if this is the first instance of libpurple running; + * @c FALSE if there is another instance running. * * @since 2.1.0 */ gboolean purple_core_ensure_single_instance(void); /** - * Returns a hashtable containing various information about the UI + * Returns a hash table containing various information about the UI. The + * following well-known entries may be in the table (along with any others the + * UI might choose to include): + * + *
+ *
name
+ *
the user-readable name for the UI.
+ * + *
version
+ *
a user-readable description of the current version of the UI.
+ *
* * @return A GHashTable with strings for keys and values. This - * hash table must not be freed. + * hash table must not be freed and should not be modified. * * @since 2.1.0 * diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/nat-pmp.c --- a/libpurple/nat-pmp.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/nat-pmp.c Wed Jun 18 03:27:05 2008 +0000 @@ -35,6 +35,10 @@ #include "signals.h" #include "network.h" +#ifdef HAVE_SYS_PARAM_H +#include +#endif + #ifdef HAVE_SYS_SYSCTL_H #include #endif diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/gg/search.h --- a/libpurple/protocols/gg/search.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/gg/search.h Wed Jun 18 03:27:05 2008 +0000 @@ -130,7 +130,7 @@ * @param gc PurpleConnection. * @param form Filled in GGPSearchForm. * - * @return Sequence number of a search or 0 if an error occured. + * @return Sequence number of a search or 0 if an error occurred. */ guint32 ggp_search_start(PurpleConnection *gc, GGPSearchForm *form); diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Jun 18 03:27:05 2008 +0000 @@ -273,70 +273,10 @@ purple_circ_buffer_mark_read(js->write_buffer, ret); } -void jabber_send_raw(JabberStream *js, const char *data, int len) +static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len) { int ret; - - /* because printing a tab to debug every minute gets old */ - if(strcmp(data, "\t")) - purple_debug(PURPLE_DEBUG_MISC, "jabber", "Sending%s: %s\n", - js->gsc ? " (ssl)" : "", data); - - /* If we've got a security layer, we need to encode the data, - * splitting it on the maximum buffer length negotiated */ - - purple_signal_emit(my_protocol, "jabber-sending-text", js->gc, &data); - if (data == NULL) - return; - -#ifdef HAVE_CYRUS_SASL - if (js->sasl_maxbuf>0) { - int pos; - - if (!js->gsc && js->fd<0) - return; - pos = 0; - if (len == -1) - len = strlen(data); - while (pos < len) { - int towrite; - const char *out; - unsigned olen; - - if ((len - pos) < js->sasl_maxbuf) - towrite = len - pos; - else - towrite = js->sasl_maxbuf; - - sasl_encode(js->sasl, &data[pos], towrite, &out, &olen); - pos += towrite; - - if (js->writeh == 0) - ret = jabber_do_send(js, out, olen); - else { - ret = -1; - errno = EAGAIN; - } - - if (ret < 0 && errno != EAGAIN) - purple_connection_error_reason (js->gc, - PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Write error")); - else if (ret < olen) { - if (ret < 0) - ret = 0; - if (js->writeh == 0) - js->writeh = purple_input_add( - js->gsc ? js->gsc->fd : js->fd, - PURPLE_INPUT_WRITE, - jabber_send_cb, js); - purple_circ_buffer_append(js->write_buffer, - out + ret, olen - ret); - } - } - return; - } -#endif + gboolean success = TRUE; if (len == -1) len = strlen(data); @@ -348,11 +288,12 @@ errno = EAGAIN; } - if (ret < 0 && errno != EAGAIN) + if (ret < 0 && errno != EAGAIN) { purple_connection_error_reason (js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Write error")); - else if (ret < len) { + success = FALSE; + } else if (ret < len) { if (ret < 0) ret = 0; if (js->writeh == 0) @@ -362,7 +303,53 @@ purple_circ_buffer_append(js->write_buffer, data + ret, len - ret); } - return; + + return success; +} + +void jabber_send_raw(JabberStream *js, const char *data, int len) +{ + + /* because printing a tab to debug every minute gets old */ + if(strcmp(data, "\t")) + purple_debug(PURPLE_DEBUG_MISC, "jabber", "Sending%s: %s\n", + js->gsc ? " (ssl)" : "", data); + + /* If we've got a security layer, we need to encode the data, + * splitting it on the maximum buffer length negotiated */ + + purple_signal_emit(my_protocol, "jabber-sending-text", js->gc, &data); + if (data == NULL) + return; + +#ifdef HAVE_CYRUS_SASL + if (js->sasl_maxbuf>0) { + int pos = 0; + + if (!js->gsc && js->fd<0) + return; + + if (len == -1) + len = strlen(data); + + while (pos < len) { + int towrite; + const char *out; + unsigned olen; + + towrite = MIN((len - pos), js->sasl_maxbuf); + + sasl_encode(js->sasl, &data[pos], towrite, &out, &olen); + pos += towrite; + + if (!do_jabber_send_raw(js, out, olen)) + break; + } + return; + } +#endif + + do_jabber_send_raw(js, data, len); } int jabber_prpl_send_raw(PurpleConnection *gc, const char *buf, int len) @@ -388,9 +375,9 @@ g_free(txt); } -static void jabber_pong_cb(JabberStream *js, xmlnode *packet, gpointer timeout) +static void jabber_pong_cb(JabberStream *js, xmlnode *packet, gpointer unused) { - purple_timeout_remove(GPOINTER_TO_INT(timeout)); + purple_timeout_remove(js->keepalive_timeout); js->keepalive_timeout = -1; } @@ -414,7 +401,7 @@ xmlnode_set_namespace(ping, "urn:xmpp:ping"); js->keepalive_timeout = purple_timeout_add_seconds(120, (GSourceFunc)(jabber_pong_timeout), gc); - jabber_iq_set_callback(iq, jabber_pong_cb, GINT_TO_POINTER(js->keepalive_timeout)); + jabber_iq_set_callback(iq, jabber_pong_cb, NULL); jabber_iq_send(iq); } } diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Wed Jun 18 03:27:05 2008 +0000 @@ -76,9 +76,9 @@ jabber_roster_remove_buddy, /* remove_buddy */ NULL, /* remove_buddies */ NULL, /* add_permit */ - jabber_google_roster_add_deny, /* add_deny */ + jabber_google_roster_add_deny, /* add_deny */ NULL, /* rem_permit */ - jabber_google_roster_rem_deny, /* rem_deny */ + jabber_google_roster_rem_deny, /* rem_deny */ NULL, /* set_permit_deny */ jabber_chat_join, /* join_chat */ NULL, /* reject_chat */ @@ -105,7 +105,7 @@ jabber_roomlist_get_list, /* roomlist_get_list */ jabber_roomlist_cancel, /* roomlist_cancel */ NULL, /* roomlist_expand_category */ - jabber_si_xfer_can_receive_file,/* can_receive_file */ + NULL, /* can_receive_file */ jabber_si_xfer_send, /* send_file */ jabber_si_new_xfer, /* new_xfer */ jabber_offline_message, /* offline_message */ diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/jabber/pep.h --- a/libpurple/protocols/jabber/pep.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/jabber/pep.h Wed Jun 18 03:27:05 2008 +0000 @@ -57,7 +57,7 @@ * @parameter id The item id of the requested item (may be NULL) * @parameter cb The callback to be used when this item is received * - * The items element passed to the callback will be NULL if any error occured (like a permission error, node doesn't exist etc.) + * The items element passed to the callback will be NULL if any error occurred (like a permission error, node doesn't exist etc.) */ void jabber_pep_request_item(JabberStream *js, const char *to, const char *node, const char *id, JabberPEPHandler cb); diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/jabber/si.c --- a/libpurple/protocols/jabber/si.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/jabber/si.c Wed Jun 18 03:27:05 2008 +0000 @@ -623,7 +623,7 @@ return; else if(acceptfd == -1) { purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno)); - /* TODO: This should cancel the ft */ + /* Don't cancel the ft - allow it to fall to the next streamhost.*/ return; } @@ -659,8 +659,11 @@ jsx = xfer->data; - if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) + if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) { + if (type && !strcmp(type, "error")) + purple_xfer_cancel_remote(xfer); return; + } if(!(from = xmlnode_get_attrib(packet, "from"))) return; @@ -718,14 +721,17 @@ JabberSIXfer *jsx; JabberIq *iq; xmlnode *query, *streamhost; - char *jid, port[6]; - const char *local_ip, *public_ip, *ft_proxies; + const char *ft_proxies; + char port[6]; GList *tmp; JabberBytestreamsStreamhost *sh, *sh2; + int streamhost_count = 0; jsx = xfer->data; jsx->listen_data = NULL; + /* I'm not sure under which conditions this can happen + * (it seems like it shouldn't be possible */ if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) { purple_xfer_unref(xfer); return; @@ -733,13 +739,6 @@ purple_xfer_unref(xfer); - if (sock < 0) { - purple_xfer_cancel_local(xfer); - return; - } - - jsx->local_streamhost_fd = sock; - iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, "http://jabber.org/protocol/bytestreams"); xmlnode_set_attrib(iq->node, "to", xfer->who); @@ -747,41 +746,45 @@ xmlnode_set_attrib(query, "sid", jsx->stream_id); - jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, + /* If we successfully started listening locally */ + if (sock >= 0) { + gchar *jid; + const char *local_ip, *public_ip; + + jsx->local_streamhost_fd = sock; + + jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource); - xfer->local_port = purple_network_get_port_from_fd(sock); - g_snprintf(port, sizeof(port), "%hu", xfer->local_port); - - /* TODO: Should there be an option to not use the local host as a ft proxy? - * (to prevent revealing IP address, etc.) */ + xfer->local_port = purple_network_get_port_from_fd(sock); + g_snprintf(port, sizeof(port), "%hu", xfer->local_port); - /* Include the localhost's IP (for in-network transfers) */ - local_ip = purple_network_get_local_system_ip(jsx->js->fd); - if (strcmp(local_ip, "0.0.0.0") != 0) - { - streamhost = xmlnode_new_child(query, "streamhost"); - xmlnode_set_attrib(streamhost, "jid", jid); - xmlnode_set_attrib(streamhost, "host", local_ip); - xmlnode_set_attrib(streamhost, "port", port); + /* Include the localhost's IP (for in-network transfers) */ + local_ip = purple_network_get_local_system_ip(jsx->js->fd); + if (strcmp(local_ip, "0.0.0.0") != 0) { + streamhost_count++; + streamhost = xmlnode_new_child(query, "streamhost"); + xmlnode_set_attrib(streamhost, "jid", jid); + xmlnode_set_attrib(streamhost, "host", local_ip); + xmlnode_set_attrib(streamhost, "port", port); + } + + /* Include the public IP (assuming that there is a port mapped somehow) */ + public_ip = purple_network_get_my_ip(jsx->js->fd); + if (strcmp(public_ip, local_ip) != 0 && strcmp(public_ip, "0.0.0.0") != 0) { + streamhost_count++; + streamhost = xmlnode_new_child(query, "streamhost"); + xmlnode_set_attrib(streamhost, "jid", jid); + xmlnode_set_attrib(streamhost, "host", public_ip); + xmlnode_set_attrib(streamhost, "port", port); + } + + g_free(jid); + + /* The listener for the local proxy */ + xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ, + jabber_si_xfer_bytestreams_send_connected_cb, xfer); } - /* Include the public IP (assuming that there is a port mapped somehow) */ - /* TODO: Check that it isn't the same as above and is a valid IP */ - public_ip = purple_network_get_my_ip(jsx->js->fd); - if (strcmp(public_ip, local_ip) != 0) - { - streamhost = xmlnode_new_child(query, "streamhost"); - xmlnode_set_attrib(streamhost, "jid", jid); - xmlnode_set_attrib(streamhost, "host", public_ip); - xmlnode_set_attrib(streamhost, "port", port); - } - - g_free(jid); - - /* The listener for the local proxy */ - xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ, - jabber_si_xfer_bytestreams_send_connected_cb, xfer); - /* insert proxies here */ ft_proxies = purple_account_get_string(xfer->account, "ft_proxies", NULL); if (ft_proxies) { @@ -806,11 +809,12 @@ g_snprintf(port, sizeof(port), "%hu", portnum); - purple_debug_info("jabber", "jabber_si_xfer_bytestreams_listen_cb() will be looking at jsx %p: jsx->streamhosts %p and ft_proxy_list[%i] %p", + purple_debug_info("jabber", "jabber_si_xfer_bytestreams_listen_cb() will be looking at jsx %p: jsx->streamhosts %p and ft_proxy_list[%i] %p\n", jsx, jsx->streamhosts, i, ft_proxy_list[i]); if(g_list_find_custom(jsx->streamhosts, ft_proxy_list[i], jabber_si_compare_jid) != NULL) continue; + streamhost_count++; streamhost = xmlnode_new_child(query, "streamhost"); xmlnode_set_attrib(streamhost, "jid", ft_proxy_list[i]); xmlnode_set_attrib(streamhost, "host", ft_proxy_list[i]); @@ -840,6 +844,7 @@ if(g_list_find_custom(jsx->streamhosts, sh->jid, jabber_si_compare_jid) != NULL) continue; + streamhost_count++; streamhost = xmlnode_new_child(query, "streamhost"); xmlnode_set_attrib(streamhost, "jid", sh->jid); xmlnode_set_attrib(streamhost, "host", sh->host); @@ -855,6 +860,14 @@ jsx->streamhosts = g_list_prepend(jsx->streamhosts, sh2); } + /* We have no way of transferring, cancel the transfer */ + if (streamhost_count == 0) { + jabber_iq_free(iq); + /* We should probably notify the target, but this really shouldn't ever happen */ + purple_xfer_cancel_local(xfer); + return; + } + jabber_iq_set_callback(iq, jabber_si_connect_proxy_cb, xfer); jabber_iq_send(iq); @@ -869,13 +882,14 @@ purple_xfer_ref(xfer); jsx = xfer->data; + + /* TODO: Should there be an option to not use the local host as a ft proxy? + * (to prevent revealing IP address, etc.) */ jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM, jabber_si_xfer_bytestreams_listen_cb, xfer); if (jsx->listen_data == NULL) { - purple_xfer_unref(xfer); - /* XXX: couldn't open a port, we're fscked */ - purple_xfer_cancel_local(xfer); - return; + /* We couldn't open a local port. Perhaps we can use a proxy. */ + jabber_si_xfer_bytestreams_listen_cb(-1, xfer); } } @@ -1205,13 +1219,6 @@ return xfer; } -gboolean jabber_si_xfer_can_receive_file(PurpleConnection *conn, const char *who) -{ - JabberStream *js = conn->proto_data; - - return purple_find_buddy(conn->account, who) && jabber_buddy_find(js, who, FALSE); -} - void jabber_si_xfer_send(PurpleConnection *gc, const char *who, const char *file) { JabberStream *js; @@ -1220,9 +1227,6 @@ js = gc->proto_data; - if (!jabber_si_xfer_can_receive_file(gc, who)) - return; - xfer = jabber_si_new_xfer(gc, who); if (file) diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/jabber/si.h --- a/libpurple/protocols/jabber/si.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/jabber/si.h Wed Jun 18 03:27:05 2008 +0000 @@ -28,7 +28,6 @@ void jabber_bytestreams_parse(JabberStream *js, xmlnode *packet); void jabber_si_parse(JabberStream *js, xmlnode *packet); -gboolean jabber_si_xfer_can_receive_file(PurpleConnection *conn, const char *who); PurpleXfer *jabber_si_new_xfer(PurpleConnection *gc, const char *who); void jabber_si_xfer_send(PurpleConnection *gc, const char *who, const char *file); diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/myspace/user.c Wed Jun 18 03:27:05 2008 +0000 @@ -635,7 +635,7 @@ if (!body) { purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username); purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - "An error occured while trying to set the username.\n" + "An error occurred while trying to set the username.\n" "Please try again, or visit http://editprofile.myspace.com/index.cfm?" "fuseaction=profile.username to set your username."); return; @@ -778,7 +778,7 @@ uid = msim_msg_get_integer(userinfo, "uid"); lid = msim_msg_get_integer(userinfo, "lid"); body = msim_msg_get_dictionary(userinfo, "body"); - errmsg = g_strdup("An error occured while trying to set the username.\n" + errmsg = g_strdup("An error occurred while trying to set the username.\n" "Please try again, or visit http://editprofile.myspace.com/index.cfm?" "fuseaction=profile.username to set your username."); diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.c Wed Jun 18 03:27:05 2008 +0000 @@ -1977,7 +1977,17 @@ } else { - purple_prpl_got_user_status(account, info->sn, status_id, NULL); + PurpleBuddy *b = purple_find_buddy(account, info->sn); + PurplePresence *presence = purple_buddy_get_presence(b); + PurpleStatus *old_status = purple_presence_get_active_status(presence); + PurpleStatus *new_status = purple_presence_get_status(presence, status_id); + + /* If our status_id would change with this update, pass it to the core. + * However, if our status_id would not change, do nothing, as we would clear out any existing + * attributes on the status prematurely. purple_got_infoblock() will update the message as needed. + */ + if (old_status != new_status) + purple_prpl_got_user_status(account, info->sn, status_id, NULL); } /* Login time stuff */ diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/qq/send_file.c --- a/libpurple/protocols/qq/send_file.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/qq/send_file.c Wed Jun 18 03:27:05 2008 +0000 @@ -155,7 +155,7 @@ gint size; /* FIXME: It seems that the transfer never use a packet * larger than 1500 bytes, so if it happened to be a - * larger packet, either error occured or protocol should + * larger packet, either error occurred or protocol should * be modified */ ft_info *info; diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/protocols/simple/simple.c --- a/libpurple/protocols/simple/simple.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/protocols/simple/simple.c Wed Jun 18 03:27:05 2008 +0000 @@ -1898,7 +1898,7 @@ PurpleConnection *gc; struct simple_account_data *sip; gchar **userserver; - gchar *hosttoconnect; + const gchar *hosttoconnect; const char *username = purple_account_get_username(account); gc = purple_account_get_connection(account); @@ -1934,14 +1934,13 @@ sip->status = g_strdup("available"); if(!purple_account_get_bool(account, "useproxy", FALSE)) { - hosttoconnect = g_strdup(sip->servername); + hosttoconnect = sip->servername; } else { - hosttoconnect = g_strdup(purple_account_get_string(account, "proxy", sip->servername)); + hosttoconnect = purple_account_get_string(account, "proxy", sip->servername); } sip->srv_query_data = purple_srv_resolve("sip", sip->udp ? "udp" : "tcp", hosttoconnect, srvresolved, sip); - g_free(hosttoconnect); } static void simple_close(PurpleConnection *gc) diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/prpl.h --- a/libpurple/prpl.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/prpl.h Wed Jun 18 03:27:05 2008 +0000 @@ -31,6 +31,7 @@ #define _PURPLE_PRPL_H_ typedef struct _PurplePluginProtocolInfo PurplePluginProtocolInfo; +/** @copydoc _PurpleAttentionType */ typedef struct _PurpleAttentionType PurpleAttentionType; /**************************************************************************/ @@ -99,6 +100,9 @@ gboolean secret; }; +/** Represents "nudges" and "buzzes" that you may send to a buddy to attract + * their attention (or vice-versa). + */ struct _PurpleAttentionType { const char *name; /**< Shown in GUI elements */ diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/roomlist.h --- a/libpurple/roomlist.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/roomlist.h Wed Jun 18 03:27:05 2008 +0000 @@ -30,6 +30,7 @@ typedef struct _PurpleRoomlist PurpleRoomlist; typedef struct _PurpleRoomlistRoom PurpleRoomlistRoom; typedef struct _PurpleRoomlistField PurpleRoomlistField; +/** @copydoc _PurpleRoomlistUiOps */ typedef struct _PurpleRoomlistUiOps PurpleRoomlistUiOps; /** diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/sound.h --- a/libpurple/sound.h Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/sound.h Wed Jun 18 03:27:05 2008 +0000 @@ -55,6 +55,9 @@ } PurpleSoundEventID; +/** Operations used by the core to request that particular sound files, or the + * sound associated with a particular event, should be played. + */ typedef struct _PurpleSoundUiOps { void (*init)(void); diff -r 54aaea893a89 -r 3f765f7e79d4 libpurple/util.c --- a/libpurple/util.c Sat Jun 14 02:03:26 2008 +0000 +++ b/libpurple/util.c Wed Jun 18 03:27:05 2008 +0000 @@ -832,6 +832,11 @@ if (offset_positive) tzoff *= -1; } + else if ((*c == 'Z') && (c = c + 1)) + { + /* 'Z' = Zulu = UTC */ + tzoff = 0; + } else if (utc) { static struct tm tmptm; diff -r 54aaea893a89 -r 3f765f7e79d4 pidgin/plugins/cap/cap.c --- a/pidgin/plugins/cap/cap.c Sat Jun 14 02:03:26 2008 +0000 +++ b/pidgin/plugins/cap/cap.c Wed Jun 18 03:27:05 2008 +0000 @@ -333,7 +333,7 @@ static gboolean max_message_difference_cb(gpointer data) { CapStatistics *stats = data; - purple_debug_info("cap", "Max Message Difference timeout occured\n"); + purple_debug_info("cap", "Max Message Difference timeout occurred\n"); insert_cap_failure(stats); stats->timeout_source_id = 0; return FALSE; diff -r 54aaea893a89 -r 3f765f7e79d4 po/en_GB.po --- a/po/en_GB.po Sat Jun 14 02:03:26 2008 +0000 +++ b/po/en_GB.po Wed Jun 18 03:27:05 2008 +0000 @@ -2911,7 +2911,7 @@ msgstr "Your current password is different from the one that you specified." msgid "Unable to change password. Error occurred.\n" -msgstr "Unable to change password. An error occured.\n" +msgstr "Unable to change password. An error occurred.\n" msgid "Change password for the Gadu-Gadu account" msgstr "Change password for the Gadu-Gadu account" @@ -5270,7 +5270,7 @@ msgstr "Message could not be sent because the user is offline:" msgid "Message could not be sent because a connection error occurred:" -msgstr "Message could not be sent because a connection error occured:" +msgstr "Message could not be sent because a connection error occurred:" msgid "Message could not be sent because we are sending too quickly:" msgstr "Message could not be sent because we are sending too quickly:"