Tue, 12 Jan 2010 14:22:02 +0000
propagate from branch 'im.pidgin.pidgin' (head 1e232732a9f31f155cd1b160e3af9723b583c040)
to branch 'im.pidgin.pidgin.openq' (head ee4ea6de47e3fd941655a6445232467e2566b122)
| libpurple/protocols/jabber/JEPS | file | annotate | diff | comparison | revisions | |
| libpurple/protocols/jabber/XEPS | file | annotate | diff | comparison | revisions | |
| libpurple/protocols/yahoo/libymsg.c | file | annotate | diff | comparison | revisions | |
| libpurple/protocols/yahoo/libymsg.h | file | annotate | diff | comparison | revisions |
--- a/AUTHORS Wed Sep 23 14:48:57 2009 +0000 +++ b/AUTHORS Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ Casey Harkins - Developer Gary 'grim' Kramlich - Developer Richard 'rlaager' Laager - Developer +Sulabh 'sulabh_m' Mahajan - Developer Richard 'wabz' Nelson - Developer Christopher 'siege' O'Brien - Developer Bartosz Oler - Developer
--- a/COPYRIGHT Wed Sep 23 14:48:57 2009 +0000 +++ b/COPYRIGHT Tue Jan 12 14:22:02 2010 +0000 @@ -154,6 +154,7 @@ David Fiander Rob Flynn <gaim@robflynn.com> Rob Foehl (rwf) +Chris Foote Alan Ford Nathan Fredrickson Chris J. Friesen @@ -268,6 +269,7 @@ Ambrose C. Li Nicolas Lichtmaier Wesley Lin +Shaun Lindsay Artem Litvinovich Josh Littlefield Daniel Ljungborg @@ -275,6 +277,8 @@ Lokheed Norberto Lopes Shlomi Loubaton +Pieter Loubser +Brian Lu Uli Luckas Matthew Luckie Marcus Lundblad @@ -317,6 +321,7 @@ Sergio Moretto Andrei Mozzhuhin Christian Muise +MXit Lifestyle (Pty) Ltd. Richard Nelson Dennis Nezic Matthew A. Nicholson @@ -405,11 +410,10 @@ Carsten Schaar Toby Schaffer Jonathan Schleifer <js-pidgin@webkeks.org> -Matteo Settenvini -Colin Seymour Luke Schierer Ralph Schmieder David Schmitt +Heiko Schmitt Mark Schneider Evan Schoenberg Gabriel Schulhof @@ -419,6 +423,8 @@ Peter Seebach Don Seiler Leonardo Serra +Matteo Settenvini +Colin Seymour Jim Seymour Javeed Shaikh Joe Shaw @@ -494,6 +500,7 @@ James Vega David Vermeille Sid Vicious +Andrew Victor Jorge VillaseƱor (Masca) Bjoern Voigt Wan Hing Wah
--- a/ChangeLog Wed Sep 23 14:48:57 2009 +0000 +++ b/ChangeLog Tue Jan 12 14:22:02 2010 +0000 @@ -1,12 +1,158 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.6.3 (??/??/20??): +version 2.6.6 (??/??/20??): + Gadu-Gadu: + * Fix display of avatars after a server-side change. (Krzysztof + Klinikowski) + + MSN: + * File transfer requests will no longer cause a crash if you delete the + file before the other side accepts. + * Recieved files will no longer hold an extra lock after completion, + meaning they can be moved or deleted without complaints from your OS. + * Buddies who sign in from a second location will no longer cause an + unnecessary chat window to open. + * Support setting an animated GIF as a buddy icon. + XMPP: - * Fix a crash when attempting to validate an invalid JID. + * Added support for the SCRAM-SHA-1 SASL mechanism. This is only + available when built without Cyrus SASL support. + * When getting info on a domain-only (server) JID, show uptime + (when given by the result of the "last query") and don't show status as + offline. + +version 2.6.5 (01/08/2010): + libpurple: + * TLS certificates are actually stored to the local cache once again + (accepting a name mismatch on a certificate should now be remembered) + + General: + * Build-time fixes for Solaris. (Paul Townsend) + + AIM and ICQ: + * Messages from some mobile clients are no longer displayed as + Chinese characters (broken in 2.6.4) + + MSN: + * Fix an issue allowing a remote user to download arbitrary files from + a libpurple client. (CVE-2010-0013) + + XMPP: + * Do not crash when attempting to register for a new account on Windows. + * Fix file transfer with clients that do not support Entity Capabilities + (e.g. Spark) + +version 2.6.4 (11/29/2009): + libpurple: + * Actually emit the hold signal for media calls. + * Fix building the GnuTLS plugin with older versions of GnuTLS. + * Fix DNS TXT query resolution. + * Don't send Proxy-Authorization headers to HTTP proxy servers until we've + received a "407 Proxy Authentication Required" response from the server. + (thecrux) + * Added "MXit" protocol plugin, supported and maintained by the MXit folks + themselves (MXit Lifestyle (Pty) Ltd.) General: * New 'plugins' sub-command to 'debug' command (i.e. '/debug plugins') to announce the list of loaded plugins (in both Finch and Pidgin). + * Always rejoin open chats after an account reconnects. + + AIM and ICQ: + * Better rate limit calculations and other improvements. (Aman Gupta) + * More detailed error messages when messages fail to send. (Aman Gupta) + * The simultaneous login account option is respected when using + the clientLogin authentication method. + * Fix offline message retrieval (broken in 2.6.3) + * Fix handling of markup on some messages (broken in 2.6.2) + * Fix SSL when clientLogin is enabled. + * Fix sending and receiving Unicode characters in a Direct IM + + MSN: + * Don't forget display names for buddies. + * Fix a random crash that might occur when idle. + * Fix more FQY 240 connection errors. + * Fix a crash that could occur when adding a buddy. + * Fix an occasional crash when sending message to an offline user. + * Fix a random crash that might occur when idle. + * Fix a crash when logging in with some long non-ASCII passwords. + (Shaun Lindsay) + * Cache our own friendly name as the server no longer does that for + us. Users of older versions may need to re-set their friendly name + as it has probably been reset. + + XMPP: + * Users connecting to Google Talk now have an "Initiate Chat" context menu + option for their buddies. (Eion Robb) + * Fix a crash when attempting to validate an invalid JID. + * Resolve an issue when connecting to iChat Server when no resource + is specified. + * Try to automatically find a STUN server by using an SRV lookup on the + account's domain, and use that for voice and video if found and the user + didn't set one manually in prefs. + * Fix a crash when adding a buddy without an '@'. + * Don't show the option to send a file to a buddy if we know for certain + they don't support any file transfer method supported by libpurple. + * Keep the avatar on the server if one is not set locally. + + Yahoo: + * Fix sending /buzz. + * Fix blocking behavior for federated (MSN/OCS/Sametime) service users. + (Jason Cohen) + * Add support for adding OCS and Sametime buddies. OCS users are added + as "ocs/user@domain.tld" and Sametime users are added as + "ibm/sametime_id". (Jason Cohen) + + Finch: + * The TinyURL plugin now creates shorter URLs for long non-conversation + URLs, e.g. URLs to open Inbox in Yahoo/MSN protocols, or the Yahoo + Captcha when joining chat rooms. + * Fix displaying umlauts etc. in non-utf8 locale (fix in libgnt). + + Pidgin: + * The userlist in a multiuser chat can be styled via gtkrc by using the + widget name "pidgin_conv_userlist". (Heiko Schmitt) + * Add a hold button to the media window. + * Fix a bug where the conversation backlog stops scrolling in a very busy + chat room. + * In the Conversation "Send To" menu, offline buddies appear grayed + out (but are still selectable). Previously, only offline buddies on + accounts that do not support offline messaging appeared grayed out. + + Pidgin Preference and Preference Window Changes: + * Removed the "Use font from theme" and "Conversation Font" preferences + for everyone except Windows users. The font can be controlled from the + Pidgin GTK+ Theme Control plugin. + * Tabs in the Preferences window are now on the left side. + * The Browser tab is now visible for GNOME users. + * Added a Proxy tab shown no matter what environment Pidgin runs in. + * The Browser and Proxy tabs show appropriate GNOME-specific messages and + allow launching the correct applications to change the relevant GNOME + preferences if found. These were previously together on the Network + tab. + * Moved the port range spin buttons on the Network tab to be beside the + checkbox that enables/disables them. + * Reorganized preferences on the Status/Idle tab to have one less + "section." + * Reorganized preferences on the Sounds tab to have one less "section." + * Renamed Smiley Themes tab to Themes. + * Moved Buddy List Theme and Status Icon Theme selectors from Interface + tab to Themes tab. + * Moved Sound Theme selector from Sounds tab to Themes tab. + * Changed the Smiley Theme selector to be consistent with the other theme + selectors. + * Rearranged tabs such that Interface is first and all remaining tabs are + alphabetized in English. + +version 2.6.3 (10/16/2009): + General: + * Fix a crash when performing DNS queries on Unixes that use the + blocking DNS lookups. (Brian Lu) + + AIM and ICQ: + * Fix a crash when some clients send contacts in a format we don't + understand. + * Fix blocking and other privacy lists. (Thanks to AOL) version 2.6.2 (09/05/2009): libpurple:
--- a/ChangeLog.API Wed Sep 23 14:48:57 2009 +0000 +++ b/ChangeLog.API Tue Jan 12 14:22:02 2010 +0000 @@ -1,5 +1,29 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.6.6 (??/??/2010): + libpurple: + Changed: + * purple_xfer_cancel_local is now called instead of + purple_xfer_request_denied if an error is found when selecting + a file to send. Request denied is still used when a receive + request is not allowed. + Perl: + Changed: + * Corrected the package names for the PurpleProxyType and + PurpleLogReadFlags enums to have the correct number of colons + (from Purple::ProxyType::::<type> to Purple::ProxyType::<type> + and Purple::Log:ReadFlags::::<type> to + Purple::Log::ReadFlags::<type>) (Chris Foote) + +version 2.6.5 (01/08/2010): + No changes + +version 2.6.4 (11/29/2009): + No changes + +version 2.6.3 (10/16/2009): + No changes + version 2.6.2 (09/05/2009): Perl: Added:
--- a/ChangeLog.win32 Wed Sep 23 14:48:57 2009 +0000 +++ b/ChangeLog.win32 Tue Jan 12 14:22:02 2010 +0000 @@ -1,3 +1,17 @@ + +version 2.6.6 (??/??/2010): + * Installer translations for: Norwegian nynorsk + +version 2.6.5 (01/08/2010): + * No changes + +version 2.6.4 (11/29/2009): + * Register URL handlers for everything that Windows knows about. Still + use the HTTP "open" handler for security reasons. + +version 2.6.3 (10/16/2009): + * No changes + version 2.6.2 (09/05/2009): * No changes
--- a/NEWS Wed Sep 23 14:48:57 2009 +0000 +++ b/NEWS Tue Jan 12 14:22:02 2010 +0000 @@ -2,6 +2,36 @@ Our development blog is available at: http://planet.pidgin.im +2.6.6 (??/??/2010): + +2.6.5 (01/08/2010): + Paul: This release fixes a pretty serious bug in the MSN code, so we're + releasing this build a little earlier than planned with only major + bugs fixed. See the ChangeLog for details. Enjoy! + +2.6.4 (11/29/2009): + John: It's release time again. Lots of bug fixes this time around, as + well as a new protocol plugin developed and maintained by the MXit folks + folks. Elliott and I also did a ton of work on the Preferences window, + which will now hopefully fit on most people's small screens. Enjoy! + + Elliott: This release has been in the works for so long, I don't really + remember doing any work on it. But I do know the MSN servers gave us a + little bit of trouble this time around, forgetting people's friendly + names. Nothing too problematic, just a touch annoying. Also, we've got + a nice new Preferences dialog. You can thank John for that mostly, with + a couple of tweaks by me. + + Sadrul: A lot of little fixes for a lot of things! Among them, a fix + for a long standing issue with displaying unicode in non-utf8 locale in + finch. We also have a new prpl for MXit. This release is very very cool + altogether. Enjoy! + +2.6.3 (10/16/2009): + Mark: Someone reported a fairly serious bug in our AIM/ICQ code + so we're releasing a special "severe bug fix only" build. See the + ChangeLog for details. Enjoy! + 2.6.2 (09/05/2009): Mark: Woo boy it's been a busy two weeks. There was a lot of new code in 2.6.0, and with new code comes new bugs. The cadre of relentless
--- a/autogen.sh Wed Sep 23 14:48:57 2009 +0000 +++ b/autogen.sh Tue Jan 12 14:22:02 2010 +0000 @@ -83,7 +83,7 @@ OUTPUT=`mktemp autogen-XXXXXX` - printf "%s" "running ${CMD} ${@}... " + printf "running %s %s... " ${CMD} "$*" ${CMD} ${@} >${OUTPUT} 2>&1 if [ $? != 0 ] ; then @@ -99,9 +99,17 @@ fi } +cleanup () { + rm -f autogen-?????? + echo + exit 2 +} + ############################################################################### # We really start here, yes, very sneaky! ############################################################################### +trap cleanup 2 + FIGLET=`which figlet 2> /dev/null` if [ x"${FIGLET}" != x"" ] ; then ${FIGLET} -f small ${PACKAGE} @@ -143,7 +151,7 @@ run_or_die ${INTLTOOLIZE} ${INTLTOOLIZE_FLAGS:-"-c -f --automake"} # This call to sed is needed to work around an annoying bug in intltool 0.40.6 # See http://developer.pidgin.im/ticket/9520 for details -run_or_die ${SED} "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" -i po/Makefile.in.in +run_or_die ${SED} -i.bak -e "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" po/Makefile.in.in run_or_die ${ACLOCAL} ${ACLOCAL_FLAGS:-"-I m4macros"} run_or_die ${AUTOHEADER} ${AUTOHEADER_FLAGS} run_or_die ${AUTOMAKE} ${AUTOMAKE_FLAGS:-"-a -c --gnu"}
--- a/configure.ac Wed Sep 23 14:48:57 2009 +0000 +++ b/configure.ac Tue Jan 12 14:22:02 2010 +0000 @@ -46,7 +46,7 @@ m4_define([purple_lt_current], [6]) m4_define([purple_major_version], [2]) m4_define([purple_minor_version], [6]) -m4_define([purple_micro_version], [3]) +m4_define([purple_micro_version], [6]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) @@ -55,7 +55,7 @@ m4_define([gnt_lt_current], [6]) m4_define([gnt_major_version], [2]) m4_define([gnt_minor_version], [6]) -m4_define([gnt_micro_version], [3]) +m4_define([gnt_micro_version], [6]) m4_define([gnt_version_suffix], [devel]) m4_define([gnt_version], [gnt_major_version.gnt_minor_version.gnt_micro_version]) @@ -144,7 +144,7 @@ ;; esac -ALL_LINGUAS="af am ar az be@latin bg bn bs ca ca@valencia cs da de dz el en_AU en_CA en_GB eo es et eu fa fi fr ga gl gu he hi hu hy id it ja ka km kn ko ku lo lt mk mn my_MM nb ne nl nn oc pa pl pt_BR pt ps ro ru si sk sl sq sr sr@latin sv sw ta te th tr uk ur vi xh zh_CN zh_HK zh_TW" +ALL_LINGUAS="af am ar az be@latin bg bn bs ca ca@valencia cs da de dz el en_AU en_CA en_GB eo es et eu fa fi fr ga gl gu he hi hu hy id it ja ka km kn ko ku lo lt mk mn ms_MY my_MM nb ne nl nn oc pa pl pt_BR pt ps ro ru si sk sl sq sr sr@latin sv sw ta te th tr uk ur vi xh zh_CN zh_HK zh_TW" AM_GLIB_GNU_GETTEXT dnl If we don't have msgfmt, then po/ is going to fail -- ensure that @@ -812,6 +812,10 @@ fi AM_CONDITIONAL(USE_VV, test "x$enable_gstreamer" != "xno" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farsight" != "xno") +dnl ####################################################################### +dnl # Check for Internationalized Domain Name support +dnl ####################################################################### + AC_ARG_ENABLE(idn, [AC_HELP_STRING([--disable-idn], [compile without IDN support])], [enable_idn="$enableval" force_idn=$enableval], [enable_idn="yes" force_idn=no]) @@ -1078,7 +1082,7 @@ fi if test "x$STATIC_PRPLS" = "xall" ; then - STATIC_PRPLS="bonjour gg irc jabber msn myspace novell oscar qq sametime silc simple yahoo zephyr" + STATIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes" ; then STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'` @@ -1135,6 +1139,7 @@ msn) static_msn=yes ;; msnp9) static_msn=yes ;; myspace) static_myspace=yes ;; + mxit) static_mxit=yes ;; novell) static_novell=yes ;; oscar) static_oscar=yes ;; aim) static_oscar=yes ;; @@ -1155,6 +1160,7 @@ AM_CONDITIONAL(STATIC_JABBER, test "x$static_jabber" = "xyes") AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes") AM_CONDITIONAL(STATIC_MYSPACE, test "x$static_myspace" = "xyes") +AM_CONDITIONAL(STATIC_MXIT, test "x$static_mxit" = "xyes") AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes") AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes") AM_CONDITIONAL(STATIC_QQ, test "x$static_qq" = "xyes") @@ -1169,7 +1175,7 @@ AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`]) if test "x$DYNAMIC_PRPLS" = "xall" ; then - DYNAMIC_PRPLS="bonjour gg irc jabber msn myspace novell oscar qq sametime silc simple yahoo zephyr" + DYNAMIC_PRPLS="bonjour gg irc jabber msn myspace mxit novell oscar qq sametime silc simple yahoo zephyr" fi if test "x$have_meanwhile" != "xyes"; then DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'` @@ -1196,6 +1202,7 @@ msn) dynamic_msn=yes ;; msnp9) dynamic_msn=yes ;; myspace) dynamic_myspace=yes ;; + mxit) dynamic_mxit=yes ;; novell) dynamic_novell=yes ;; null) dynamic_null=yes ;; oscar) dynamic_oscar=yes ;; @@ -1467,7 +1474,7 @@ AC_CHECK_LIB(pthread, pthread_create, ) AC_CHECK_LIB(util, openpty, ) AC_CHECK_LIB(db, dbopen, ) - PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config" + PY_LIBS="-L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config -lpython$PY_VERSION" PY_CFLAGS="-I$PY_PREFIX/include/python$PY_VERSION" AC_DEFINE(USE_PYTHON, [1], [Define if python headers are available.]) AC_MSG_RESULT(ok) @@ -1773,6 +1780,23 @@ LIBS="$LIBS_save" fi +if test "x$enable_gnutls" = "xyes"; then + AC_MSG_CHECKING(for GNUTLS_CERT_INSECURE_ALGORITHM) + LIBS_save="$LIBS" + LIBS="$LIBS $GNUTLS_LIBS" + CPPFLAGS_save="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GNUTLS_CFLAGS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], + [[unsigned int verify = GNUTLS_CERT_INSECURE_ALGORITHM;]])], + [AC_DEFINE([HAVE_GNUTLS_CERT_INSECURE_ALGORITHM], 1, + [Define if your gnutls has the GNUTLS_CERT_INSECURE_ALGORITHM flag]) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no)]) + CPPFLAGS="$CPPFLAGS_save" + LIBS="$LIBS_save" +fi + + AM_CONDITIONAL(USE_GNUTLS, test "x$enable_gnutls" = "xyes") @@ -2247,11 +2271,15 @@ AC_ARG_ENABLE(cyrus-sasl, AC_HELP_STRING([--enable-cyrus-sasl], [enable Cyrus SASL support for jabberd]), enable_cyrus_sasl=$enableval, enable_cyrus_sasl=no) if test "x$enable_cyrus_sasl" = "xyes" ; then AC_CHECK_LIB(sasl2, sasl_client_init, [ + AM_CONDITIONAL(USE_CYRUS_SASL, true) AC_DEFINE(HAVE_CYRUS_SASL, [1], [Define to 1 if Cyrus SASL is present]) SASL_LIBS=-"lsasl2" ], [ + AM_CONDITIONAL(USE_CYRUS_SASL, false) AC_ERROR(Cyrus SASL library not found) ]) +else + AM_CONDITIONAL(USE_CYRUS_SASL, false) fi dnl ####################################################################### @@ -2512,6 +2540,7 @@ libpurple/protocols/msn/Makefile libpurple/protocols/msnp9/Makefile libpurple/protocols/myspace/Makefile + libpurple/protocols/mxit/Makefile libpurple/protocols/novell/Makefile libpurple/protocols/null/Makefile libpurple/protocols/oscar/Makefile
--- a/doc/finch.1.in Wed Sep 23 14:48:57 2009 +0000 +++ b/doc/finch.1.in Tue Jan 12 14:22:02 2010 +0000 @@ -114,7 +114,7 @@ .B Ctrl \+ o \fR or \fB F10 Bring up the menu (if there is one) for a window. .TP -.B F11 +.B F11 \fR or \fB Ctrl \+ x Popup the context menu (if there is one) for the selected widget. .TP .B Alt \+ /
--- a/doc/pidgin.1.in Wed Sep 23 14:48:57 2009 +0000 +++ b/doc/pidgin.1.in Tue Jan 12 14:22:02 2010 +0000 @@ -628,6 +628,8 @@ .br Richard 'rlaager' Laager (developer) <\fIrlaager@pidgin.im\fR> .br + Sulabh 'sulabh_m' Mahajan (developer) +.br Richard 'wabz' Nelson (developer) .br Christopher 'siege' O'Brien (developer)
--- a/finch/finch.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/finch.c Tue Jan 12 14:22:02 2010 +0000 @@ -19,8 +19,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include "account.h" #include "conversation.h"
--- a/finch/gntaccount.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntaccount.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -36,7 +38,6 @@ #include <gntwindow.h> #include "finch.h" -#include <internal.h> #include <account.h> #include <accountopt.h> @@ -166,8 +167,7 @@ /* Alias */ value = gnt_entry_get_text(GNT_ENTRY(dialog->alias)); - if (value && *value) - purple_account_set_alias(account, value); + purple_account_set_alias(account, value); /* Remember password and password */ purple_account_set_remember_password(account,
--- a/finch/gntblist.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntblist.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include <account.h> #include <blist.h> @@ -1119,6 +1119,8 @@ PurpleMenuAction *act = (PurpleMenuAction *) list->data; act->data = node; gnt_append_menu_action(menu, act, NULL); + g_signal_connect_swapped(G_OBJECT(menu), "destroy", + G_CALLBACK(purple_menu_action_free), act); } } @@ -1368,6 +1370,8 @@ iter; iter = g_list_delete_link(iter, iter)) { gnt_append_menu_action(menu, iter->data, NULL); + g_signal_connect_swapped(G_OBJECT(menu), "destroy", + G_CALLBACK(purple_menu_action_free), iter->data); } } @@ -1940,7 +1944,7 @@ } else if (!gnt_tree_is_searching(GNT_TREE(ggblist->tree))) { if (strcmp(text, "t") == 0) { finch_blist_toggle_tag_buddy(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree))); - gnt_bindable_perform_action_named(GNT_BINDABLE(ggblist->tree), "move-down"); + gnt_bindable_perform_action_named(GNT_BINDABLE(ggblist->tree), "move-down", NULL); } else if (strcmp(text, "a") == 0) { finch_blist_place_tagged(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree))); } else
--- a/finch/gntcertmgr.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntcertmgr.c Tue Jan 12 14:22:02 2010 +0000 @@ -25,8 +25,8 @@ * */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include "certificate.h" #include "debug.h"
--- a/finch/gntconn.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntconn.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include "account.h" #include "core.h" @@ -107,7 +107,6 @@ { FinchAutoRecon *info; PurpleAccount *account = purple_connection_get_account(gc); - GList *list; if (!purple_connection_error_is_fatal(reason)) { info = g_hash_table_lookup(hash, account); @@ -144,21 +143,6 @@ g_free(secondary); purple_account_set_enabled(account, FINCH_UI, FALSE); } - - /* If we have any open chats, we probably want to rejoin when we get back online. */ - list = purple_get_chats(); - while (list) { - PurpleConversation *conv = list->data; - list = list->next; - if (purple_conversation_get_account(conv) != account || - purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) - continue; - purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); - purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " - "longer in this chat. You will be automatically rejoined in the chat when " - "the account reconnects."), - PURPLE_MESSAGE_SYSTEM, time(NULL)); - } } static void
--- a/finch/gntconv.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntconv.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,10 +23,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include <string.h> +#include <internal.h> #include "finch.h" -#include <internal.h> #include <cmds.h> #include <core.h> @@ -367,6 +366,28 @@ } } +static void +account_signing_off(PurpleConnection *gc) +{ + GList *list = purple_get_chats(); + PurpleAccount *account = purple_connection_get_account(gc); + + /* We are about to sign off. See which chats we are currently in, and mark + * them for rejoin on reconnect. */ + while (list) { + PurpleConversation *conv = list->data; + if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) && + purple_conversation_get_account(conv) == account) { + purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); + purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " + "longer in this chat. You will be automatically rejoined in the chat when " + "the account reconnects."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + } + list = list->next; + } +} + static gpointer finch_conv_get_handle(void) { @@ -642,8 +663,25 @@ create_conv_from_userlist(GntWidget *widget, FinchConv *fc) { PurpleAccount *account = purple_conversation_get_account(fc->active_conv); - char *name = gnt_tree_get_selection_data(GNT_TREE(widget)); - purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name); + PurpleConnection *gc = purple_account_get_connection(account); + PurplePluginProtocolInfo *prpl_info = NULL; + char *name, *realname; + + if (!gc) { + purple_conversation_write(fc->active_conv, NULL, _("You are not connected."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + return; + } + + name = gnt_tree_get_selection_data(GNT_TREE(widget)); + + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_cb_real_name)) + realname = prpl_info->get_cb_real_name(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(fc->active_conv)), name); + else + realname = NULL; + purple_conversation_new(PURPLE_CONV_TYPE_IM, account, realname ? realname : name); + g_free(realname); } static void @@ -1433,6 +1471,8 @@ PURPLE_CALLBACK(account_signed_on_off), NULL); purple_signal_connect(purple_connections_get_handle(), "signed-off", finch_conv_get_handle(), PURPLE_CALLBACK(account_signed_on_off), NULL); + purple_signal_connect(purple_connections_get_handle(), "signing-off", finch_conv_get_handle(), + PURPLE_CALLBACK(account_signing_off), NULL); } void finch_conversation_uninit()
--- a/finch/gntdebug.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntdebug.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -35,7 +38,6 @@ #include "gntdebug.h" #include "finch.h" -#include <internal.h> #include "notify.h" #include "util.h"
--- a/finch/gntft.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntft.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include <gnt.h> #include <gntbox.h>
--- a/finch/gntidle.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntidle.c Tue Jan 12 14:22:02 2010 +0000 @@ -21,6 +21,8 @@ * */ +#include <internal.h> + #include "finch.h" #include "gntidle.h" #include "gntwm.h"
--- a/finch/gntlog.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntlog.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include <gnt.h> #include <gntbox.h>
--- a/finch/gntmedia.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntmedia.c Tue Jan 12 14:22:02 2010 +0000 @@ -24,8 +24,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> #include "finch.h" -#include <internal.h> #include "gntconv.h" #include "gntmedia.h"
--- a/finch/gntnotify.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntnotify.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -32,7 +34,6 @@ #include <gntwindow.h> #include "finch.h" -#include <internal.h> #include <util.h>
--- a/finch/gntplugin.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntplugin.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -32,7 +34,6 @@ #include <gntutils.h> #include "finch.h" -#include <internal.h> #include "debug.h" #include "notify.h"
--- a/finch/gntpounce.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntpounce.c Tue Jan 12 14:22:02 2010 +0000 @@ -24,6 +24,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -36,7 +38,6 @@ #include <gntutils.h> #include "finch.h" -#include <internal.h> #include "account.h" #include "conversation.h"
--- a/finch/gntrequest.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntrequest.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -35,7 +37,6 @@ #include <gnttree.h> #include "finch.h" -#include <internal.h> #include "gntrequest.h" #include "debug.h" #include "util.h"
--- a/finch/gntstatus.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/gntstatus.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <internal.h> + #include <gnt.h> #include <gntbox.h> #include <gntbutton.h> @@ -34,7 +36,6 @@ #include <gntutils.h> #include "finch.h" -#include <internal.h> #include <notify.h> #include <request.h>
--- a/finch/libgnt/gntbindable.h Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntbindable.h Tue Jan 12 14:22:02 2010 +0000 @@ -166,7 +166,7 @@ * * @return @c TRUE if the action was performed successfully, @c FALSE otherwise. */ -gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...); +gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...) G_GNUC_NULL_TERMINATED; /** * Returns a GntTree populated with "key" -> "binding" for the widget.
--- a/finch/libgnt/gntbox.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntbox.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntbox.h" #include "gntstyle.h" #include "gntutils.h" @@ -90,7 +91,7 @@ else wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TITLE_D)); mvwaddch(widget->window, 0, pos-1, ACS_RTEE | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddstr(widget->window, 0, pos, title); + mvwaddstr(widget->window, 0, pos, C_(title)); mvwaddch(widget->window, 0, right, ACS_LTEE | gnt_color_pair(GNT_COLOR_NORMAL)); g_free(title); } @@ -687,8 +688,8 @@ get_title_thingies(b, prev, &pos, &right); mvwhline(w->window, 0, pos - 1, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), right - pos + 2); - g_free(prev); } + g_free(prev); } void gnt_box_set_pad(GntBox *box, int pad)
--- a/finch/libgnt/gntbutton.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntbutton.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> +#include "gntinternal.h" #include "gntbutton.h" #include "gntstyle.h" #include "gntutils.h" @@ -48,7 +49,7 @@ type = GNT_COLOR_NORMAL; wbkgdset(widget->window, '\0' | gnt_color_pair(type)); - mvwaddstr(widget->window, (small_button) ? 0 : 1, 2, button->priv->text); + mvwaddstr(widget->window, (small_button) ? 0 : 1, 2, C_(button->priv->text)); if (small_button) { type = GNT_COLOR_HIGHLIGHT; mvwchgat(widget->window, 0, 0, widget->priv.width, focus ? A_BOLD : A_REVERSE, type, NULL);
--- a/finch/libgnt/gntcheckbox.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntcheckbox.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntcheckbox.h" enum @@ -36,21 +37,21 @@ { GntCheckBox *cb = GNT_CHECK_BOX(widget); GntColorType type; - char *text; + gboolean focus = gnt_widget_has_focus(widget); - if (gnt_widget_has_focus(widget)) + if (focus) type = GNT_COLOR_HIGHLIGHT; else type = GNT_COLOR_NORMAL; wbkgdset(widget->window, '\0' | gnt_color_pair(type)); - text = g_strdup_printf("[%c]", cb->checked ? 'X' : ' '); - mvwaddstr(widget->window, 0, 0, text); - g_free(text); + mvwaddch(widget->window, 0, 0, '['); + mvwaddch(widget->window, 0, 1, (cb->checked ? 'X' : ' ') | (focus ? A_UNDERLINE : A_NORMAL)); + mvwaddch(widget->window, 0, 2, ']'); wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddstr(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text); + mvwaddstr(widget->window, 0, 4, C_(GNT_BUTTON(cb)->priv->text)); wmove(widget->window, 0, 1); GNTDEBUG;
--- a/finch/libgnt/gntcolors.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntcolors.c Tue Jan 12 14:22:02 2010 +0000 @@ -208,8 +208,10 @@ key = g_ascii_strdown(key, -1); color = gnt_colors_get_color(key); g_free(key); - if (color == -EINVAL) + if (color == -EINVAL) { + g_strfreev(list); continue; + } init_color(color, r, g, b); } @@ -251,8 +253,10 @@ int bg = gnt_colors_get_color(bgc); g_free(fgc); g_free(bgc); - if (fg == -EINVAL || bg == -EINVAL) + if (fg == -EINVAL || bg == -EINVAL) { + g_strfreev(list); continue; + } key = g_ascii_strdown(key, -1); @@ -275,6 +279,7 @@ else if (strcmp(key, "urgent") == 0) type = GNT_COLOR_URGENT; else { + g_strfreev(list); g_free(key); continue; }
--- a/finch/libgnt/gntcombobox.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntcombobox.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntbox.h" #include "gntcombobox.h" #include "gnttree.h" @@ -90,7 +91,7 @@ s = (char*)gnt_util_onscreen_width_to_pointer(text, widget->priv.width - 4, &len); *s = '\0'; - mvwaddstr(widget->window, 1, 1, text); + mvwaddstr(widget->window, 1, 1, C_(text)); whline(widget->window, ' ' | gnt_color_pair(type), widget->priv.width - 4 - len); mvwaddch(widget->window, 1, widget->priv.width - 3, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL)); mvwaddch(widget->window, 1, widget->priv.width - 2, ACS_DARROW | gnt_color_pair(GNT_COLOR_NORMAL));
--- a/finch/libgnt/gntentry.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntentry.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,6 +23,7 @@ #include <ctype.h> #include <string.h> +#include "gntinternal.h" #include "gntbox.h" #include "gntentry.h" #include "gntmarshal.h" @@ -284,7 +285,7 @@ g_utf8_pointer_to_offset(entry->scroll, entry->end)); } else - mvwprintw(widget->window, 0, 0, "%s", entry->scroll); + mvwprintw(widget->window, 0, 0, "%s", C_(entry->scroll)); stop = gnt_util_onscreen_width(entry->scroll, entry->end); if (stop < widget->priv.width) @@ -495,7 +496,7 @@ { GntEntry *entry = GNT_ENTRY(bind); if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down"); + gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL); return TRUE; } return show_suggest_dropdown(entry); @@ -1044,8 +1045,11 @@ snprintf(entry->start, len + 1, "%s", text); entry->end = entry->start + len; - entry->scroll = entry->start + scroll; - entry->cursor = entry->end - cursor; + if ((entry->scroll = entry->start + scroll) > entry->end) + entry->scroll = entry->end; + + if ((entry->cursor = entry->end - cursor) > entry->end) + entry->cursor = entry->end; if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED)) entry_redraw(GNT_WIDGET(entry));
--- a/finch/libgnt/gntfilesel.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntfilesel.c Tue Jan 12 14:22:02 2010 +0000 @@ -176,9 +176,13 @@ splits = g_strsplit(path, G_DIR_SEPARATOR_S, -1); for (i = 0, j = 0; splits[i]; i++) { if (strcmp(splits[i], ".") == 0) { + g_free(splits[i]); + splits[i] = NULL; } else if (strcmp(splits[i], "..") == 0) { if (j) j--; + g_free(splits[i]); + splits[i] = NULL; } else { if (i != j) { g_free(splits[j]); @@ -625,6 +629,7 @@ sel->files = gnt_tree_new_with_columns(2); /* Name, Size */ gnt_tree_set_compare_func(GNT_TREE(sel->files), (GCompareFunc)g_utf8_collate); + gnt_tree_set_hash_fns(GNT_TREE(sel->files), g_str_hash, g_str_equal, g_free); gnt_tree_set_column_titles(GNT_TREE(sel->files), "Filename", "Size"); gnt_tree_set_show_title(GNT_TREE(sel->files), TRUE); gnt_tree_set_col_width(GNT_TREE(sel->files), 0, 25);
--- a/finch/libgnt/gntinternal.h Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntinternal.h Tue Jan 12 14:22:02 2010 +0000 @@ -19,6 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <glib.h> #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "Gnt" @@ -31,3 +32,14 @@ # define gnt_warning g_warning #endif +#ifndef G_GNUC_NULL_TERMINATED +# if defined(__GNUC__) && __GNUC__ >= 4 +# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) +# else +# define G_GNUC_NULL_TERMINATED +# endif +#endif + +extern int gnt_need_conversation_to_locale; +extern const char *C_(const char *x); +
--- a/finch/libgnt/gntkeys.h Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntkeys.h Tue Jan 12 14:22:02 2010 +0000 @@ -65,7 +65,7 @@ #define GNT_KEY_BACKSPACE SAFE(key_backspace) #define GNT_KEY_DEL SAFE(key_dc) #define GNT_KEY_INS SAFE(key_ic) -#define GNT_KEY_BACK_TAB SAFE(back_tab) +#define GNT_KEY_BACK_TAB (back_tab ? back_tab : SAFE(key_btab)) #define GNT_KEY_CTRL_A "\001" #define GNT_KEY_CTRL_B "\002"
--- a/finch/libgnt/gntlabel.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntlabel.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntlabel.h" #include "gntutils.h" @@ -53,7 +54,7 @@ chtype flag = gnt_text_format_flag_to_chtype(label->flags); wbkgdset(widget->window, '\0' | flag); - mvwaddstr(widget->window, 0, 0, label->text); + mvwaddstr(widget->window, 0, 0, C_(label->text)); GNTDEBUG; }
--- a/finch/libgnt/gntline.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntline.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntline.h" enum
--- a/finch/libgnt/gntmain.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntmain.c Tue Jan 12 14:22:02 2010 +0000 @@ -82,6 +82,8 @@ static GntWM *wm; static GntClipboard *clipboard; +int gnt_need_conversation_to_locale; + #define HOLDING_ESCAPE (escape_stuff.timer != 0) static struct { @@ -465,10 +467,12 @@ #ifdef NO_WIDECHAR ascii_only = TRUE; #else - if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) + if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) { ascii_only = FALSE; - else + } else { ascii_only = TRUE; + gnt_need_conversation_to_locale = TRUE; + } #endif initscr(); @@ -731,3 +735,24 @@ #endif } +const char *C_(const char *x) +{ + static char *c = NULL; + if (gnt_need_conversation_to_locale) { + GError *error = NULL; + g_free(c); + c = g_locale_from_utf8(x, -1, NULL, NULL, &error); + if (c == NULL || error) { + char *store = c; + c = NULL; + gnt_warning("Error: %s\n", error ? error->message : "(unknown)"); + g_error_free(error); + error = NULL; + g_free(c); + c = store; + } + return c ? c : x; + } else + return x; +} +
--- a/finch/libgnt/gntmenu.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntmenu.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntmenu.h" #include "gntmenuitemcheck.h" @@ -92,7 +93,7 @@ item->priv.x = getcurx(widget->window) + widget->priv.x; item->priv.y = getcury(widget->window) + widget->priv.y + 1; wbkgdset(widget->window, type); - wprintw(widget->window, " %s ", item->text); + wprintw(widget->window, " %s ", C_(item->text)); } } else { org_draw(widget);
--- a/finch/libgnt/gntmenuitem.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntmenuitem.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntmenu.h" #include "gntmenuitem.h"
--- a/finch/libgnt/gntmenuitemcheck.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntmenuitemcheck.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntmenuitemcheck.h" static GntMenuItemClass *parent_class = NULL;
--- a/finch/libgnt/gntprogressbar.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntprogressbar.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA **/ +#include "gntinternal.h" #include "gntprogressbar.h" #include "gntutils.h"
--- a/finch/libgnt/gntslider.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntslider.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntcolors.h" #include "gntkeys.h" #include "gntslider.h"
--- a/finch/libgnt/gnttextview.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gnttextview.c Tue Jan 12 14:22:02 2010 +0000 @@ -67,6 +67,12 @@ static void reset_text_view(GntTextView *view); +static gboolean +text_view_contains(GntTextView *view, const char *str) +{ + return (str >= view->string->str && str < view->string->str + view->string->len); +} + static void gnt_text_view_draw(GntWidget *widget) { @@ -109,10 +115,10 @@ char back = *end; chtype fl = seg->flags; *end = '\0'; - if (select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) { + if (select_start && select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) { fl |= A_REVERSE; wattrset(widget->window, fl); - wprintw(widget->window, "%s", (view->string->str + seg->start)); + wprintw(widget->window, "%s", C_(view->string->str + seg->start)); } else if (select_start && select_end && ((select_start >= view->string->str + seg->start && select_start <= view->string->str + seg->end) || (select_end <= view->string->str + seg->end && select_start <= view->string->str + seg->start))) { @@ -126,13 +132,13 @@ fl = seg->flags; str = g_strndup(cur, last - cur); wattrset(widget->window, fl); - waddstr(widget->window, str); + waddstr(widget->window, C_(str)); g_free(str); cur = g_utf8_next_char(cur); } } else { wattrset(widget->window, fl); - wprintw(widget->window, "%s", (view->string->str + seg->start)); + wprintw(widget->window, "%s", C_(view->string->str + seg->start)); } *end = back; } @@ -326,9 +332,10 @@ select_start = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y); g_timeout_add(500, too_slow, NULL); } else if (event == GNT_MOUSE_UP) { - if (select_start) { + GntTextView *view = GNT_TEXT_VIEW(widget); + if (text_view_contains(view, select_start)) { GString *clip; - select_end = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y); + select_end = gnt_text_view_get_p(view, x - widget->priv.x, y - widget->priv.y); if (select_end < select_start) { gchar *t = select_start; select_start = select_end; @@ -336,7 +343,7 @@ } if (select_start == select_end) { if (double_click) { - clip = select_word_text(GNT_TEXT_VIEW(widget), select_start); + clip = select_word_text(view, select_start); double_click = FALSE; } else { double_click = TRUE; @@ -767,6 +774,7 @@ line->segments = g_list_delete_link(line->segments, segs); if (line->segments == NULL) { free_text_line(line, NULL); + line = NULL; if (view->list == iter) { if (inext) view->list = inext; @@ -780,7 +788,8 @@ seg->start = tag->start; seg->end = tag->end - change; } - line->length -= change; + if (line) + line->length -= change; /* XXX: Make things work if the tagged text spans over several lines. */ } else { /* XXX: handle the rest of the conditions */
--- a/finch/libgnt/gnttree.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gnttree.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntmarshal.h" #include "gntstyle.h" #include "gnttree.h" @@ -549,7 +550,7 @@ } wbkgdset(widget->window, '\0' | attr); - mvwaddstr(widget->window, i, pos, str); + mvwaddstr(widget->window, i, pos, C_(str)); whline(widget->window, ' ', scrcol - wr); tree->bottom = row; g_free(str); @@ -815,7 +816,7 @@ gnt_widget_activate(widget); } else if (tree->priv->search) { gboolean changed = TRUE; - if (isalnum(*text)) { + if (g_unichar_isprint(*text)) { tree->priv->search = g_string_append_c(tree->priv->search, *text); } else if (g_utf8_collate(text, GNT_KEY_BACKSPACE) == 0) { if (tree->priv->search->len)
--- a/finch/libgnt/gntutils.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntutils.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "config.h" + #include "gntinternal.h" #undef GNT_LOG_DOMAIN #define GNT_LOG_DOMAIN "Utils" @@ -35,8 +37,6 @@ #include "gntutils.h" #include "gntwindow.h" -#include "config.h" - #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -46,8 +46,6 @@ #include <libxml/tree.h> #endif -#include "config.h" - void gnt_util_get_text_bound(const char *text, int *width, int *height) { const char *s = text, *last; @@ -374,6 +372,7 @@ gnt_widget_from_xmlnode(node, data, num); xmlFreeDoc(doc); + xmlFreeParserCtxt(ctxt); xmlCleanupParser(); va_end(list); g_free(data); @@ -470,6 +469,7 @@ xmlFreeDoc(doc); ret = TRUE; } + xmlFreeParserCtxt(ctxt); xmlCleanupParser(); return ret; #endif
--- a/finch/libgnt/gntwidget.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntwidget.c Tue Jan 12 14:22:02 2010 +0000 @@ -22,6 +22,7 @@ /* Stuff brutally ripped from Gflib */ +#include "gntinternal.h" #include "gntwidget.h" #include "gntstyle.h" #include "gntmarshal.h"
--- a/finch/libgnt/gntwindow.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntwindow.c Tue Jan 12 14:22:02 2010 +0000 @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "gntinternal.h" #include "gntstyle.h" #include "gntwindow.h"
--- a/finch/libgnt/gntws.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/gntws.c Tue Jan 12 14:22:02 2010 +0000 @@ -1,5 +1,28 @@ +/* + * GNT - The GLib Ncurses Toolkit + * + * GNT is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + #include <gmodule.h> +#include "gntinternal.h" #include "gntbox.h" #include "gntwidget.h" #include "gntwindow.h" @@ -73,7 +96,7 @@ else mvwhline(taskbar, 0, width * i, ' ' | gnt_color_pair(color), getmaxx(stdscr) - width * i); title = GNT_BOX(w)->title; - mvwprintw(taskbar, 0, width * i, "%s", title ? title : "<gnt>"); + mvwprintw(taskbar, 0, width * i, "%s", title ? C_(title) : "<gnt>"); if (i) mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | gnt_color_pair(GNT_COLOR_NORMAL)); }
--- a/finch/libgnt/wms/irssi.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/wms/irssi.c Tue Jan 12 14:22:02 2010 +0000 @@ -33,6 +33,8 @@ #include <string.h> #include <sys/types.h> +#include "gntinternal.h" + #include "gnt.h" #include "gntbox.h" #include "gntmenu.h"
--- a/finch/libgnt/wms/s.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/libgnt/wms/s.c Tue Jan 12 14:22:02 2010 +0000 @@ -1,8 +1,8 @@ +#include "internal.h" + #include <string.h> #include <sys/types.h> -#include "internal.h" - #include "gnt.h" #include "gntbox.h" #include "gntmenu.h"
--- a/finch/plugins/gnttinyurl.c Wed Sep 23 14:48:57 2009 +0000 +++ b/finch/plugins/gnttinyurl.c Tue Jan 12 14:22:02 2010 +0000 @@ -41,7 +41,10 @@ #include <gntconv.h> #include <gntplugin.h> + +#include <gntlabel.h> #include <gnttextview.h> +#include <gntwindow.h> static int tag_num = 0; @@ -52,6 +55,8 @@ int num; } CbInfo; +static void process_urls(PurpleConversation *conv, GList *urls); + /* 3 functions from util.c */ static gboolean badchar(char c) @@ -83,7 +88,8 @@ return FALSE; } -static GList *extract_urls(char *text) { +static GList *extract_urls(const char *text) +{ const char *t, *c, *q = NULL; char *url_buf; GList *ret = NULL; @@ -142,7 +148,9 @@ url_buf = g_strndup(c, t - c); if (!g_list_find_custom(ret, url_buf, (GCompareFunc)strcmp)) { purple_debug_info("TinyURL", "Added URL %s\n", url_buf); - ret = g_list_append(ret, g_strdup(url_buf)); + ret = g_list_append(ret, url_buf); + } else { + g_free(url_buf); } c = t; break; @@ -173,6 +181,8 @@ if (!g_list_find_custom(ret, url_buf, (GCompareFunc)strcmp)) { purple_debug_info("TinyURL", "Added URL %s\n", url_buf); ret = g_list_append(ret, url_buf); + } else { + g_free(url_buf); } c = t; break; @@ -207,10 +217,12 @@ gnt_text_view_tag_change(tv, data->tag, str, FALSE); g_free(str); g_free(data->tag); + g_free(data); return; } } g_free(data->tag); + g_free(data); purple_debug_info("TinyURL", "Conversation no longer exists... :(\n"); } @@ -219,13 +231,14 @@ g_free(data); } -static gboolean receiving_msg(PurpleAccount *account, char **sender, char **message, - PurpleConversation *conv, PurpleMessageFlags *flags) { +static gboolean writing_msg(PurpleAccount *account, char *sender, char **message, + PurpleConversation *conv, PurpleMessageFlags flags) +{ GString *t; - GList *iter, *urls; + GList *iter, *urls, *next; int c = 0; - if (!(*flags & PURPLE_MESSAGE_RECV) || *flags & PURPLE_MESSAGE_INVISIBLE) + if ((flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_INVISIBLE))) return FALSE; urls = purple_conversation_get_data(conv, "TinyURLs"); @@ -238,7 +251,8 @@ t = g_string_new(*message); g_free(*message); - for (iter = urls; iter; iter = iter->next) { + for (iter = urls; iter; iter = next) { + next = iter->next; if (g_utf8_strlen((char *)iter->data, -1) >= purple_prefs_get_int(PREF_LENGTH)) { int pos, x = 0; gchar *j, *s, *str, *orig; @@ -256,36 +270,40 @@ g_free(str); continue; } else { - if (iter->prev) { - iter = iter->prev; - g_free(iter->next->data); - urls = g_list_delete_link(urls, iter->next); - } else { - g_free(iter->data); - g_list_free(urls); - urls = NULL; - } + g_free(iter->data); + urls = g_list_delete_link(urls, iter); } } *message = t->str; g_string_free(t, FALSE); if (conv == NULL) - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, *sender); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); purple_conversation_set_data(conv, "TinyURLs", urls); return FALSE; } -static void received_msg(PurpleAccount *account, char *sender, char *message, - PurpleConversation *conv, PurpleMessageFlags flags) { +static void wrote_msg(PurpleAccount *account, char *sender, char *message, + PurpleConversation *conv, PurpleMessageFlags flags) +{ + GList *urls; + + urls = purple_conversation_get_data(conv, "TinyURLs"); + if ((flags & PURPLE_MESSAGE_SEND) || urls == NULL) + return; + + process_urls(conv, urls); + purple_conversation_set_data(conv, "TinyURLs", NULL); +} + +/* Frees 'urls' */ +static void +process_urls(PurpleConversation *conv, GList *urls) +{ + GList *iter; int c; - GList *urls, *iter; FinchConv *fconv = FINCH_CONV(conv); GntTextView *tv = GNT_TEXT_VIEW(fconv->tv); - urls = purple_conversation_get_data(conv, "TinyURLs"); - if (!(flags & PURPLE_MESSAGE_RECV) || urls == NULL) - return; - for (iter = urls, c = 0; iter; iter = iter->next) { int i; CbInfo *cbdata; @@ -312,7 +330,6 @@ g_free(url); } g_list_free(urls); - purple_conversation_set_data(conv, "TinyURLs", NULL); } static void @@ -324,20 +341,75 @@ g_list_free(urls); } +static void tinyurl_notify_fetch_cb(PurpleUtilFetchUrlData *urldata, gpointer cbdata, + const gchar *urltext, gsize len, const gchar *error) +{ + GntWidget *win = cbdata; + GntWidget *label = g_object_get_data(G_OBJECT(win), "info-widget"); + char *message; + + message = g_strdup_printf(_("TinyURL for above: %s"), urltext); + gnt_label_set_text(GNT_LABEL(label), message); + g_free(message); + + g_signal_handlers_disconnect_matched(G_OBJECT(win), G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, + G_CALLBACK(purple_util_fetch_url_cancel), NULL); +} + +static void * +tinyurl_notify_uri(const char *uri) +{ + char *fullurl = NULL; + GntWidget *win; + PurpleUtilFetchUrlData *urlcb; + + /* XXX: The following expects that finch_notify_message gets called. This + * may not always happen, e.g. when another plugin sets its own + * notify_message. So tread carefully. */ + win = purple_notify_message(NULL, PURPLE_NOTIFY_URI, _("URI"), uri, + _("Please wait while TinyURL fetches a shorter URL ..."), NULL, NULL); + if (!GNT_IS_WINDOW(win) || !g_object_get_data(G_OBJECT(win), "info-widget")) + return win; + + if (g_ascii_strncasecmp(uri, "http://", 7) && g_ascii_strncasecmp(uri, "https://", 8)) { + fullurl = g_strdup_printf("%shttp%%3A%%2F%%2F%s", + purple_prefs_get_string(PREF_URL), purple_url_encode(uri)); + } else { + fullurl = g_strdup_printf("%s%s", purple_prefs_get_string(PREF_URL), + purple_url_encode(uri)); + } + + /* Store the return value of _fetch_url and destroy that when win is + destroyed, so that the callback for _fetch_url does not try to molest a + non-existent window */ + urlcb = purple_util_fetch_url(fullurl, TRUE, "finch", FALSE, tinyurl_notify_fetch_cb, win); + g_free(fullurl); + g_signal_connect_swapped(G_OBJECT(win), "destroy", + G_CALLBACK(purple_util_fetch_url_cancel), urlcb); + + return win; +} + static gboolean -plugin_load(PurplePlugin *plugin) { +plugin_load(PurplePlugin *plugin) +{ + PurpleNotifyUiOps *ops = purple_notify_get_ui_ops(); + plugin->extra = ops->notify_uri; + ops->notify_uri = tinyurl_notify_uri; + purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", - plugin, PURPLE_CALLBACK(received_msg), NULL); + plugin, PURPLE_CALLBACK(wrote_msg), NULL); purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", - plugin, PURPLE_CALLBACK(received_msg), NULL); + plugin, PURPLE_CALLBACK(wrote_msg), NULL); purple_signal_connect(purple_conversations_get_handle(), - "receiving-im-msg", - plugin, PURPLE_CALLBACK(receiving_msg), NULL); + "writing-im-msg", + plugin, PURPLE_CALLBACK(writing_msg), NULL); purple_signal_connect(purple_conversations_get_handle(), - "receiving-chat-msg", - plugin, PURPLE_CALLBACK(receiving_msg), NULL); + "writing-chat-msg", + plugin, PURPLE_CALLBACK(writing_msg), NULL); purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation", plugin, PURPLE_CALLBACK(free_conv_urls), NULL); @@ -345,6 +417,15 @@ return TRUE; } +static gboolean +plugin_unload(PurplePlugin *plugin) +{ + PurpleNotifyUiOps *ops = purple_notify_get_ui_ops(); + if (ops->notify_uri == tinyurl_notify_uri) + ops->notify_uri = plugin->extra; + return TRUE; +} + static PurplePluginPrefFrame * get_plugin_pref_frame(PurplePlugin *plugin) { @@ -394,7 +475,7 @@ "Richard Nelson <wabz@whatsbeef.net>", PURPLE_WEBSITE, plugin_load, - NULL, + plugin_unload, NULL, NULL, NULL,
--- a/libpurple/Makefile.am Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/Makefile.am Tue Jan 12 14:22:02 2010 +0000 @@ -32,7 +32,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = purple.pc -SUBDIRS = $(GCONF_DIR) plugins protocols tests . example +SUBDIRS = $(GCONF_DIR) plugins protocols . tests example purple_coresources = \ account.c \
--- a/libpurple/account.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/account.c Tue Jan 12 14:22:02 2010 +0000 @@ -1050,9 +1050,22 @@ if(account->system_log) purple_log_free(account->system_log); + while (account->deny) { + g_free(account->deny->data); + account->deny = g_slist_delete_link(account->deny, account->deny); + } + + while (account->permit) { + g_free(account->permit->data); + account->permit = g_slist_delete_link(account->permit, account->permit); + } + priv = PURPLE_ACCOUNT_GET_PRIVATE(account); PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error); - g_free(priv->current_error); + if (priv->current_error) { + g_free(priv->current_error->description); + g_free(priv->current_error); + } g_free(priv); PURPLE_DBUS_UNREGISTER_POINTER(account); @@ -1328,7 +1341,8 @@ handles = g_list_remove(handles, info); - info->auth_cb(info->userdata); + if (info->auth_cb != NULL) + info->auth_cb(info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-granted", info->account, info->user); @@ -1343,7 +1357,8 @@ handles = g_list_remove(handles, info); - info->deny_cb(info->userdata); + if (info->deny_cb != NULL) + info->deny_cb(info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-denied", info->account, info->user); @@ -1370,10 +1385,12 @@ "account-authorization-requested", account, remote_user)); if (plugin_return > 0) { - auth_cb(user_data); + if (auth_cb != NULL) + auth_cb(user_data); return NULL; } else if (plugin_return < 0) { - deny_cb(user_data); + if (deny_cb != NULL) + deny_cb(user_data); return NULL; } @@ -2298,7 +2315,7 @@ gc = purple_account_get_connection(account); if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2315,7 +2332,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2354,7 +2371,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2371,7 +2388,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2399,7 +2416,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2419,7 +2436,7 @@ purple_account_set_password(account, new_pw); if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
--- a/libpurple/blist.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/blist.c Tue Jan 12 14:22:02 2010 +0000 @@ -2009,18 +2009,14 @@ ops = purple_blist_get_ui_ops(); - if (!purplebuddylist->root) { - purplebuddylist->root = gnode; - - key = g_utf8_collate_key(group->name, -1); - g_hash_table_insert(groups_cache, key, group); - return; + /* if we're moving to overtop of ourselves, do nothing */ + if (gnode == node) { + if (!purplebuddylist->root) + node = NULL; + else + return; } - /* if we're moving to overtop of ourselves, do nothing */ - if (gnode == node) - return; - if (purple_find_group(group->name)) { /* This is just being moved */
--- a/libpurple/certificate.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/certificate.c Tue Jan 12 14:22:02 2010 +0000 @@ -26,8 +26,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include <glib.h> - #include "internal.h" #include "certificate.h" #include "dbus-maybe.h" @@ -97,8 +95,8 @@ "automatically checked."); break; case PURPLE_CERTIFICATE_CA_UNKNOWN: - return _("The root certificate this one claims to be issued by is " - "unknown."); + return _("The certificate is not trusted because no certificate " + "that can verify it is currently trusted."); break; case PURPLE_CERTIFICATE_NOT_ACTIVATED: return _("The certificate is not valid yet."); @@ -1402,13 +1400,15 @@ if (flags & PURPLE_CERTIFICATE_NAME_MISMATCH) { gchar *sn = purple_certificate_get_subject_name(peer_crt); - g_string_append_printf(errors, _("The certificate claims to be " - "from \"%s\" instead. This could mean that you are " - "not connecting to the service you believe you are."), - sn); - g_free(sn); + if (sn) { + g_string_append_printf(errors, _("The certificate claims to be " + "from \"%s\" instead. This could mean that you are " + "not connecting to the service you believe you are."), + sn); + g_free(sn); - flags &= ~PURPLE_CERTIFICATE_NAME_MISMATCH; + flags &= ~PURPLE_CERTIFICATE_NAME_MISMATCH; + } } while (i != PURPLE_CERTIFICATE_LAST) { @@ -1431,9 +1431,8 @@ tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name, "tls_peers"); if (tls_peers) { - if (!purple_certificate_pool_contains(tls_peers, vrq->subject_name) && - !purple_certificate_pool_store(tls_peers,vrq->subject_name, - peer_crt)) { + if (!purple_certificate_pool_store(tls_peers,vrq->subject_name, + peer_crt)) { purple_debug_error("certificate/x509/tls_cached", "FAILED to cache peer certificate\n"); }
--- a/libpurple/cipher.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/cipher.c Tue Jan 12 14:22:02 2010 +0000 @@ -50,10 +50,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include <glib.h> -#include <string.h> -#include <stdio.h> - #include "internal.h" #include "cipher.h" #include "dbus-maybe.h"
--- a/libpurple/cmds.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/cmds.c Tue Jan 12 14:22:02 2010 +0000 @@ -21,8 +21,6 @@ * */ -#include <string.h> - #include "internal.h" #include "account.h"
--- a/libpurple/conversation.h Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/conversation.h Tue Jan 12 14:22:02 2010 +0000 @@ -368,7 +368,8 @@ * @param type The type of conversation. * @param account The account opening the conversation window on the purple * user's end. - * @param name The name of the conversation. + * @param name The name of the conversation. For PURPLE_CONV_TYPE_IM, + * this is the name of the buddy. * * @return The new conversation. */ @@ -1025,7 +1026,8 @@ GList *purple_conv_chat_set_users(PurpleConvChat *chat, GList *users); /** - * Returns a list of users in the chat room. + * Returns a list of users in the chat room. The members of the list + * are PurpleConvChatBuddy objects. * * @param chat The chat. *
--- a/libpurple/dbus-server.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/dbus-server.c Tue Jan 12 14:22:02 2010 +0000 @@ -25,14 +25,16 @@ #define DBUS_API_SUBJECT_TO_CHANGE #endif +/* Allow the code below to see deprecated functions, so we can continue to + * export them via DBus. */ +#undef PURPLE_DISABLE_DEPRECATED + +#include "internal.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> -/* Allow the code below to see deprecated functions, so we can continue to - * export them via DBus. */ -#undef PURPLE_DISABLE_DEPRECATED - #include "account.h" #include "blist.h" #include "conversation.h" @@ -42,7 +44,6 @@ #include "dbus-bindings.h" #include "debug.h" #include "core.h" -#include "internal.h" #include "savedstatuses.h" #include "smiley.h" #include "util.h" @@ -600,7 +601,6 @@ { static DBusObjectPathVTable vtable = {NULL, &purple_dbus_dispatch, NULL, NULL, NULL, NULL}; DBusError error; - int result; dbus_error_init(&error); purple_dbus_connection = dbus_bus_get(DBUS_BUS_STARTER, &error); @@ -624,16 +624,15 @@ return; } - dbus_request_name_reply = - result = dbus_bus_request_name(purple_dbus_connection, + dbus_request_name_reply = dbus_bus_request_name(purple_dbus_connection, DBUS_SERVICE_PURPLE, 0, &error); if (dbus_error_is_set(&error)) { dbus_connection_unref(purple_dbus_connection); - dbus_error_free(&error); purple_dbus_connection = NULL; init_error = g_strdup_printf(N_("Failed to get serv name: %s"), error.name); + dbus_error_free(&error); return; }
--- a/libpurple/debug.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/debug.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "internal.h" #include "debug.h" -#include "internal.h" #include "prefs.h" #include "util.h"
--- a/libpurple/desktopitem.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/desktopitem.c Tue Jan 12 14:22:02 2010 +0000 @@ -53,12 +53,12 @@ * Boston, MA 02111-1301, USA. */ +#include "internal.h" #include <errno.h> #include <stdio.h> #include <string.h> #include <time.h> #include "desktopitem.h" -#include "internal.h" struct _PurpleDesktopItem { int refcount;
--- a/libpurple/dnsquery.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/dnsquery.c Tue Jan 12 14:22:02 2010 +0000 @@ -172,6 +172,7 @@ return FALSE; } +#ifdef USE_IDN static gboolean dns_str_is_ascii(const char *name) { @@ -183,6 +184,7 @@ return TRUE; } +#endif #if defined(PURPLE_DNSQUERY_USE_FORK) @@ -293,12 +295,11 @@ rc = purple_network_convert_idn_to_ascii(dns_params.hostname, &hostname); if (rc != 0) { write_to_parent(child_out, &rc, sizeof(rc)); - close(child_out); if (show_debug) fprintf(stderr, "dns[%d] Error: IDN conversion returned " "%d\n", getpid(), rc); dns_params.hostname[0] = '\0'; - continue; + break; } } else /* intentional to execute the g_strdup */ #endif @@ -323,12 +324,13 @@ rc = getaddrinfo(hostname, servname, &hints, &res); write_to_parent(child_out, &rc, sizeof(rc)); if (rc != 0) { - close(child_out); if (show_debug) printf("dns[%d] Error: getaddrinfo returned %d\n", getpid(), rc); dns_params.hostname[0] = '\0'; - continue; + g_free(hostname); + hostname = NULL; + break; } tmp = res; while (res) { @@ -774,11 +776,8 @@ if (!dns_str_is_ascii(query_data->hostname)) { rc = purple_network_convert_idn_to_ascii(query_data->hostname, &hostname); if (rc != 0) { - /* FIXME: Dirty 2.6.0 string freeze hack */ - char tmp[8]; - g_snprintf(tmp, sizeof(tmp), "%d", rc); - query_data->error_message = g_strdup_printf(_("Error resolving %s:\n%s"), - query_data->hostname, tmp); + query_data->error_message = g_strdup_printf(_("Error converting %s " + "to punycode: %d"), query_data->hostname, rc); /* back to main thread */ purple_timeout_add(0, dns_main_thread_cb, query_data); return 0; @@ -918,7 +917,6 @@ PurpleDnsQueryData *query_data; struct sockaddr_in sin; GSList *hosts = NULL; - char *hostname; query_data = data; query_data->timeout = 0; @@ -931,6 +929,7 @@ if (!inet_aton(query_data->hostname, &sin.sin_addr)) { struct hostent *hp; + gchar *hostname; #ifdef USE_IDN if (!dns_str_is_ascii(query_data->hostname)) { int ret = purple_network_convert_idn_to_ascii(query_data->hostname, @@ -951,16 +950,17 @@ g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), query_data->hostname, h_errno); purple_dnsquery_failed(query_data, message); + g_free(hostname); return FALSE; } memset(&sin, 0, sizeof(struct sockaddr_in)); memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; + g_free(hostname); } else sin.sin_family = AF_INET; sin.sin_port = htons(query_data->port); - g_free(hostname); hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin)));
--- a/libpurple/dnsquery.h Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/dnsquery.h Tue Jan 12 14:22:02 2010 +0000 @@ -30,6 +30,11 @@ #include "eventloop.h" #include "account.h" +/** + * An opaque structure representing a DNS query. The hostname and port + * associated with the query can be retrieved using + * purple_dnsquery_get_host() and purple_dnsquery_get_port(). + */ typedef struct _PurpleDnsQueryData PurpleDnsQueryData; /**
--- a/libpurple/dnssrv.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/dnssrv.c Tue Jan 12 14:22:02 2010 +0000 @@ -248,6 +248,7 @@ return list; } +#ifdef USE_IDN static gboolean dns_str_is_ascii(const char *name) { @@ -259,8 +260,60 @@ return TRUE; } +#endif #ifndef _WIN32 +static void +write_to_parent(int in, int out, gconstpointer data, gsize size) +{ + const guchar *buf = data; + gssize w; + + do { + w = write(out, buf, size); + if (w > 0) { + buf += w; + size -= w; + } else if (w < 0 && errno == EINTR) { + /* Let's try some more; */ + w = 1; + } + } while (size > 0 && w > 0); + + if (size != 0) { + /* An error occurred */ + close(out); + close(in); + _exit(0); + } +} + +/* Read size bytes to data. Dies if an error occurs. */ +static void +read_from_parent(int in, int out, gpointer data, gsize size) +{ + guchar *buf = data; + gssize r; + + do { + r = read(in, data, size); + if (r > 0) { + buf += r; + size -= r; + } else if (r < 0 && errno == EINTR) { + /* Let's try some more; */ + r = 1; + } + } while (size > 0 && r > 0); + + if (size != 0) { + /* An error occurred */ + close(out); + close(in); + _exit(0); + } +} + G_GNUC_NORETURN static void resolve(int in, int out) @@ -279,16 +332,12 @@ purple_restore_default_signal_handlers(); #endif - if (read(in, &query, sizeof(query)) <= 0) { - close(out); - close(in); - _exit(0); - } + read_from_parent(in, out, &query, sizeof(query)); size = res_query( query.query, C_IN, query.type, (u_char*)&answer, sizeof( answer)); if (size == -1) { - write(out, &(query.type), sizeof(query.type)); - write(out, &size, sizeof(int)); + write_to_parent(in, out, &(query.type), sizeof(query.type)); + write_to_parent(in, out, &size, sizeof(size)); close(out); close(in); _exit(0); @@ -353,16 +402,18 @@ if (query.type == T_SRV) ret = purple_srv_sort(ret); - /* TODO: Check return value */ - write(out, &(query.type), sizeof(query.type)); - write(out, &size, sizeof(size)); + write_to_parent(in, out, &(query.type), sizeof(query.type)); + write_to_parent(in, out, &size, sizeof(size)); while (ret != NULL) { - /* TODO: Check return value */ if (query.type == T_SRV) - write(out, ret->data, sizeof(PurpleSrvResponse)); - if (query.type == T_TXT) - write(out, ret->data, sizeof(PurpleTxtResponse)); + write_to_parent(in, out, ret->data, sizeof(PurpleSrvResponse)); + if (query.type == T_TXT) { + PurpleTxtResponse *response = ret->data; + gsize l = strlen(response->content) + 1 /* null byte */; + write_to_parent(in, out, &l, sizeof(l)); + write_to_parent(in, out, response->content, l); + } g_free(ret->data); ret = g_list_remove(ret, ret->data); @@ -429,21 +480,38 @@ PurpleTxtCallback cb = query_data->cb.txt; ssize_t red; purple_debug_info("dnssrv","found %d TXT entries\n", size); - res = g_new0(PurpleTxtResponse, 1); for (i = 0; i < size; i++) { - red = read(source, res, sizeof(PurpleTxtResponse)); - if (red != sizeof(PurpleTxtResponse)) { + gsize len; + + red = read(source, &len, sizeof(len)); + if (red != sizeof(len)) { purple_debug_error("dnssrv","unable to read txt " - "response: %s\n", g_strerror(errno)); + "response length: %s\n", g_strerror(errno)); size = 0; - g_free(res); g_list_foreach(responses, (GFunc)purple_txt_response_destroy, NULL); g_list_free(responses); responses = NULL; break; } + + res = g_new0(PurpleTxtResponse, 1); + res->content = g_new0(gchar, len); + + red = read(source, res->content, len); + if (red != len) { + purple_debug_error("dnssrv","unable to read txt " + "response: %s\n", g_strerror(errno)); + size = 0; + purple_txt_response_destroy(res); + g_list_foreach(responses, (GFunc)purple_txt_response_destroy, NULL); + g_list_free(responses); + responses = NULL; + break; + } + responses = g_list_prepend(responses, res); } + responses = g_list_reverse(responses); cb(responses, query_data->extradata); } else { purple_debug_error("dnssrv", "type unknown of DNS result entry; errno is %i\n", errno); @@ -674,6 +742,7 @@ internal_query.type = T_SRV; strncpy(internal_query.query, query, 255); + internal_query.query[255] = '\0'; if (write(in[1], &internal_query, sizeof(internal_query)) < 0) purple_debug_error("dnssrv", "Could not write to SRV resolver\n"); @@ -787,6 +856,7 @@ internal_query.type = T_TXT; strncpy(internal_query.query, query, 255); + internal_query.query[255] = '\0'; if (write(in[1], &internal_query, sizeof(internal_query)) < 0) purple_debug_error("dnssrv", "Could not write to TXT resolver\n");
--- a/libpurple/eventloop.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/eventloop.c Tue Jan 12 14:22:02 2010 +0000 @@ -23,8 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include "internal.h" #include "eventloop.h" -#include "internal.h" static PurpleEventLoopUiOps *eventloop_ui_ops = NULL;
--- a/libpurple/ft.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/ft.c Tue Jan 12 14:22:02 2010 +0000 @@ -69,6 +69,30 @@ g_free(priv); } +static const gchar * +purple_xfer_status_type_to_string(PurpleXferStatusType type) +{ + static const struct { + PurpleXferStatusType type; + const char *name; + } type_names[] = { + { PURPLE_XFER_STATUS_UNKNOWN, "unknown" }, + { PURPLE_XFER_STATUS_NOT_STARTED, "not started" }, + { PURPLE_XFER_STATUS_ACCEPTED, "accepted" }, + { PURPLE_XFER_STATUS_STARTED, "started" }, + { PURPLE_XFER_STATUS_DONE, "done" }, + { PURPLE_XFER_STATUS_CANCEL_LOCAL, "cancelled locally" }, + { PURPLE_XFER_STATUS_CANCEL_REMOTE, "cancelled remotely" } + }; + int i; + + for (i = 0; i < G_N_ELEMENTS(type_names); ++i) + if (type_names[i].type == type) + return type_names[i].name; + + return "invalid state"; +} + GList * purple_xfers_get_all() { @@ -109,6 +133,10 @@ ui_ops->new_xfer(xfer); xfers = g_list_prepend(xfers, xfer); + + if (purple_debug_is_verbose()) + purple_debug_info("xfer", "new %p [%d]\n", xfer, xfer->ref); + return xfer; } @@ -119,6 +147,9 @@ g_return_if_fail(xfer != NULL); + if (purple_debug_is_verbose()) + purple_debug_info("xfer", "destroyed %p [%d]\n", xfer, xfer->ref); + /* Close the file browser, if it's open */ purple_request_close_with_handle(xfer); @@ -148,6 +179,9 @@ g_return_if_fail(xfer != NULL); xfer->ref++; + + if (purple_debug_is_verbose()) + purple_debug_info("xfer", "ref'd %p [%d]\n", xfer, xfer->ref); } void @@ -158,6 +192,9 @@ xfer->ref--; + if (purple_debug_is_verbose()) + purple_debug_info("xfer", "unref'd %p [%d]\n", xfer, xfer->ref); + if (xfer->ref == 0) purple_xfer_destroy(xfer); } @@ -167,6 +204,11 @@ { g_return_if_fail(xfer != NULL); + if (purple_debug_is_verbose()) + purple_debug_info("xfer", "Changing status of xfer %p from %s to %s\n", + xfer, purple_xfer_status_type_to_string(xfer->status), + purple_xfer_status_type_to_string(status)); + if (xfer->status == status) return; @@ -229,7 +271,7 @@ escaped = g_markup_escape_text(message, -1); if (is_error) - flags = PURPLE_MESSAGE_ERROR; + flags |= PURPLE_MESSAGE_ERROR; purple_conversation_write(conv, NULL, escaped, flags, time(NULL)); g_free(escaped); @@ -268,14 +310,16 @@ 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 (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { + if (type == PURPLE_XFER_RECEIVE) { #ifndef _WIN32 int mode = W_OK; #else @@ -297,29 +341,26 @@ } else { purple_xfer_show_file_error(xfer, filename); - purple_xfer_request_denied(xfer); + purple_xfer_cancel_local(xfer); } } - else if ((purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) && - (st.st_size == 0)) { + 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_request_denied(xfer); + purple_xfer_cancel_local(xfer); } - else if ((purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) && - S_ISDIR(st.st_mode)) { + 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_request_denied(xfer); + purple_xfer_cancel_local(xfer); } - else if ((purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) && - S_ISDIR(st.st_mode)) { + 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( @@ -329,6 +370,23 @@ 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); } @@ -342,7 +400,11 @@ PurpleXfer *xfer = (PurpleXfer *)user_data; purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_CANCEL_LOCAL); - purple_xfer_request_denied(xfer); + if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) + purple_xfer_cancel_local(xfer); + else + purple_xfer_request_denied(xfer); + purple_xfer_unref(xfer); } static int @@ -506,6 +568,8 @@ type = purple_xfer_get_type(xfer); account = purple_xfer_get_account(xfer); + purple_debug_misc("xfer", "request accepted for %p\n", xfer); + if (!filename && type == PURPLE_XFER_RECEIVE) { xfer->status = PURPLE_XFER_STATUS_ACCEPTED; xfer->ops.init(xfer); @@ -583,6 +647,8 @@ { g_return_if_fail(xfer != NULL); + purple_debug_misc("xfer", "xfer %p denied\n", xfer); + if (xfer->ops.request_denied != NULL) xfer->ops.request_denied(xfer); @@ -1030,7 +1096,7 @@ * watcher. */ if (xfer->watcher != 0) { - purple_timeout_remove(xfer->watcher); + purple_input_remove(xfer->watcher); xfer->watcher = 0; } @@ -1111,6 +1177,8 @@ purple_input_remove(xfer->watcher); xfer->watcher = 0; + + purple_debug_misc("xfer", "prpl is ready on ft %p, waiting for UI\n", xfer); return; } } @@ -1173,8 +1241,12 @@ priv = g_hash_table_lookup(xfers_data, xfer); priv->ready |= PURPLE_XFER_READY_UI; - if (0 == (priv->ready & PURPLE_XFER_READY_PRPL)) + if (0 == (priv->ready & PURPLE_XFER_READY_PRPL)) { + purple_debug_misc("xfer", "UI is ready on ft %p, waiting for prpl\n", xfer); return; + } + + purple_debug_misc("xfer", "UI (and prpl) ready on ft %p, so proceeding\n", xfer); type = purple_xfer_get_type(xfer); if (type == PURPLE_XFER_SEND) @@ -1201,8 +1273,12 @@ priv->ready |= PURPLE_XFER_READY_PRPL; /* I don't think fwrite/fread are ever *not* ready */ - if (xfer->dest_fp == NULL && 0 == (priv->ready & PURPLE_XFER_READY_UI)) + if (xfer->dest_fp == NULL && 0 == (priv->ready & PURPLE_XFER_READY_UI)) { + purple_debug_misc("xfer", "prpl is ready on ft %p, waiting for UI\n", xfer); return; + } + + purple_debug_misc("xfer", "Prpl (and UI) ready on ft %p, so proceeding\n", xfer); priv->ready = PURPLE_XFER_READY_NONE;
--- a/libpurple/ft.h Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/ft.h Tue Jan 12 14:22:02 2010 +0000 @@ -160,7 +160,10 @@ PurpleXferStatusType status; /**< File Transfer's status. */ - /* I/O operations. */ + /** I/O operations, which should be set by the prpl using + * purple_xfer_set_init_fnc() and friends. Setting #init is + * mandatory; all others are optional. + */ struct { void (*init)(PurpleXfer *xfer); @@ -674,7 +677,7 @@ void purple_xfer_ui_ready(PurpleXfer *xfer); /** - * Allows the prpl to signal it's readh to send/receive data (depending on + * Allows the prpl to signal it's ready to send/receive data (depending on * the direction of the file transfer. Used when the prpl provides read/write * ops and cannot/does not provide a raw fd to the core. *
--- a/libpurple/imgstore.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/imgstore.c Tue Jan 12 14:22:02 2010 +0000 @@ -25,7 +25,6 @@ * */ -#include <glib.h> #include "internal.h" #include "dbus-maybe.h"
--- a/libpurple/media.c Wed Sep 23 14:48:57 2009 +0000 +++ b/libpurple/media.c Tue Jan 12 14:22:02 2010 +0000 @@ -24,8 +24,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include <string.h> - #include "internal.h" #include "account.h" @@ -103,6 +101,8 @@ gboolean initiator; gboolean accepted; gboolean candidates_prepared; + gboolean held; + gboolean paused; GList *active_local_candidates; GList *active_remote_candidates; @@ -281,7 +281,7 @@ { PURPLE_MEDIA_INFO_HOLD, "PURPLE_MEDIA_INFO_HOLD", "hold" }, { PURPLE_MEDIA_INFO_UNHOLD, - "PURPLE_MEDIA_INFO_HOLD", "unhold" }, + "PURPLE_MEDIA_INFO_UNHOLD", "unhold" }, { 0, NULL, NULL } }; type = g_enum_register_static("PurpleMediaInfoType", values); @@ -2279,7 +2279,8 @@ stream->session->type), NULL); stream->accepted = TRUE; - if (stream->remote_candidates != NULL) { + if (stream->remote_candidates != NULL && + stream->initiator == FALSE) { GError *err = NULL; fs_stream_set_remote_candidates(stream->stream, stream->remote_candidates, &err); @@ -2330,11 +2331,46 @@ for (; streams; streams = g_list_delete_link(streams, streams)) { PurpleMediaStream *stream = streams->data;