Sat, 02 Feb 2013 21:20:08 +0100
Merge from trunk
| libpurple/ciphers/md5.c | file | annotate | diff | comparison | revisions | |
| libpurple/ciphers/sha1.c | file | annotate | diff | comparison | revisions | |
| libpurple/ciphers/sha256.c | file | annotate | diff | comparison | revisions | |
| libpurple/protocols/gg/gg.c | file | annotate | diff | comparison | revisions | |
| libpurple/protocols/gg/image.c | file | annotate | diff | comparison | revisions | |
| share/ca-certs/Microsoft_Internet_Authority.pem | file | annotate | diff | comparison | revisions | |
| share/ca-certs/Microsoft_Secure_Server_Authority.pem | file | annotate | diff | comparison | revisions | |
| share/ca-certs/Verisign_RSA_Secure_Server_CA.pem | file | annotate | diff | comparison | revisions |
--- a/.hgignore Sat Feb 02 18:29:35 2013 +0100 +++ b/.hgignore Sat Feb 02 21:20:08 2013 +0100 @@ -10,6 +10,7 @@ .*/perl/common/MYMETA\.(json|yml) .*~$ .*\.a$ +.*\.asc$ .*\.bak$ .*\.bs$ .*\.def$
--- a/COPYRIGHT Sat Feb 02 18:29:35 2013 +0100 +++ b/COPYRIGHT Sat Feb 02 21:20:08 2013 +0100 @@ -17,6 +17,7 @@ Copyright (C) 1998-2012 by the following: +Mark Saleem Abdulrasool Jakub Adam Dave Ahlswede @@ -73,6 +74,7 @@ Éric Boumaour Chris Boyle Stanislav Brabec +Bartosz Brachaczek Quentin Brandon Derrick J Brashear Mauro Sérgio Ferreira Brasil @@ -175,6 +177,7 @@ Gavan Fantom (gavan) Leonardo Fernandes David Fiander +Michael Fiedler Ryan Flegel Rob Flynn <gaim@robflynn.com> Rob Foehl (rwf) @@ -459,6 +462,7 @@ Thanumalayan S. Jonathan Sailor Elliott Sales de Andrade +Catalin Salgau Tomasz Sałaciński <tsalacinski@gmail.com> Pradyumna Sampath Arvind Samptur @@ -511,6 +515,7 @@ Lex Spoon Chris Stafford Kevin Stange +Ferdinand Stehle Joshua Stein Jakub Steiner Richard Stellingwerff @@ -537,6 +542,7 @@ Cestonaro Thilo Will Thompson Douglas Thrift (douglaswth) +Niels Thykier Mark Tiefenbruck Andrew Tinney Jeffery To
--- a/ChangeLog Sat Feb 02 18:29:35 2013 +0100 +++ b/ChangeLog Sat Feb 02 21:20:08 2013 +0100 @@ -10,6 +10,8 @@ * Add email notification in the docklet area. (Alexei) (#3571) * Add a pref to select the type messages in conversation that triggers the docklet notification. (Momchil) (#12598) + * Complete support for receiving a limited amount of history when + joining a room. (Kha) (#15458) Finch: * Support the conversation-extended signal for extending the @@ -60,21 +62,83 @@ * Fix a crash at startup with large contact list. Avatar support for buddies will be disabled till 3.0.0. (#15226, #14305) + General: + * The configure script will now exit with status 1 when specifying + invalid protocol plugins using the --with-static-prpls and + --with-dynamic-prpls arguments. (Michael Fiedler) (#15316) + + libpurple: + * Don't link directly to libgcrypt when building with GnuTLS support. + (Bartosz Brachaczek) (#15329) + * Fix UPnP mappings on routers that return empty <URLBase/> elements + in their response. (Ferdinand Stehle) (#15373) + * Tcl plugin uses saner, race-free plugin loading. + * Fix the Tcl signals-test plugin for savedstatus-changed. + (Andrew Shadura) (#15443) + + Pidgin: + * Make Pidgin more friendly to non-X11 GTK+, such as MacPorts' +no_x11 + variant. + Gadu-Gadu: * Fix a crash at startup with large contact list. Avatar support for buddies will be disabled till 3.0.0. (#15226, #14305) + IRC: + * Support for SASL authentication. (Thijs Alkemade, Andy Spencer) + (#13270) + * Print topic setter information at channel join. (#13317) + MSN: + * Fix SSL certificate issue when signing into MSN for some users. * Fix a crash when removing a user before its icon is loaded. (Mark Barfield) (#15217) + MXit: + * Display farewell messages in a different colour to distinguish + them from normal messages. + * Add support for typing notification. + * Add support for the Relationship Status profile attribute. + * Remove all reference to Hidden Number. + * Ignore new invites to join a GroupChat if you're already joined, or + still have a pending invite. + * The buddy's name was not centered vertically in the buddy-list if they + did not have a status-message or mood set. + * Fix decoding of font-size changes in the markup of received messages. + Yahoo!: * Fix a double-free in profile/picture loading code. (Mihai Serban) (#15053) + * Fix retrieving server-side buddy aliases. (Catalin Salgu) (#15381) Plugins: * The Voice/Video Settings plugin supports using the sndio GStreamer - backends. (Brad Smith) (#14414) + backends. (Brad Smith) (#14414) + * Fix a crash in the Contact Availability Detection plugin. (Mark) + (#15327) + * Make the Message Notification plugin more friendly to non-X11 GTK+, + such as MacPorts' +no_x11 variant. + + Windows-Specific Changes: + * Compile with secure flags (#15290) + * Installer downloads GTK+ Runtime and Debug Symbols more securely. + (#15277) + * Updates to a number of dependencies, some of which have security + related fixes. (#14571, #15285, #15286) + * ATK 1.32.0-2 + * Cyrus SASL 2.1.25 + * expat 2.1.0-1 + * freetype 2.4.10-1 + * gettext 0.18.1.1-2 + * Glib 2.28.8-1 + * libpng 1.4.12-1 + * libxml2 2.9.0-1 + * NSS 3.13.6 and NSPR 4.9.2 + * Pango 1.29.4-1 + * SILC 1.1.10 + * zlib 1.2.5-2 + * Patch libmeanwhile (sametime library) to fix crash. (Jonathan Rice) + (#12637) version 2.10.6 (07/06/2012): Pidgin:
--- a/ChangeLog.API Sat Feb 02 18:29:35 2013 +0100 +++ b/ChangeLog.API Sat Feb 02 21:20:08 2013 +0100 @@ -78,10 +78,12 @@ * PidginDockletFlag Changed: + * account-authorization-requested signal merged with account-authorization-requested-with-message signal * purple_account_add_buddy now takes an invite message as the last parameter * purple_account_add_buddies now takes an invite message as the last parameter + * purple_buddy_icon_unref no longer has a return value * purple_certificate_check_signature_chain now returns a list of failing PurpleCertificate*s as the second parameter * purple_connection_error now takes a PurpleConnectionError @@ -89,6 +91,8 @@ * purple_conversation_get_gc renamed to purple_conversation_get_connection * purple_dnsquery_a now takes a PurpleAccount as the first parameter + * purple_imgstore_add renamed to purple_imgstore_new + * purple_imgstore_add_with_id renamed to purple_imgstore_new_with_id * purple_network_listen now takes the protocol family as the second parameter * purple_network_listen now takes a boolean indicating external port @@ -103,6 +107,8 @@ a GList * purple_notify_user_info_prepend_pair renamed to purple_notify_user_info_prepend_pair_html + * pidgin_setup_screenname_autocomplete now takes a filter function and + its data as final two arguments * purple_srv_resolve now takes a PurpleAccount as the first parameter * purple_str_size_to_units now takes a goffset as the size parameter * purple_txt_resolve now takes a PurpleAccount as the first parameter @@ -118,6 +124,9 @@ * purple_xfer_set_bytes_sent now takes a goffset as the bytes_sent parameter * purple_xfer_set_size now takes a goffset as the size parameter + * PurpleCertificateVerificationStatus enumeration is now merged with + internal flags, thus removing PURPLE_CERTIFICATE_INVALID and + replacing it with more precise errors. * PurpleConnectionUiOps.report_disconnect now passes a PurpleConnectionError as the second parameter * PurpleXfer.bytes_remaining is now a goffset @@ -142,6 +151,7 @@ * _PurplePrivacyType * _PurpleSoundEventID * _XMLNodeType + * account-authorization-requested-with-message signal * GtkIMHtml.clipboard_html_string * GtkIMHtml.clipboard_text_string * GtkIMHtmlFontDetail @@ -155,12 +165,16 @@ * pidgin_check_if_dir * PIDGIN_DIALOG * pidgin_dialogs_alias_contact + * pidgin_mini_dialog_links_supported * pidgin_set_custom_buddy_icon - * pidgin_setup_screenname_autocomplete + * pidgin_setup_screenname_autocomplete_with_filter * PidginBuddyList.connection_errors * PidginConversation.sg * purple_account_add_buddies_with_invite * purple_account_add_buddy_with_invite + * purple_blist_load + * purple_blist_new + * purple_set_blist * purple_blist_update_buddy_icon * purple_buddy_get_local_alias * purple_buddy_icons_has_custom_icon @@ -192,6 +206,7 @@ * purple_plugins_unregister_load_notify_cb * purple_plugins_unregister_probe_notify_cb * purple_plugins_unregister_unload_notify_cb + * purple_pounces_load * purple_presence_add_status * purple_presence_add_list * purple_proxy_connect_socks5 @@ -216,6 +231,7 @@ * purple_util_fetch_url_request, instead. * purple_util_fetch_url_request_len_with_account. Use purple_util_fetch_url_request, instead. + * PurpleCertificateVerificationStatus.PURPLE_CERTIFICATE_INVALID * PurpleConnectionUiOps.report_disconnect_reason * PurplePluginProtocolInfo.add_buddy_with_invite * PurplePluginProtocolInfo.add_buddies_with_invite
--- a/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -54,13 +54,13 @@ # ... and have no changes in the working copy. (this isn't really necessary with hg because hg id appends a "+") test "x`hg st -mard`" = x -packages: +sign-packages: dist gpg -ab pidgin-$(PACKAGE_VERSION).tar.gz gpg -ab pidgin-$(PACKAGE_VERSION).tar.bz2 gpg --verify pidgin-$(PACKAGE_VERSION).tar.gz.asc pidgin-$(PACKAGE_VERSION).tar.gz gpg --verify pidgin-$(PACKAGE_VERSION).tar.bz2.asc pidgin-$(PACKAGE_VERSION).tar.bz2 -release: commit-check version-check distcheck packages +release: commit-check version-check distcheck sign-packages if INSTALL_I18N PO_DIR=po
--- a/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -31,11 +31,21 @@ exit; \ }' VERSION) -GTK_INSTALL_VERSION = 2.16.6.0 +GTK_INSTALL_VERSION = 2.16.6.1 + +authenticode_sign = $(MONO_SIGNCODE) \ + -spc "$(SIGNCODE_SPC)" -v "$(SIGNCODE_PVK)" \ + -a sha1 -$$ commercial \ + -n "$(2)" -i "https://pidgin.im" \ + -t "http://timestamp.verisign.com/scripts/timstamp.dll" -tr 10 \ + $(1) + +gpg_sign = $(GPG_SIGN) -ab $(1) && $(GPG_SIGN) --verify $(1).asc STRIPPED_RELEASE_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-win32bin DEBUG_SYMBOLS_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-dbgsym +PIDGIN_INST_DEP_DIR="$(WIN32_DEV_TOP)/pidgin-inst-deps-20120910" # Any *.dll or *.exe files included in win32-install-dir that we don't compile # should be included in this list so they don't get stripped @@ -55,9 +65,9 @@ libplc4.dll \ libplds4.dll \ libsasl.dll \ + libssp-0.dll \ libxml2-2.dll \ nss3.dll \ - nssckbi.dll \ nssutil3.dll \ saslANONYMOUS.dll \ saslCRAMMD5.dll \ @@ -77,7 +87,7 @@ include $(PIDGIN_COMMON_RULES) -.PHONY: all docs install installer installer_offline installer_zip debug_symbols_zip installers clean uninstall create_release_install_dir generate_installer_includes $(PIDGIN_REVISION_H) $(PIDGIN_REVISION_RAW_TXT) +.PHONY: all docs install installer installer_offline installer_zip debug_symbols_zip installers clean uninstall create_release_install_dir generate_installer_includes $(PIDGIN_REVISION_H) $(PIDGIN_REVISION_RAW_TXT) gtk_runtime_zip all: $(PIDGIN_CONFIG_H) $(PIDGIN_REVISION_H) $(MAKE) -C $(PURPLE_TOP) -f $(MINGW_MAKEFILE) @@ -98,12 +108,13 @@ cp $(GTKSPELL_TOP)/bin/libgtkspell-0.dll $(PIDGIN_INSTALL_DIR)/spellcheck cp $(ENCHANT_TOP)/bin/libenchant.dll $(PIDGIN_INSTALL_DIR)/spellcheck cp -R $(ENCHANT_TOP)/lib/enchant/*.dll $(PIDGIN_INSTALL_DIR)/spellcheck/lib/enchant - cp $(WIN32_DEV_TOP)/pidgin-inst-deps-20100315/exchndl.dll $(PIDGIN_INSTALL_DIR) + cp $(PIDGIN_INST_DEP_DIR)/exchndl.dll $(PIDGIN_INSTALL_DIR) + cp $(GCC_SSP_TOP)/bin/libssp-0.dll $(PIDGIN_INSTALL_DIR) -pidgin/win32/nsis/gtk-runtime-$(GTK_BUNDLE_VERSION).zip: - pidgin/win32/nsis/generate_gtk_zip.sh `pwd` +gtk_runtime_zip: + pidgin/win32/nsis/generate_gtk_zip.sh "`pwd`" "$(GPG_SIGN)" -generate_installer_includes: create_release_install_dir pidgin/win32/nsis/gtk-runtime-$(GTK_BUNDLE_VERSION).zip debug_symbols_zip $(PIDGIN_TREE_TOP)/pidgin/win32/nsis/nsis_translations.desktop +generate_installer_includes: create_release_install_dir gtk_runtime_zip debug_symbols_zip $(PIDGIN_TREE_TOP)/pidgin/win32/nsis/nsis_translations.desktop rm -f pidgin/win32/nsis/pidgin-translations.nsh pidgin/win32/nsis/pidgin-spellcheck.nsh pidgin/win32/nsis/pidgin-spellcheck-preselect.nsh find $(STRIPPED_RELEASE_DIR)/locale -maxdepth 1 -mindepth 1 \ -exec basename {} ';' \ @@ -137,18 +148,32 @@ find $(STRIPPED_RELEASE_DIR) \( -name '*.dll' -o -name '*.exe' \) \ -not \( -false $(EXTERNAL_DLLS_FIND_EXP) \) \ -exec $(STRIP) --strip-unneeded {} ';' + $(call authenticode_sign, $(STRIPPED_RELEASE_DIR)/pidgin.exe, "Pidgin $(PIDGIN_VERSION)") installer: generate_installer_includes - $(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" pidgin/win32/nsis/pidgin-installer.nsi + $(eval $@_DEBUG_SYMBOLS_SHA1SUM := $(shell sha1sum $(DEBUG_SYMBOLS_DIR).zip | sed -e "s/\ .*$$//")) + $(eval $@_GTK_SHA1SUM := $(shell sha1sum pidgin/win32/nsis/gtk-runtime-$(GTK_INSTALL_VERSION).zip | sed -e "s/\ .*$$//")) + $(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" \ + -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" \ + -DDEBUG_SYMBOLS_SHA1SUM="$($@_DEBUG_SYMBOLS_SHA1SUM)" -DGTK_SHA1SUM="$($@_GTK_SHA1SUM)"\ + pidgin/win32/nsis/pidgin-installer.nsi + $(call authenticode_sign, pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION).exe, "Pidgin Installer") mv pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION).exe ./ + $(call gpg_sign, pidgin-$(PIDGIN_VERSION).exe) installer_offline: generate_installer_includes - $(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" -DOFFLINE_INSTALLER -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" pidgin/win32/nsis/pidgin-installer.nsi + $(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" \ + -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" \ + -DOFFLINE_INSTALLER \ + pidgin/win32/nsis/pidgin-installer.nsi + $(call authenticode_sign, pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION)-offline.exe, "Pidgin Installer") mv pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION)-offline.exe ./ + $(call gpg_sign, pidgin-$(PIDGIN_VERSION)-offline.exe) installer_zip: create_release_install_dir rm -f pidgin-$(PIDGIN_VERSION)-win32-bin.zip zip -9 -r pidgin-$(PIDGIN_VERSION)-win32-bin.zip $(STRIPPED_RELEASE_DIR) + $(call gpg_sign, pidgin-$(PIDGIN_VERSION)-win32-bin.zip) debug_symbols_zip: install rm -rf $(DEBUG_SYMBOLS_DIR) $(DEBUG_SYMBOLS_DIR).zip @@ -156,7 +181,9 @@ tar -cf - `find $(PIDGIN_INSTALL_DIR) \( -name '*.dll' -o -name '*.exe' \) \ -not \( -false $(EXTERNAL_DLLS_FIND_EXP) \) -print` \ | tar --strip 2 --xform s/$$/.dbgsym/ -xC $(DEBUG_SYMBOLS_DIR) -f - + cp $(MEANWHILE_TOP)/bin/libmeanwhile-1.dll.unstripped $(DEBUG_SYMBOLS_DIR)/libmeanwhile-1.dll.dbgsym zip -9 -r $(DEBUG_SYMBOLS_DIR).zip $(DEBUG_SYMBOLS_DIR) + $(call gpg_sign, $(DEBUG_SYMBOLS_DIR).zip) installers: installer installer_offline debug_symbols_zip installer_zip
--- a/autogen.sh Sat Feb 02 18:29:35 2013 +0100 +++ b/autogen.sh Sat Feb 02 21:20:08 2013 +0100 @@ -160,5 +160,8 @@ ############################################################################### # Run configure ############################################################################### -echo "running ./configure ${CONFIGURE_FLAGS} $@" -./configure ${CONFIGURE_FLAGS} $@ +if test -z "$NOCONFIGURE"; then + echo "running ./configure ${CONFIGURE_FLAGS} $@" + ./configure ${CONFIGURE_FLAGS} $@ +fi +
--- a/configure.ac Sat Feb 02 18:29:35 2013 +0100 +++ b/configure.ac Sat Feb 02 21:20:08 2013 +0100 @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_PREREQ([2.50]) +AC_PREREQ([2.63]) # UPDATING VERSION NUMBERS FOR RELEASES # @@ -74,9 +74,8 @@ AC_CANONICAL_HOST AC_CONFIG_HEADERS([config.h]) -AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2]) -dnl TODO: Always use AM_SILENT_RULES when we depend on automake >= 1.11 -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_INIT_AUTOMAKE([1.11 -Wno-portability dist-bzip2]) +AM_SILENT_RULES([yes]) PURPLE_MAJOR_VERSION=purple_major_version PURPLE_MINOR_VERSION=purple_minor_version @@ -110,8 +109,8 @@ dnl Checks for programs. AC_PROG_CC AM_PROG_CC_C_O -AC_DISABLE_STATIC -AC_PROG_LIBTOOL +LT_PREREQ([2.2.6]) +LT_INIT([disable-static]) LIBTOOL="$LIBTOOL --silent" AC_PROG_INSTALL PKG_PROG_PKG_CONFIG @@ -158,7 +157,7 @@ [AC_DEFINE([HAVE_GETADDRINFO], [1], [Define to 1 if you have the getaddrinfo function.])], [AC_CHECK_LIB(socket, getaddrinfo, - [AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lsnl $LIBS"], , , -lnsl)]) + [AC_DEFINE([HAVE_GETADDRINFO]) LIBS="-lsocket -lnsl $LIBS"], , -lnsl)]) AC_CHECK_FUNCS(inet_ntop) AC_CHECK_FUNCS(getifaddrs) dnl Check for socklen_t (in Unix98) @@ -208,7 +207,7 @@ AC_MSG_ERROR([unable to find the ceil() function]) ]) -AC_MSG_CHECKING(for fileno()) +AC_MSG_CHECKING([for fileno()]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <stdio.h> @@ -232,7 +231,7 @@ AC_MSG_RESULT(no) ]) -AC_MSG_CHECKING(for the %z format string in strftime()) +AC_MSG_CHECKING([for the %z format string in strftime()]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_SYS_TIME_H #include <sys/time.h> @@ -297,10 +296,10 @@ dnl ####################################################################### dnl # Disable creation and installation of translation files dnl ####################################################################### -AC_ARG_ENABLE(nls, AC_HELP_STRING([--disable-nls], [disable installation of translation files]), enable_i18n="$enableval", enable_i18n=yes) +AC_ARG_ENABLE(nls, AS_HELP_STRING([--disable-nls], [disable installation of translation files]), enable_i18n="$enableval", enable_i18n=yes) if test x$enable_i18n = xyes; then - AC_PROG_INTLTOOL + IT_PROG_INTLTOOL GETTEXT_PACKAGE=pidgin AC_SUBST(GETTEXT_PACKAGE) @@ -332,16 +331,16 @@ AM_CONDITIONAL(INSTALL_I18N, test "x$enable_i18n" = "xyes") dnl ####################################################################### -dnl # Check for GLib 2.16 (required) +dnl # Check for GLib 2.20 (required) dnl ####################################################################### # TODO: gmodule-2.0 is only needed if enable_plugins is 'yes'. It # might be nice to change this check so that it's not required # if enable_plugins is 'no'. -PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [ +PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.20.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [ AC_MSG_RESULT(no) AC_MSG_ERROR([ -You must have GLib 2.16.0 or newer development headers installed to build. +You must have GLib 2.20.0 or newer development headers installed to build. If you have these installed already you may need to install pkg-config so I can find them. @@ -353,7 +352,7 @@ AC_SUBST(GLIB_GENMARSHAL) AC_ARG_WITH([extraversion], - AC_HELP_STRING([--with-extraversion=STRING], + AS_HELP_STRING([--with-extraversion=STRING], [extra version number to be displayed in Help->About and --help (for packagers)]), EXTRA_VERSION=$withval) @@ -363,55 +362,55 @@ AC_DEFINE_UNQUOTED(DISPLAY_VERSION, "$VERSION", [display version info]) fi -AC_ARG_ENABLE(missing-dependencies, [AC_HELP_STRING([--disable-missing-dependencies], +AC_ARG_ENABLE(missing-dependencies, [AS_HELP_STRING([--disable-missing-dependencies], [skip missing dependencies instead of aborting configure])], force_deps="$enableval", force_deps="yes") AC_ARG_WITH(x, [], with_x="$withval", with_x="yes") -AC_ARG_ENABLE(gtkui, [AC_HELP_STRING([--disable-gtkui], +AC_ARG_ENABLE(gtkui, [AS_HELP_STRING([--disable-gtkui], [compile without GTK+ user interface])], enable_gtkui="$enableval", enable_gtkui="yes") -AC_ARG_WITH(gtk, [AC_HELP_STRING([--with-gtk=<version>], +AC_ARG_WITH(gtk, [AS_HELP_STRING([--with-gtk=<version>], [compile with GTK+ 2 or 3 user interface (default: auto)])], with_gtk="$withval", with_gtk="auto") -AC_ARG_ENABLE(consoleui, [AC_HELP_STRING([--disable-consoleui], +AC_ARG_ENABLE(consoleui, [AS_HELP_STRING([--disable-consoleui], [compile without console user interface])], [enable_consoleui=$enableval force_finch=$enableval], [enable_consoleui=yes force_finch=no]) dnl ####################################################################### -dnl # Check for GTK+ 2.10 and other things used by the GTK UI +dnl # Check for GTK+ 2.18 and other things used by the GTK UI dnl ####################################################################### AC_ARG_ENABLE(screensaver, - [AC_HELP_STRING([--disable-screensaver], + [AS_HELP_STRING([--disable-screensaver], [compile without X screensaver extension (used to detect idleness)])], enable_screensaver="$enableval", enable_screensaver="yes") AC_ARG_ENABLE(sm, - [AC_HELP_STRING([--disable-sm], + [AS_HELP_STRING([--disable-sm], [compile without X session management support])], enable_sm="$enableval", enable_sm="yes") AC_ARG_ENABLE(startup-notification, - [AC_HELP_STRING([--disable-startup-notification], + [AS_HELP_STRING([--disable-startup-notification], [compile without startup notification support])], enable_startup_notification="$enableval", enable_startup_notification="yes") AC_ARG_ENABLE(gtkspell, - [AC_HELP_STRING([--disable-gtkspell], + [AS_HELP_STRING([--disable-gtkspell], [compile without GtkSpell automatic spell checking])], enable_gtkspell="$enableval", enable_gtkspell="yes") AC_ARG_ENABLE(gevolution, - [AC_HELP_STRING([--enable-gevolution], + [AS_HELP_STRING([--enable-gevolution], [compile with the Evolution plugin])], enable_gevolution="$enableval", enable_gevolution="no") AC_ARG_ENABLE(cap, - [AC_HELP_STRING([--enable-cap], + [AS_HELP_STRING([--enable-cap], [compile with Contact Availability Prediction plugin])], enable_cap="$enableval", enable_cap="no") AC_ARG_ENABLE(gestures, - [AC_HELP_STRING([--disable-gestures], + [AS_HELP_STRING([--disable-gestures], [compile without the gestures plugin])], enable_gestures="$enableval", enable_gestures="yes") AC_ARG_ENABLE(gcr, - [AC_HELP_STRING([--enable-gcr], + [AS_HELP_STRING([--enable-gcr], [compile with GCR certificate widgets])], enable_gcr="$enableval", enable_gcr="no") @@ -440,20 +439,20 @@ running configure. ])]) elif test "x$with_gtk" = "x2"; then - PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], , [ + PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.18.0], , [ AC_MSG_RESULT(no) AC_MSG_ERROR([ -You must have GTK+ 2.10.0 or newer development headers installed to compile +You must have GTK+ 2.18.0 or newer development headers installed to compile Pidgin. If you want to build only Finch then specify --disable-gtkui when running configure. ])]) elif test "x$with_gtk" = "xauto"; then PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.0.0], [with_gtk=3], [ AC_MSG_RESULT(no) - PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.10.0], [with_gtk=2], [ + PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.18.0], [with_gtk=2], [ AC_MSG_RESULT(no) AC_MSG_ERROR([ -You must have GTK+ 2.10.0 or newer development headers installed to compile +You must have GTK+ 2.18.0 or newer development headers installed to compile Pidgin. If you want to build only Finch then specify --disable-gtkui when running configure. ])])]) @@ -463,6 +462,9 @@ AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) + GTK_PC_MODULE="gtk+-${with_gtk}.0" + AC_SUBST(GTK_PC_MODULE) + dnl We only really need Pango >= 1.4 for decent RTL support PKG_CHECK_MODULES(PANGO, [pango >= 1.4.0], AC_DEFINE(HAVE_PANGO14, 1, [Define if we have Pango 1.4 or newer.]),:) @@ -715,7 +717,7 @@ dnl ####################################################################### GNT_LIBS="" GNT_CFLAGS="" -AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR], +AC_ARG_WITH(ncurses-headers, [AS_HELP_STRING([--with-ncurses-headers=DIR], [compile finch against the ncurses includes in DIR])], [ac_ncurses_includes="$withval"], [ac_ncurses_includes=""]) if test "x$enable_consoleui" = "xyes"; then @@ -816,10 +818,14 @@ AC_SUBST(LIBXML_LIBS) dnl ####################################################################### -dnl # Check for JSON-GLib (required, if compiled with Gadu-Gadu support) +dnl # Check for JSON-GLib (required) dnl ####################################################################### -PKG_CHECK_MODULES([JSON], [json-glib-1.0], [enable_json="yes"], [enable_json="no"]) +PKG_CHECK_MODULES([JSON], [json-glib-1.0 >= 0.14.0], , [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([ +You must have JSON-GLib >= 0.14.0 development headers installed to build. +])]) AC_SUBST(JSON_CFLAGS) AC_SUBST(JSON_LIBS) @@ -846,9 +852,9 @@ dnl # Check for GStreamer dnl ####################################################################### AC_ARG_ENABLE(gstreamer, - [AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])], + [AS_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])], enable_gst="$enableval", enable_gst="yes") -AC_ARG_WITH(gstreamer, [AC_HELP_STRING([--with-gstreamer=<version>], +AC_ARG_WITH(gstreamer, [AS_HELP_STRING([--with-gstreamer=<version>], [compile with GStreamer 0.10 or 1.0 interface (default: auto)])], with_gstreamer="$withval", with_gstreamer="auto") if test "x$enable_gst" != "xno"; then @@ -916,7 +922,7 @@ dnl ####################################################################### if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0"; then AC_ARG_ENABLE(gstreamer-video, - [AC_HELP_STRING([--disable-gstreamer-video], [compile without GStreamer 1.0 Video Overlay support])], + [AS_HELP_STRING([--disable-gstreamer-video], [compile without GStreamer 1.0 Video Overlay support])], enable_gstvideo="$enableval", enable_gstvideo="yes") if test "x$enable_gstvideo" != "xno"; then PKG_CHECK_MODULES(GSTVIDEO, [gstreamer-video-1.0], [ @@ -936,7 +942,7 @@ dnl ####################################################################### if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x0.10"; then AC_ARG_ENABLE(gstreamer-interfaces, - [AC_HELP_STRING([--disable-gstreamer-interfaces], [compile without GStreamer 0.10 interface support])], + [AS_HELP_STRING([--disable-gstreamer-interfaces], [compile without GStreamer 0.10 interface support])], enable_gstinterfaces="$enableval", enable_gstinterfaces="yes") if test "x$enable_gstinterfaces" != "xno"; then PKG_CHECK_MODULES(GSTINTERFACES, [gstreamer-interfaces-0.10], [ @@ -955,7 +961,7 @@ dnl # Check for Farstream dnl ####################################################################### AC_ARG_ENABLE(farstream, - [AC_HELP_STRING([--disable-farstream], [compile without farstream support])], + [AS_HELP_STRING([--disable-farstream], [compile without farstream support])], enable_farstream="$enableval", enable_farstream="yes") if test "x$enable_farstream" != "xno"; then if test "x$with_gstreamer" == "x1.0"; then @@ -986,7 +992,7 @@ dnl # Check for Voice and Video support dnl ####################################################################### AC_ARG_ENABLE(vv, - [AC_HELP_STRING([--disable-vv], [compile without voice and video support])], + [AS_HELP_STRING([--disable-vv], [compile without voice and video support])], enable_vv="$enableval", enable_vv="yes") if test "x$enable_vv" != "xno"; then if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0" -a "x$enable_gstvideo" != "xno" -a "x$enable_farstream" != "xno"; then @@ -1011,7 +1017,7 @@ dnl ####################################################################### AC_ARG_ENABLE(idn, - [AC_HELP_STRING([--disable-idn], [compile without IDN support])], + [AS_HELP_STRING([--disable-idn], [compile without IDN support])], [enable_idn="$enableval" force_idn=$enableval], [enable_idn="yes" force_idn=no]) if test "x$enable_idn" != "xno"; then PKG_CHECK_MODULES(IDN, libidn >= 0.0.0, [ @@ -1034,7 +1040,7 @@ dnl # Check for Meanwhile headers (for Sametime) dnl ####################################################################### AC_ARG_ENABLE(meanwhile, - [AC_HELP_STRING([--disable-meanwhile], + [AS_HELP_STRING([--disable-meanwhile], [compile without meanwhile (required for Sametime support)])], enable_meanwhile="$enableval", enable_meanwhile="yes") if test "x$enable_meanwhile" = "xyes"; then @@ -1056,13 +1062,13 @@ dnl # Check for Native Avahi headers (for Bonjour) dnl ####################################################################### AC_ARG_ENABLE(avahi, - [AC_HELP_STRING([--disable-avahi], + [AS_HELP_STRING([--disable-avahi], [compile without avahi (required for Bonjour support)])], enable_avahi="$enableval", enable_avahi="yes") if test "x$enable_avahi" = "xyes"; then - AC_ARG_WITH(avahi-client-includes, [AC_HELP_STRING([--with-avahi-client-includes=DIR], [compile the Bonjour plugin against the Avahi Client includes in DIR])], [ac_avahi_client_includes="$withval"], [ac_avahi_client_includes="no"]) - AC_ARG_WITH(avahi-client-libs, [AC_HELP_STRING([--with-avahi-client-libs=DIR], [compile the Bonjour plugin against the Avahi Client libs in DIR])], [ac_avahi_client_libs="$withval"], [ac_avahi_client_libs="no"]) + AC_ARG_WITH(avahi-client-includes, [AS_HELP_STRING([--with-avahi-client-includes=DIR], [compile the Bonjour plugin against the Avahi Client includes in DIR])], [ac_avahi_client_includes="$withval"], [ac_avahi_client_includes="no"]) + AC_ARG_WITH(avahi-client-libs, [AS_HELP_STRING([--with-avahi-client-libs=DIR], [compile the Bonjour plugin against the Avahi Client libs in DIR])], [ac_avahi_client_libs="$withval"], [ac_avahi_client_libs="no"]) AVAHI_CFLAGS="" AVAHI_LIBS="" @@ -1109,8 +1115,8 @@ dnl ####################################################################### dnl # Check for SILC client includes and libraries dnl ####################################################################### -AC_ARG_WITH(silc-includes, [AC_HELP_STRING([--with-silc-includes=DIR], [compile the SILC plugin against includes in DIR])], [ac_silc_includes="$withval"], [ac_silc_includes="no"]) -AC_ARG_WITH(silc-libs, [AC_HELP_STRING([--with-silc-libs=DIR], [compile the SILC plugin against the SILC libs in DIR])], [ac_silc_libs="$withval"], [ac_silc_libs="no"]) +AC_ARG_WITH(silc-includes, [AS_HELP_STRING([--with-silc-includes=DIR], [compile the SILC plugin against includes in DIR])], [ac_silc_includes="$withval"], [ac_silc_includes="no"]) +AC_ARG_WITH(silc-libs, [AS_HELP_STRING([--with-silc-libs=DIR], [compile the SILC plugin against the SILC libs in DIR])], [ac_silc_libs="$withval"], [ac_silc_libs="no"]) SILC_CFLAGS="" SILC_LIBS="" have_silc="no" @@ -1156,8 +1162,8 @@ dnl ####################################################################### dnl # Check for Gadu-Gadu client includes and libraries dnl ####################################################################### -AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) -AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) +AC_ARG_WITH(gadu-includes, [AS_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"]) +AC_ARG_WITH(gadu-libs, [AS_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"]) GADU_CFLAGS="" GADU_LIBS="" GADU_LIBGADU_VERSION=1.11.2 @@ -1260,7 +1266,7 @@ AC_ARG_ENABLE(distrib,,,enable_distrib=no) AM_CONDITIONAL(DISTRIB, test "x$enable_distrib" = "xyes") DYNAMIC_PRPLS=all -AC_ARG_WITH(static-prpls, [AC_HELP_STRING([--with-static-prpls], [Link to certain protocols statically])], [STATIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`], [STATIC_PRPLS=""]) +AC_ARG_WITH(static-prpls, [AS_HELP_STRING([--with-static-prpls], [Link to certain protocols statically])], [STATIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`], [STATIC_PRPLS=""]) if test "x$STATIC_PRPLS" != "x" -a "x$DYNAMIC_PRPLS" = "xall"; then DYNAMIC_PRPLS="" fi @@ -1322,7 +1328,7 @@ simple) static_simple=yes ;; yahoo) static_yahoo=yes ;; zephyr) static_zephyr=yes ;; - *) echo "Invalid static protocol $i!!" ; exit ;; + *) echo "Invalid static protocol $i!!" ; exit 1 ;; esac done AM_CONDITIONAL(STATIC_BONJOUR, test "x$static_bonjour" = "xyes") @@ -1343,7 +1349,7 @@ AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init(void) { $load_proto }, [Loads static protocol plugin module initialization functions.]) -AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`]) +AC_ARG_WITH(dynamic_prpls, [AS_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 mxit myspace novell oscar sametime silc simple yahoo zephyr" fi @@ -1376,23 +1382,19 @@ simple) dynamic_simple=yes ;; yahoo) dynamic_yahoo=yes ;; zephyr) dynamic_zephyr=yes ;; - *) echo "Invalid dynamic protocol $i!!" ; exit ;; + *) echo "Invalid dynamic protocol $i!!" ; exit 1 ;; esac done -AC_ARG_ENABLE(plugins, [AC_HELP_STRING([--disable-plugins], [compile without plugin support])], , enable_plugins=yes) -AC_ARG_WITH(krb4, [AC_HELP_STRING([--with-krb4=PREFIX], [compile Zephyr plugin with Kerberos 4 support])], kerberos="$withval", kerberos="no") -AC_ARG_WITH(zephyr, [AC_HELP_STRING([--with-zephyr=PREFIX], [compile Zephyr plugin against external libzephyr])], zephyr="$withval", zephyr="no") +AC_ARG_ENABLE(plugins, [AS_HELP_STRING([--disable-plugins], [compile without plugin support])], , enable_plugins=yes) +AC_ARG_WITH(krb4, [AS_HELP_STRING([--with-krb4=PREFIX], [compile Zephyr plugin with Kerberos 4 support])], kerberos="$withval", kerberos="no") +AC_ARG_WITH(zephyr, [AS_HELP_STRING([--with-zephyr=PREFIX], [compile Zephyr plugin against external libzephyr])], zephyr="$withval", zephyr="no") AM_CONDITIONAL(EXTERNAL_LIBZEPHYR, test "x$zephyr" != "xno") AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_FUNC(uname) -AC_ARG_ENABLE(fortify, [AC_HELP_STRING([--disable-fortify], [compile without FORTIFY_SOURCE support])], , enable_fortify=yes) - -if test \( "x$static_gg" = "xyes" -o "x$dynamic_gg" = "xyes" \) -a "x$enable_json" != "xyes" ; then - AC_MSG_ERROR([json-glib-1.0 not found (required, when compiling with Gadu-Gadu support)]) -fi +AC_ARG_ENABLE(fortify, [AS_HELP_STRING([--disable-fortify], [compile without FORTIFY_SOURCE support])], , enable_fortify=yes) DEBUG_CFLAGS="$DEBUG_CFLAGS -DPURPLE_DISABLE_DEPRECATED -DPIDGIN_DISABLE_DEPRECATED -DFINCH_DISABLE_DEPRECATED -DGNT_DISABLE_DEPRECATED" if test "x$GCC" = "xyes"; then @@ -1485,8 +1487,8 @@ dnl # Check for D-Bus libraries dnl ####################################################################### -AC_ARG_ENABLE(dbus, [AC_HELP_STRING([--disable-dbus], [disable D-Bus support])], , enable_dbus=yes) -AC_ARG_ENABLE(nm, [AC_HELP_STRING([--disable-nm], [disable NetworkManager support (requires D-Bus)])], enable_nm=$enableval, enable_nm=yes) +AC_ARG_ENABLE(dbus, [AS_HELP_STRING([--disable-dbus], [disable D-Bus support])], , enable_dbus=yes) +AC_ARG_ENABLE(nm, [AS_HELP_STRING([--disable-nm], [disable NetworkManager support (requires D-Bus)])], enable_nm=$enableval, enable_nm=yes) if test "x$enable_dbus" = "xyes" ; then AC_CHECK_PROG(enable_dbus, dbus-binding-tool, yes, no) @@ -1544,7 +1546,7 @@ dnl in C (brrrr ...). AC_ARG_WITH([python], - AC_HELP_STRING([--with-python=PATH], + AS_HELP_STRING([--with-python=PATH], [which python interpreter to use for dbus code generation]), PYTHON=$withval) @@ -1578,7 +1580,7 @@ dnl # although a newer dbus is installed. But I have tried to order the dnl # directory searching to keep this situation at a minimum. dnl ########################################################################### -AC_ARG_WITH(dbus-services, [AC_HELP_STRING([--with-dbus-services=<dir>], [where the D-Bus services directory is located.])]) +AC_ARG_WITH(dbus-services, [AS_HELP_STRING([--with-dbus-services=<dir>], [where the D-Bus services directory is located.])]) DBUS_SERVICES_DIR="" @@ -1659,7 +1661,7 @@ dnl ####################################################################### dnl # Check for Mono support dnl ####################################################################### -AC_ARG_ENABLE(mono, [AC_HELP_STRING([--enable-mono], [compile with Mono runtime support (experimental)])], , enable_mono=no) +AC_ARG_ENABLE(mono, [AS_HELP_STRING([--enable-mono], [compile with Mono runtime support (experimental)])], , enable_mono=no) if test x"$enable_mono" = x"yes" ; then PKG_CHECK_MODULES(MONO, mono, [ AC_SUBST(MONO_CFLAGS) @@ -1700,7 +1702,7 @@ dnl ####################################################################### dnl # Check for Perl support dnl ####################################################################### -AC_ARG_ENABLE(perl, [AC_HELP_STRING([--disable-perl], [compile without perl scripting])], , enable_perl=yes) +AC_ARG_ENABLE(perl, [AS_HELP_STRING([--disable-perl], [compile without perl scripting])], , enable_perl=yes) if test "$enable_plugins" = no ; then enable_perl=no @@ -1823,7 +1825,7 @@ dnl # Thanks go to Evolution for the checks. dnl ####################################################################### -AC_ARG_WITH(system-ssl-certs, [AC_HELP_STRING([--with-system-ssl-certs=<dir>], [directory containing system-wide SSL CA certificates])], [ssl_certificates_dir=$withval]) +AC_ARG_WITH(system-ssl-certs, [AS_HELP_STRING([--with-system-ssl-certs=<dir>], [directory containing system-wide SSL CA certificates])], [ssl_certificates_dir=$withval]) SSL_CERTIFICATES_DIR="" if ! test -z "$ssl_certificates_dir" ; then @@ -1893,7 +1895,7 @@ fi AC_ARG_WITH(gnutls-libs, - [AC_HELP_STRING([--with-gnutls-libs=PREFIX], [location of GnuTLS libraries.])], + [AS_HELP_STRING([--with-gnutls-libs=PREFIX], [location of GnuTLS libraries.])], [ with_gnutls_libs="$withval" ]) if test "x$with_gnutls_libs" != "xno" -a \ @@ -1908,8 +1910,8 @@ AC_CACHE_CHECK([for GnuTLS libraries], ac_cv_gnutls_libs, [ - LIBS="$LIBS $with_gnutls_libs -lgnutls -lgcrypt" - AC_TRY_LINK_FUNC(gnutls_init, ac_cv_gnutls_libs="yes", ac_cv_gnutls_libs="no") + LIBS="$LIBS $with_gnutls_libs -lgnutls" + AC_LINK_IFELSE([AC_LANG_CALL([], [gnutls_init])], ac_cv_gnutls_libs="yes", ac_cv_gnutls_libs="no") LIBS="$LIBS_save" ]) @@ -1917,7 +1919,7 @@ AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS]) AC_DEFINE(HAVE_SSL) msg_gnutls="GnuTLS" - GNUTLS_LIBS="$with_gnutls_libs -lgnutls -lgcrypt" + GNUTLS_LIBS="$with_gnutls_libs -lgnutls" enable_gnutls="yes" else @@ -1980,19 +1982,19 @@ looked_for_nss="yes" AC_ARG_WITH(nspr-includes, - [AC_HELP_STRING([--with-nspr-includes=PREFIX], [specify location of Mozilla nspr4 includes.])], + [AS_HELP_STRING([--with-nspr-includes=PREFIX], [specify location of Mozilla nspr4 includes.])], [with_nspr_includes="$withval"]) AC_ARG_WITH(nspr-libs, - [AC_HELP_STRING([--with-nspr-libs=PREFIX], [specify location of Mozilla nspr4 libs.])], + [AS_HELP_STRING([--with-nspr-libs=PREFIX], [specify location of Mozilla nspr4 libs.])], [with_nspr_libs="$withval"]) AC_ARG_WITH(nss-includes, - [AC_HELP_STRING([--with-nss-includes=PREFIX], [specify location of Mozilla nss3 includes.])], + [AS_HELP_STRING([--with-nss-includes=PREFIX], [specify location of Mozilla nss3 includes.])], [with_nss_includes="$withval"]) AC_ARG_WITH(nss-libs, - [AC_HELP_STRING([--with-nss-libs=PREFIX], [specify location of Mozilla nss3 libs.])], + [AS_HELP_STRING([--with-nss-libs=PREFIX], [specify location of Mozilla nss3 libs.])], [with_nss_libs="$withval"]) @@ -2112,7 +2114,7 @@ LDFLAGS="$LDFLAGS" fi - AC_TRY_LINK_FUNC(PR_Init, + AC_LINK_IFELSE([AC_LANG_CALL([], [PR_Init])], [ac_cv_moz_nspr_libs="yes"], [ac_cv_moz_nspr_libs="no"]) @@ -2200,7 +2202,7 @@ LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs" LIBS="$nsslibs $nsprlibs" - AC_TRY_LINK_FUNC(NSS_Init, + AC_LINK_IFELSE([AC_LANG_CALL([], [NSS_Init])], [ac_cv_moz_nss_libs="yes"], [ac_cv_moz_nss_libs="no"]) @@ -2208,7 +2210,7 @@ nsslibs="-lssl3 -lsmime3 -lnss3 -lsoftokn3" LDFLAGS="$LDFLAGS -L$with_nspr_libs -L$with_nss_libs" LIBS="$LIBS $nsslibs" - AC_TRY_LINK_FUNC(NSS_Init, + AC_LINK_IFELSE([AC_LANG_CALL([], [NSS_Init])], [ac_cv_moz_nss_libs="yes"], [ac_cv_moz_nss_libs="no"]) fi @@ -2280,9 +2282,9 @@ dnl ####################################################################### dnl # Check for Tcl dnl ####################################################################### -AC_ARG_ENABLE(tcl, [AC_HELP_STRING([--disable-tcl], +AC_ARG_ENABLE(tcl, [AS_HELP_STRING([--disable-tcl], [compile without Tcl scripting])], enable_tcl="$enableval", enable_tcl="yes") -AC_ARG_WITH(tclconfig, [AC_HELP_STRING([--with-tclconfig=DIR], +AC_ARG_WITH(tclconfig, [AS_HELP_STRING([--with-tclconfig=DIR], [directory containing tclConfig.sh])]) if test "$enable_plugins" = no; then @@ -2359,9 +2361,9 @@ dnl ####################################################################### dnl # Check for Tk dnl ####################################################################### -AC_ARG_ENABLE(tk, [AC_HELP_STRING([--disable-tk], +AC_ARG_ENABLE(tk, [AS_HELP_STRING([--disable-tk], [compile without Tcl support for Tk])], enable_tk="$enableval", enable_tk="yes") -AC_ARG_WITH(tkconfig, [AC_HELP_STRING([--with-tkconfig=DIR], +AC_ARG_WITH(tkconfig, [AS_HELP_STRING([--with-tkconfig=DIR], [directory containing tkConfig.sh])]) if test "$enable_tcl" = yes -a "$enable_tk" = yes; then @@ -2443,7 +2445,7 @@ dnl AC_CHECK_SIZEOF(short) AC_CHECK_FUNCS(snprintf connect) AC_SUBST(SASL_LIBS) -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) +AC_ARG_ENABLE(cyrus-sasl, AS_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) @@ -2594,14 +2596,14 @@ dnl ####################################################################### dnl # Disable pixmap installation dnl ####################################################################### -AC_ARG_ENABLE(pixmaps-install, AC_HELP_STRING([--disable-pixmaps-install], [disable installation of pixmap files - Pidgin still needs them!]), enable_pixmaps="$enableval", enable_pixmaps=yes) +AC_ARG_ENABLE(pixmaps-install, AS_HELP_STRING([--disable-pixmaps-install], [disable installation of pixmap files - Pidgin still needs them!]), enable_pixmaps="$enableval", enable_pixmaps=yes) AM_CONDITIONAL(INSTALL_PIXMAPS, test "x$enable_pixmaps" = "xyes") dnl ####################################################################### dnl # Tweak status tray icon installation directory dnl ####################################################################### -AC_ARG_ENABLE(trayicon-compat, AC_HELP_STRING([--enable-trayicon-compat], [install tray icons in location compatible with older releases of hicolor-icon-theme]), enable_traycompat="$enableval", enable_traycompat=no) +AC_ARG_ENABLE(trayicon-compat, AS_HELP_STRING([--enable-trayicon-compat], [install tray icons in location compatible with older releases of hicolor-icon-theme]), enable_traycompat="$enableval", enable_traycompat=no) AM_CONDITIONAL(ENABLE_TRAYCOMPAT, test "x$enable_traycompat" = "xyes") @@ -2609,15 +2611,15 @@ dnl # Check for Doxygen and dot (part of GraphViz) dnl ####################################################################### AC_ARG_ENABLE(doxygen, - [AC_HELP_STRING([--disable-doxygen], + [AS_HELP_STRING([--disable-doxygen], [disable documentation with doxygen])], enable_doxygen="$enableval", enable_doxygen="yes") AC_ARG_ENABLE(dot, - [AC_HELP_STRING([--disable-dot], + [AS_HELP_STRING([--disable-dot], [disable graphs in doxygen via 'dot'])], enable_dot="$enableval", enable_dot="yes") AC_ARG_ENABLE(devhelp, - [AC_HELP_STRING([--disable-devhelp], + [AS_HELP_STRING([--disable-devhelp], [disable building index for devhelp documentation browser])], enable_devhelp="$enableval", enable_devhelp="yes") @@ -2662,7 +2664,7 @@ AM_CONDITIONAL(HAVE_DOXYGEN, test "x$enable_doxygen" = "xyes") AM_CONDITIONAL(HAVE_XSLTPROC, test "x$enable_devhelp" = "xyes") -AC_ARG_ENABLE(debug, [AC_HELP_STRING([--enable-debug], +AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], [compile with debugging support])], , enable_debug=no) if test "x$enable_debug" = "xyes" ; then @@ -2783,7 +2785,6 @@ echo Use startup notification...... : $enable_startup_notification echo Build with GtkSpell support... : $enable_gtkspell echo Build with GCR widgets........ : $enable_gcr -echo Build with JSON support....... : $enable_json echo echo Build with plugin support..... : $enable_plugins echo Build with Mono support....... : $enable_mono
--- a/doc/account-signals.dox Sat Feb 02 18:29:35 2013 +0100 +++ b/doc/account-signals.dox Sat Feb 02 21:20:08 2013 +0100 @@ -14,7 +14,6 @@ @signal account-actions-changed @signal account-alias-changed @signal account-authorization-requested - @signal account-authorization-requested-with-message @signal account-authorization-denied @signal account-authorization-granted @signal account-error-changed @@ -145,51 +144,41 @@ @signaldef account-authorization-requested @signalproto -int (*account_authorization_requested)(PurpleAccount *account, const char *user); +int (*account_authorization_requested)(PurpleAccount *account, const char *user, const char *message, char **response); @endsignalproto @signaldesc Emitted when a user requests authorization. - @param account The account. - @param user The name of the user requesting authorization. - @return Less than zero to deny the request without prompting, greater - than zero if the request should be granted. If zero is returned, - then the user will be prompted with the request. - @endsignaldef - - @signaldef account-authorization-requested-with-message - @signalproto -int (*account_authorization_requested)(PurpleAccount *account, const char *user, const char *message); - @endsignalproto - @signaldesc - Emitted when a user requests authorization. - @param account The account. - @param user The name of the user requesting authorization. - @param message The authorization request message + @param account The account. + @param user The name of the user requesting authorization. + @param message The authorization request message. + @param response The message to send in the response. @return PURPLE_ACCOUNT_RESPONSE_IGNORE to silently ignore the request, PURPLE_ACCOUNT_RESPONSE_DENY to block the request (the sender might - get informed, PURPLE_ACCOUNT_RESPONSE_ACCEPT if the request should be + get informed), PURPLE_ACCOUNT_RESPONSE_ACCEPT if the request should be granted. If PURPLE_ACCOUNT_RESPONSE_PASS is returned, then the user will be prompted with the request. @endsignaldef @signaldef account-authorization-denied @signalproto -void (*account_authorization_denied)(PurpleAccount *account, const char *user); +void (*account_authorization_denied)(PurpleAccount *account, const char *user, const char *message); @endsignalproto @signaldesc Emitted when the authorization request for a buddy is denied. @param account The account. @param user The name of the user requesting authorization. + @param message The message to tell the buddy who was denied. @endsignaldef @signaldef account-authorization-granted @signalproto -void (*account_authorization_granted)(PurpleAccount *account, const char *user); +void (*account_authorization_granted)(PurpleAccount *account, const char *user, const char *message); @endsignalproto @signaldesc Emitted when the authorization request for a buddy is granted. @param account The account. @param user The name of the user requesting authorization. + @param message The message to tell the buddy who was granted authorization. @endsignaldef @signaldef account-error-changed
--- a/finch/finch.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/finch.c Sat Feb 02 21:20:08 2013 +0100 @@ -219,11 +219,7 @@ gnt_input_add, g_source_remove, NULL, /* input_get_error */ -#if GLIB_CHECK_VERSION(2,14,0) g_timeout_add_seconds, -#else - NULL, -#endif /* padding */ NULL, @@ -381,19 +377,12 @@ abort(); } - /* TODO: Move blist loading into purple_blist_init() */ - purple_set_blist(purple_blist_new()); - purple_blist_load(); - /* TODO: should this be moved into finch_prefs_init() ? */ finch_prefs_update_old(); /* load plugins we had when we quit */ purple_plugins_load_saved("/finch/plugins/loaded"); - /* TODO: Move pounces loading into purple_pounces_init() */ - purple_pounces_load(); - if (opt_nologin) { /* Set all accounts to "offline" */
--- a/finch/gntaccount.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/gntaccount.c Sat Feb 02 21:20:08 2013 +0100 @@ -1036,7 +1036,7 @@ static void authorize_and_add_cb(auth_and_add *aa) { - aa->auth_cb(aa->data); + aa->auth_cb(NULL, aa->data); purple_blist_request_add_buddy(aa->account, aa->username, NULL, aa->alias); } @@ -1044,7 +1044,7 @@ static void deny_no_add_cb(auth_and_add *aa) { - aa->deny_cb(aa->data); + aa->deny_cb(NULL, aa->data); } static void *
--- a/finch/gntconv.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/gntconv.c Sat Feb 02 21:20:08 2013 +0100 @@ -383,7 +383,7 @@ 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)); + PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL)); } list = list->next; }
--- a/finch/libgnt/gnt.h Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gnt.h Sat Feb 02 21:20:08 2013 +0100 @@ -40,19 +40,6 @@ #include "gntkeys.h" /** - * Get things to compile in Glib < 2.8 - */ -#if !GLIB_CHECK_VERSION(2,8,0) - #define G_PARAM_STATIC_NAME G_PARAM_PRIVATE - #define G_PARAM_STATIC_NICK G_PARAM_PRIVATE - #define G_PARAM_STATIC_BLURB G_PARAM_PRIVATE -#endif - -#if !GLIB_CHECK_VERSION(2,14,0) - #define g_timeout_add_seconds(time, callback, data) g_timeout_add(time * 1000, callback, data) -#endif - -/** * Initialize GNT. */ void gnt_init(void);
--- a/finch/libgnt/gntcolors.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntcolors.c Sat Feb 02 21:20:08 2013 +0100 @@ -142,7 +142,6 @@ restore_colors(); } -#if GLIB_CHECK_VERSION(2,6,0) int gnt_colors_get_color(char *key) { @@ -293,8 +292,6 @@ g_strfreev(keys); } -#endif /* GKeyFile */ - int gnt_color_pair(int pair) { return (hascolors ? COLOR_PAIR(pair) :
--- a/finch/libgnt/gntcolors.h Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntcolors.h Sat Feb 02 21:20:08 2013 +0100 @@ -71,7 +71,6 @@ */ void gnt_uninit_colors(void); -#if GLIB_CHECK_VERSION(2,6,0) /** * Parse color information from a file. * @@ -96,7 +95,6 @@ * @since 2.4.0 */ int gnt_colors_get_color(char *key); -#endif /** * Return the appropriate character attribute for a specified color.
--- a/finch/libgnt/gntfilesel.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntfilesel.c Sat Feb 02 21:20:08 2013 +0100 @@ -66,106 +66,6 @@ } } -#if !GLIB_CHECK_VERSION(2,8,0) -/* ripped from glib/gfileutils.c */ -static gchar * -g_build_path_va (const gchar *separator, - gchar **str_array) -{ - GString *result; - gint separator_len = strlen (separator); - gboolean is_first = TRUE; - gboolean have_leading = FALSE; - const gchar *single_element = NULL; - const gchar *next_element; - const gchar *last_trailing = NULL; - gint i = 0; - - result = g_string_new (NULL); - - next_element = str_array[i++]; - - while (TRUE) { - const gchar *element; - const gchar *start; - const gchar *end; - - if (next_element) { - element = next_element; - next_element = str_array[i++]; - } else - break; - - /* Ignore empty elements */ - if (!*element) - continue; - - start = element; - - if (separator_len) { - while (start && - strncmp (start, separator, separator_len) == 0) - start += separator_len; - } - - end = start + strlen (start); - - if (separator_len) { - while (end >= start + separator_len && - strncmp (end - separator_len, separator, separator_len) == 0) - end -= separator_len; - - last_trailing = end; - while (last_trailing >= element + separator_len && - strncmp (last_trailing - separator_len, separator, separator_len) == 0) - last_trailing -= separator_len; - - if (!have_leading) { - /* If the leading and trailing separator strings are in the - * same element and overlap, the result is exactly that element - */ - if (last_trailing <= start) - single_element = element; - - g_string_append_len (result, element, start - element); - have_leading = TRUE; - } else - single_element = NULL; - } - - if (end == start) - continue; - - if (!is_first) - g_string_append (result, separator); - - g_string_append_len (result, start, end - start); - is_first = FALSE; - } - - if (single_element) { - g_string_free (result, TRUE); - return g_strdup (single_element); - } else { - if (last_trailing) - g_string_append (result, last_trailing); - - return g_string_free (result, FALSE); - } -} - -static gchar * -g_build_pathv (const gchar *separator, - gchar **args) -{ - if (!args) - return NULL; - - return g_build_path_va (separator, args); -} - -#endif - static char * process_path(const char *path) {
--- a/finch/libgnt/gntmain.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntmain.c Sat Feb 02 21:20:08 2013 +0100 @@ -675,7 +675,6 @@ return gnt_clipboard_get_string(clipboard); } -#if GLIB_CHECK_VERSION(2,4,0) typedef struct { void (*callback)(int status, gpointer data); @@ -697,13 +696,11 @@ refresh(); refresh_screen(); } -#endif gboolean gnt_giveup_console(const char *wd, char **argv, char **envp, gint *stin, gint *stout, gint *sterr, void (*callback)(int status, gpointer data), gpointer data) { -#if GLIB_CHECK_VERSION(2,4,0) GPid pid = 0; ChildProcess *cp = NULL; @@ -721,18 +718,11 @@ g_child_watch_add(pid, reap_child, cp); return TRUE; -#else - return FALSE; -#endif } gboolean gnt_is_refugee() { -#if GLIB_CHECK_VERSION(2,4,0) return (wm && wm->mode == GNT_KP_MODE_WAIT_ON_CHILD); -#else - return FALSE; -#endif } const char *C_(const char *x)
--- a/finch/libgnt/gntprogressbar.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntprogressbar.c Sat Feb 02 21:20:08 2013 +0100 @@ -36,16 +36,9 @@ struct _GntProgressBar { GntWidget parent; -#if !GLIB_CHECK_VERSION(2,4,0) - GntProgressBarPrivate priv; -#endif }; -#if GLIB_CHECK_VERSION(2,4,0) #define GNT_PROGRESS_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarPrivate)) -#else -#define GNT_PROGRESS_BAR_GET_PRIVATE(o) &(GNT_PROGRESS_BAR(o)->priv) -#endif static GntWidgetClass *parent_class = NULL; @@ -128,9 +121,7 @@ parent_class = GNT_WIDGET_CLASS (klass); -#if GLIB_CHECK_VERSION(2,4,0) g_type_class_add_private (g_class, sizeof (GntProgressBarPrivate)); -#endif parent_class->draw = gnt_progress_bar_draw; parent_class->size_request = gnt_progress_bar_size_request;
--- a/finch/libgnt/gntstyle.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntstyle.c Sat Feb 02 21:20:08 2013 +0100 @@ -35,9 +35,7 @@ #define MAX_WORKSPACES 99 -#if GLIB_CHECK_VERSION(2,6,0) static GKeyFile *gkfile; -#endif static char * str_styles[GNT_STYLES]; static int int_styles[GNT_STYLES]; @@ -50,7 +48,6 @@ char *gnt_style_get_from_name(const char *group, const char *key) { -#if GLIB_CHECK_VERSION(2,6,0) const char *prg = g_get_prgname(); if ((group == NULL || *group == '\0') && prg && g_key_file_has_group(gkfile, prg)) @@ -58,15 +55,11 @@ if (!group) group = "general"; return g_key_file_get_value(gkfile, group, key, NULL); -#else - return NULL; -#endif } int gnt_style_get_color(char *group, char *key) { -#if GLIB_CHECK_VERSION(2,6,0) int fg = 0, bg = 0; gsize n; char **vals; @@ -79,14 +72,10 @@ } g_strfreev(vals); return ret; -#else - return 0; -#endif } char **gnt_style_get_string_list(const char *group, const char *key, gsize *length) { -#if GLIB_CHECK_VERSION(2,6,0) const char *prg = g_get_prgname(); if ((group == NULL || *group == '\0') && prg && g_key_file_has_group(gkfile, prg)) @@ -94,9 +83,6 @@ if (!group) group = "general"; return g_key_file_get_string_list(gkfile, group, key, length, NULL); -#else - return NULL; -#endif } gboolean gnt_style_get_bool(GntStyle style, gboolean def) @@ -134,7 +120,6 @@ return def; } -#if GLIB_CHECK_VERSION(2,6,0) static void refine(char *text) { @@ -175,11 +160,9 @@ { return (char *)gnt_key_translate(key); } -#endif void gnt_style_read_workspaces(GntWM *wm) { -#if GLIB_CHECK_VERSION(2,6,0) int i; gchar *name; gsize c; @@ -212,11 +195,10 @@ g_strfreev(titles); } } -#endif } + void gnt_style_read_actions(GType type, GntBindableClass *klass) { -#if GLIB_CHECK_VERSION(2,6,0) char *name; GError *error = NULL; @@ -264,12 +246,10 @@ g_strfreev(keys); } g_free(name); -#endif } gboolean gnt_style_read_menu_accels(const char *name, GHashTable *table) { -#if GLIB_CHECK_VERSION(2,6,0) char *kname; GError *error = NULL; gboolean ret = FALSE; @@ -322,13 +302,10 @@ g_free(kname); return ret; -#endif - return FALSE; } void gnt_styles_get_keyremaps(GType type, GHashTable *hash) { -#if GLIB_CHECK_VERSION(2,6,0) char *name; GError *error = NULL; @@ -373,10 +350,8 @@ } g_free(name); -#endif } -#if GLIB_CHECK_VERSION(2,6,0) static void read_general_style(GKeyFile *kfile) { @@ -419,11 +394,9 @@ } g_strfreev(keys); } -#endif void gnt_style_read_configure_file(const char *filename) { -#if GLIB_CHECK_VERSION(2,6,0) GError *error = NULL; gkfile = g_key_file_new(); @@ -436,7 +409,6 @@ } gnt_colors_parse(gkfile); read_general_style(gkfile); -#endif } void gnt_init_styles() @@ -458,9 +430,7 @@ str_styles[i] = NULL; } -#if GLIB_CHECK_VERSION(2,6,0) g_key_file_free(gkfile); gkfile = NULL; -#endif }
--- a/finch/libgnt/gntwm.c Sat Feb 02 18:29:35 2013 +0100 +++ b/finch/libgnt/gntwm.c Sat Feb 02 21:20:08 2013 +0100 @@ -37,14 +37,7 @@ #endif #include <glib.h> -#if GLIB_CHECK_VERSION(2,6,0) -# include <glib/gstdio.h> -#else -# include <sys/types.h> -# include <sys/stat.h> -# include <fcntl.h> -# define g_fopen open -#endif +#include <glib/gstdio.h> #include <ctype.h> #include <gmodule.h> #include <stdlib.h> @@ -337,7 +330,6 @@ static void read_window_positions(GntWM *wm) { -#if GLIB_CHECK_VERSION(2,6,0) GKeyFile *gfile = g_key_file_new(); char *filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); GError *error = NULL; @@ -379,7 +371,6 @@ g_free(filename); g_key_file_free(gfile); -#endif } static gboolean check_idle(gpointer n) @@ -1753,31 +1744,6 @@ return FALSE; } -#if !GLIB_CHECK_VERSION(2,4,0) -struct -{ - gpointer data; - gpointer value; -} table_find_data; - -static void -table_find_helper(gpointer key, gpointer value, gpointer data) -{ - GHRFunc func = data; - if (func(key, value, table_find_data.data)) - table_find_data.value = value; -} - -static gpointer -g_hash_table_find(GHashTable * table, GHRFunc func, gpointer data) -{ - table_find_data.data = data; - table_find_data.value = NULL; - g_hash_table_foreach(table, table_find_helper, func); - return table_find_data.value; -} -#endif - static GntWS * new_widget_find_workspace(GntWM *wm, GntWidget *widget) {
--- a/libpurple/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -119,6 +119,7 @@ desktopitem.h \ eventloop.h \ ft.h \ + http.h \ idle.h \ imgstore.h \ log.h \ @@ -313,6 +314,7 @@ $(GSTVIDEO_LIBS) \ $(GSTINTERFACES_LIBS) \ $(IDN_LIBS) \ + $(JSON_LIBS) \ ciphers/libpurple-ciphers.la \ -lm @@ -330,7 +332,8 @@ $(GSTVIDEO_CFLAGS) \ $(GSTINTERFACES_CFLAGS) \ $(IDN_CFLAGS) \ - $(NETWORKMANAGER_CFLAGS) + $(NETWORKMANAGER_CFLAGS) \ + $(JSON_CFLAGS) # INSTALL_SSL_CERTIFICATES is true when SSL_CERTIFICATES_DIR is empty. # We want to use SSL_CERTIFICATES_DIR when it's not empty.
--- a/libpurple/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -10,6 +10,19 @@ TARGET = libpurple NEEDED_DLLS = $(LIBXML2_TOP)/bin/libxml2-2.dll +ifeq ($(CYRUS_SASL), 1) +NEEDED_DLLS += $(CYRUS_SASL_TOP)/bin/libsasl.dll + +CYRUS_SASL_PLUGINS = \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslANONYMOUS.dll \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslCRAMMD5.dll \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslDIGESTMD5.dll \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslGSSAPI.dll \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslLOGIN.dll \ + $(CYRUS_SASL_TOP)/bin/sasl2/saslPLAIN.dll + +endif + ## ## INCLUDE PATHS ## @@ -39,10 +52,7 @@ ciphers/gchecksum.c \ ciphers/hmac.c \ ciphers/md4.c \ - ciphers/md5.c \ ciphers/rc4.c \ - ciphers/sha1.c \ - ciphers/sha256.c \ circbuffer.c \ cmds.c \ connection.c \ @@ -126,6 +136,10 @@ install_shallow: $(PURPLE_INSTALL_DIR) $(TARGET).dll cp $(TARGET).dll $(PURPLE_INSTALL_DIR) cp $(NEEDED_DLLS) $(PURPLE_INSTALL_DIR) +ifeq ($(CYRUS_SASL), 1) + mkdir -p $(PURPLE_INSTALL_DIR)/sasl2 + cp $(CYRUS_SASL_PLUGINS) $(PURPLE_INSTALL_DIR)/sasl2 +endif install: install_shallow all $(MAKE) -C $(PURPLE_PROTOS_TOP) -f $(MINGW_MAKEFILE) install
--- a/libpurple/account.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/account.c Sat Feb 02 21:20:08 2013 +0100 @@ -1378,33 +1378,33 @@ } static void -request_auth_cb(void *data) +request_auth_cb(const char *message, void *data) { PurpleAccountRequestInfo *info = data; handles = g_list_remove(handles, info); if (info->auth_cb != NULL) - info->auth_cb(info->userdata); + info->auth_cb(message, info->userdata); purple_signal_emit(purple_accounts_get_handle(), - "account-authorization-granted", info->account, info->user); + "account-authorization-granted", info->account, info->user, message); purple_account_request_info_unref(info); } static void -request_deny_cb(void *data) +request_deny_cb(const char *message, void *data) { PurpleAccountRequestInfo *info = data; handles = g_list_remove(handles, info); if (info->deny_cb != NULL) - info->deny_cb(info->userdata); + info->deny_cb(message, info->userdata); purple_signal_emit(purple_accounts_get_handle(), - "account-authorization-denied", info->account, info->user); + "account-authorization-denied", info->account, info->user, message); purple_account_request_info_unref(info); } @@ -1417,6 +1417,7 @@ PurpleAccountUiOps *ui_ops; PurpleAccountRequestInfo *info; int plugin_return; + char *response = NULL; g_return_val_if_fail(account != NULL, NULL); g_return_val_if_fail(remote_user != NULL, NULL); @@ -1424,40 +1425,31 @@ ui_ops = purple_accounts_get_ui_ops(); plugin_return = GPOINTER_TO_INT( - purple_signal_emit_return_1(purple_accounts_get_handle(), - "account-authorization-requested", account, remote_user)); - - if (plugin_return > 0) { - if (auth_cb != NULL) - auth_cb(user_data); - return NULL; - } else if (plugin_return < 0) { - if (deny_cb != NULL) - deny_cb(user_data); - return NULL; - } - - plugin_return = GPOINTER_TO_INT( purple_signal_emit_return_1( purple_accounts_get_handle(), - "account-authorization-requested-with-message", - account, remote_user, message + "account-authorization-requested", + account, remote_user, message, &response )); switch (plugin_return) { case PURPLE_ACCOUNT_RESPONSE_IGNORE: + g_free(response); return NULL; case PURPLE_ACCOUNT_RESPONSE_ACCEPT: if (auth_cb != NULL) - auth_cb(user_data); + auth_cb(response, user_data); + g_free(response); return NULL; case PURPLE_ACCOUNT_RESPONSE_DENY: if (deny_cb != NULL) - deny_cb(user_data); + deny_cb(response, user_data); + g_free(response); return NULL; } + g_free(response); + if (ui_ops != NULL && ui_ops->request_authorize != NULL) { info = g_new0(PurpleAccountRequestInfo, 1); info->type = PURPLE_ACCOUNT_REQUEST_AUTHORIZATION; @@ -3088,29 +3080,26 @@ purple_value_new(PURPLE_TYPE_STRING)); purple_signal_register(handle, "account-authorization-requested", - purple_marshal_INT__POINTER_POINTER, - purple_value_new(PURPLE_TYPE_INT), 2, + purple_marshal_INT__POINTER_POINTER_POINTER, + purple_value_new(PURPLE_TYPE_INT), 4, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), + purple_value_new(PURPLE_TYPE_STRING), purple_value_new(PURPLE_TYPE_STRING)); - purple_signal_register(handle, "account-authorization-requested-with-message", - purple_marshal_INT__POINTER_POINTER_POINTER, - purple_value_new(PURPLE_TYPE_INT), 3, + purple_signal_register(handle, "account-authorization-denied", + purple_marshal_VOID__POINTER_POINTER, NULL, 3, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT), purple_value_new(PURPLE_TYPE_STRING), purple_value_new(PURPLE_TYPE_STRING)); - purple_signal_register(handle, "account-authorization-denied", - purple_marshal_VOID__POINTER_POINTER, NULL, 2, + + purple_signal_register(handle, "account-authorization-granted", + purple_marshal_VOID__POINTER_POINTER, NULL, 3, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT), - purple_value_new(PURPLE_TYPE_STRING)); - - purple_signal_register(handle, "account-authorization-granted", - purple_marshal_VOID__POINTER_POINTER, NULL, 2, - purple_value_new(PURPLE_TYPE_SUBTYPE, - PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), purple_value_new(PURPLE_TYPE_STRING)); purple_signal_register(handle, "account-error-changed",
--- a/libpurple/account.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/account.h Sat Feb 02 21:20:08 2013 +0100 @@ -36,7 +36,7 @@ typedef struct _PurpleAccount PurpleAccount; typedef gboolean (*PurpleFilterAccountFunc)(PurpleAccount *account); -typedef void (*PurpleAccountRequestAuthorizationCb)(void *); +typedef void (*PurpleAccountRequestAuthorizationCb)(const char *, void *); typedef void (*PurpleAccountRegistrationCb)(PurpleAccount *account, gboolean succeeded, void *user_data); typedef void (*PurpleAccountUnregistrationCb)(PurpleAccount *account, gboolean succeeded, void *user_data); typedef void (*PurpleSetPublicAliasSuccessCallback)(PurpleAccount *account, const char *new_alias); @@ -97,7 +97,8 @@ /** Prompt for authorization when someone adds this account to their buddy * list. To authorize them to see this account's presence, call \a - * authorize_cb (\a user_data); otherwise call \a deny_cb (\a user_data); + * authorize_cb (\a message, \a user_data); otherwise call + * \a deny_cb (\a message, \a user_data); * @return a UI-specific handle, as passed to #close_account_request. */ void *(*request_authorize)(PurpleAccount *account,
--- a/libpurple/blist.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/blist.c Sat Feb 02 21:20:08 2013 +0100 @@ -597,9 +597,8 @@ } } -/* TODO: Make static and rename to load_blist */ -void -purple_blist_load() +static void +load_blist(void) { xmlnode *purple, *blist, *privacy; @@ -721,7 +720,8 @@ * Public API functions * *****************************************************************************/ -PurpleBuddyList *purple_blist_new() +void +purple_blist_boot(void) { PurpleBlistUiOps *ui_ops; GList *account; @@ -749,13 +749,9 @@ if (ui_ops != NULL && ui_ops->new_list != NULL) ui_ops->new_list(gbl); - return gbl; -} - -void -purple_set_blist(PurpleBuddyList *list) -{ - purplebuddylist = list; + purplebuddylist = gbl; + + load_blist(); } PurpleBuddyList *
--- a/libpurple/blist.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/blist.h Sat Feb 02 21:20:08 2013 +0100 @@ -252,22 +252,6 @@ /*@{*/ /** - * Creates a new buddy list - * - * @return The new buddy list. - * @deprecated In 3.0.0, this will be handled by purple_blist_init() - */ -PurpleBuddyList *purple_blist_new(void); - -/** - * Sets the main buddy list. - * - * @param blist The buddy list you want to use. - * @deprecated In 3.0.0, this will be handled by purple_blist_init() - */ -void purple_set_blist(PurpleBuddyList *blist); - -/** * Returns the main buddy list. * * @return The main buddy list. @@ -1008,11 +992,6 @@ /****************************************************************************************/ /** - * Loads the buddy list from ~/.purple/blist.xml. - */ -void purple_blist_load(void); - -/** * Schedule a save of the blist.xml file. This is used by the privacy * API whenever the privacy settings are changed. If you make a change * to blist.xml using one of the functions in the buddy list API, then @@ -1204,6 +1183,13 @@ void purple_blist_init(void); /** + * Loads the buddy list. + * + * You shouldn't call this. purple_core_init() will do it for you. + */ +void purple_blist_boot(void); + +/** * Uninitializes the buddy list subsystem. */ void purple_blist_uninit(void);
--- a/libpurple/buddyicon.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/buddyicon.c Sat Feb 02 21:20:08 2013 +0100 @@ -42,7 +42,7 @@ the icon data. */ char *username; /**< The username the icon belongs to. */ char *checksum; /**< The protocol checksum. */ - int ref_count; /**< The buddy icon reference count. */ + unsigned int ref_count; /**< The buddy icon reference count. */ }; /** @@ -75,7 +75,7 @@ static GHashTable *icon_data_cache = NULL; /** - * This hash table contains references counts for how many times each + * This hash table contains reference counts for how many times each * icon in the ~/.purple/icons/ directory is being used. It's pretty * crazy. It maintains the reference count across sessions, too, so * if you exit Pidgin then this hash table is reconstructed the next @@ -156,7 +156,7 @@ if (!purple_buddy_icons_is_caching()) return; - dirname = purple_buddy_icons_get_cache_dir(); + dirname = purple_buddy_icons_get_cache_dir(); path = g_build_filename(dirname, purple_imgstore_get_filename(img), NULL); if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) @@ -189,7 +189,7 @@ if (GPOINTER_TO_INT(g_hash_table_lookup(icon_file_cache, filename))) return; - dirname = purple_buddy_icons_get_cache_dir(); + dirname = purple_buddy_icons_get_cache_dir(); path = g_build_filename(dirname, filename, NULL); if (g_file_test(path, G_FILE_TEST_EXISTS)) @@ -243,36 +243,26 @@ } static PurpleStoredImage * -purple_buddy_icon_data_new(guchar *icon_data, size_t icon_len, const char *filename) +purple_buddy_icon_data_new(guchar *icon_data, size_t icon_len) { char *file; PurpleStoredImage *img; g_return_val_if_fail(icon_data != NULL, NULL); - g_return_val_if_fail(icon_len > 0, NULL); + g_return_val_if_fail(icon_len > 0, NULL); - if (filename == NULL) - { - file = purple_util_get_image_filename(icon_data, icon_len); - if (file == NULL) - { - g_free(icon_data); - return NULL; - } - } - else - file = g_strdup(filename); + file = purple_util_get_image_filename(icon_data, icon_len); - if ((img = g_hash_table_lookup(icon_data_cache, file))) - { + img = g_hash_table_lookup(icon_data_cache, file); + if (img) { g_free(file); g_free(icon_data); return purple_imgstore_ref(img); } - img = purple_imgstore_add(icon_data, icon_len, file); + img = purple_imgstore_new(icon_data, icon_len, file); - /* This will take ownership of file and g_free it either now or later. */ + /* This will take ownership of file and free it as needed */ g_hash_table_insert(icon_data_cache, file, img); purple_buddy_icon_data_cache(img); @@ -352,13 +342,13 @@ return icon; } -PurpleBuddyIcon * +void purple_buddy_icon_unref(PurpleBuddyIcon *icon) { if (icon == NULL) - return NULL; + return; - g_return_val_if_fail(icon->ref_count > 0, NULL); + g_return_if_fail(icon->ref_count > 0); icon->ref_count--; @@ -375,11 +365,7 @@ PURPLE_DBUS_UNREGISTER_POINTER(icon); g_slice_free(PurpleBuddyIcon, icon); - - return NULL; } - - return icon; } void @@ -469,7 +455,7 @@ if (data != NULL) { if (len > 0) - icon->img = purple_buddy_icon_data_new(data, len, NULL); + icon->img = purple_buddy_icon_data_new(data, len); else g_free(data); } @@ -638,6 +624,7 @@ if ((icon_cache == NULL) || ((icon = g_hash_table_lookup(icon_cache, username)) == NULL)) { + /* The icon is not currently cached in memory--try reading from disk */ PurpleBuddy *b = purple_find_buddy(account, username); const char *protocol_icon_file; const char *dirname; @@ -729,9 +716,8 @@ PurpleStoredImage *img = NULL; char *old_icon; - if (icon_data != NULL && icon_len > 0) - { - img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); + if (icon_data != NULL && icon_len > 0) { + img = purple_buddy_icon_data_new(icon_data, icon_len); } old_icon = g_strdup(purple_account_get_string(account, "buddy_icon", NULL)); @@ -864,7 +850,7 @@ old_img = g_hash_table_lookup(pointer_icon_cache, node); if (icon_data != NULL && icon_len > 0) { - img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); + img = purple_buddy_icon_data_new(icon_data, icon_len); } old_icon = g_strdup(purple_blist_node_get_string(node, @@ -1093,7 +1079,7 @@ pointer_icon_cache = g_hash_table_new(g_direct_hash, g_direct_equal); if (!cache_dir) - cache_dir = g_build_filename(purple_user_dir(), "icons", NULL); + cache_dir = g_build_filename(purple_user_dir(), "icons", NULL); purple_signal_connect(purple_imgstore_get_handle(), "image-deleting", purple_buddy_icons_get_handle(),
--- a/libpurple/buddyicon.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/buddyicon.h Sat Feb 02 21:20:08 2013 +0100 @@ -49,8 +49,8 @@ /** * Creates a new buddy icon structure and populates it. * - * If the buddy icon already exists, you'll get a reference to that structure, - * which will have been updated with the data supplied. + * If an icon for this account+username already exists, you'll get a reference + * to that structure, which will have been updated with the data supplied. * * @param account The account the user is on. * @param username The username the icon belongs to. @@ -79,10 +79,8 @@ * If the reference count reaches 0, the icon will be destroyed. * * @param icon The buddy icon. - * - * @return @a icon, or @c NULL if the reference count reached 0. */ -PurpleBuddyIcon *purple_buddy_icon_unref(PurpleBuddyIcon *icon); +void purple_buddy_icon_unref(PurpleBuddyIcon *icon); /** * Updates every instance of this icon. @@ -331,7 +329,7 @@ /** * Sets whether or not buddy icon caching is enabled. * - * @param caching TRUE of buddy icon caching should be enabled, or + * @param caching TRUE if buddy icon caching should be enabled, or * FALSE otherwise. */ void purple_buddy_icons_set_caching(gboolean caching);
--- a/libpurple/certificate.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/certificate.c Sat Feb 02 21:20:08 2013 +0100 @@ -41,53 +41,8 @@ /** List of registered Pools */ static GList *cert_pools = NULL; -/* - * TODO: Merge this with PurpleCertificateVerificationStatus for 3.0.0 */ -typedef enum { - PURPLE_CERTIFICATE_UNKNOWN_ERROR = -1, - - /* Not an error */ - PURPLE_CERTIFICATE_NO_PROBLEMS = 0, - - /* Non-fatal */ - PURPLE_CERTIFICATE_NON_FATALS_MASK = 0x0000FFFF, - - /* The certificate is self-signed. */ - PURPLE_CERTIFICATE_SELF_SIGNED = 0x01, - - /* The CA is not in libpurple's pool of certificates. */ - PURPLE_CERTIFICATE_CA_UNKNOWN = 0x02, - - /* The current time is before the certificate's specified - * activation time. - */ - PURPLE_CERTIFICATE_NOT_ACTIVATED = 0x04, - - /* The current time is after the certificate's specified expiration time */ - PURPLE_CERTIFICATE_EXPIRED = 0x08, - - /* The certificate's subject name doesn't match the expected */ - PURPLE_CERTIFICATE_NAME_MISMATCH = 0x10, - - /* No CA pool was found. This shouldn't happen... */ - PURPLE_CERTIFICATE_NO_CA_POOL = 0x20, - - /* Fatal */ - PURPLE_CERTIFICATE_FATALS_MASK = 0xFFFF0000, - - /* The signature chain could not be validated. Due to limitations in the - * the current API, this also indicates one of the CA certificates in the - * chain is expired (or not yet activated). FIXME 3.0.0 */ - PURPLE_CERTIFICATE_INVALID_CHAIN = 0x10000, - - /* The signature has been revoked. */ - PURPLE_CERTIFICATE_REVOKED = 0x20000, - - PURPLE_CERTIFICATE_LAST = 0x40000, -} PurpleCertificateInvalidityFlags; - static const gchar * -invalidity_reason_to_string(PurpleCertificateInvalidityFlags flag) +invalidity_reason_to_string(PurpleCertificateVerificationStatus flag) { switch (flag) { case PURPLE_CERTIFICATE_SELF_SIGNED: @@ -121,6 +76,9 @@ case PURPLE_CERTIFICATE_REVOKED: return _("The certificate has been revoked."); break; + case PURPLE_CERTIFICATE_REJECTED: + return _("The certificate was rejected by the user."); + break; case PURPLE_CERTIFICATE_UNKNOWN_ERROR: default: return _("An unknown certificate error occurred."); @@ -700,7 +658,7 @@ "VRQ on cert from %s rejected\n", vrq->subject_name); - purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID); + purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_REJECTED); } static void @@ -1319,7 +1277,7 @@ purple_debug_warning("certificate/x509/tls_cached", "User REJECTED cert\n"); - purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID); + purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_REJECTED); } /** Validates a certificate by asking the user @@ -1351,11 +1309,11 @@ static void x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq, - PurpleCertificateInvalidityFlags flags); + PurpleCertificateVerificationStatus flags); static void x509_tls_cached_complete(PurpleCertificateVerificationRequest *vrq, - PurpleCertificateInvalidityFlags flags) + PurpleCertificateVerificationStatus flags) { PurpleCertificatePool *tls_peers; PurpleCertificate *peer_crt = vrq->cert_chain->data; @@ -1377,13 +1335,16 @@ secondary = g_strconcat(tmp, " ", error, NULL); g_free(tmp); + purple_debug_error("certificate/x509/tls_cached", + "Unable to validate certificate: %s\n", secondary); + purple_notify_error(NULL, /* TODO: Probably wrong. */ _("SSL Certificate Error"), _("Unable to validate certificate"), secondary); g_free(secondary); - purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID); + purple_certificate_verify_complete(vrq, flags); return; } else if (flags & PURPLE_CERTIFICATE_NON_FATALS_MASK) { /* Non-fatal error. Prompt the user. */ @@ -1448,7 +1409,7 @@ static void x509_tls_cached_cert_in_cache(PurpleCertificateVerificationRequest *vrq, - PurpleCertificateInvalidityFlags flags) + PurpleCertificateVerificationStatus flags) { /* TODO: Looking this up by name over and over is expensive. Fix, please! */ @@ -1502,7 +1463,7 @@ */ static void x509_tls_cached_check_subject_name(PurpleCertificateVerificationRequest *vrq, - PurpleCertificateInvalidityFlags flags) + PurpleCertificateVerificationStatus flags) { PurpleCertificate *peer_crt; GList *chain = vrq->cert_chain; @@ -1531,7 +1492,7 @@ */ static void x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq, - PurpleCertificateInvalidityFlags flags) + PurpleCertificateVerificationStatus flags) { PurpleCertificatePool *ca; PurpleCertificate *peer_crt; @@ -1611,7 +1572,7 @@ * CA, or is a trusted CA (based on fingerprint). */ /* If, for whatever reason, there is no Certificate Authority pool - loaded, we'll verify the subject name and then warn about thsi. */ + loaded, we'll verify the subject name and then warn about this. */ if ( !ca ) { purple_debug_error("certificate/x509/tls_cached", "No X.509 Certificate Authority pool " @@ -1637,8 +1598,6 @@ "Also checking for a CA with DN=%s\n", ca2_id); ca_crts = g_slist_concat(x509_ca_get_certs(ca_id), x509_ca_get_certs(ca2_id)); - g_free(ca_id); - g_free(ca2_id); if ( NULL == ca_crts ) { flags |= PURPLE_CERTIFICATE_CA_UNKNOWN; @@ -1647,6 +1606,8 @@ "found. I'll prompt the user, I guess.\n"); x509_tls_cached_check_subject_name(vrq, flags); + g_free(ca_id); + g_free(ca2_id); return; } @@ -1681,12 +1642,19 @@ g_byte_array_free(ca_fpr, TRUE); } - if (valid == FALSE) + if (valid == FALSE) { + purple_debug_error("certificate/x509/tls_cached", + "Unable to verify final certificate %s signed by %s. " + "Not a trusted root or signed by a trusted root.\n", + ca2_id, ca_id); flags |= PURPLE_CERTIFICATE_INVALID_CHAIN; + } g_slist_foreach(ca_crts, (GFunc)purple_certificate_destroy, NULL); g_slist_free(ca_crts); g_byte_array_free(last_fpr, TRUE); + g_free(ca_id); + g_free(ca2_id); x509_tls_cached_check_subject_name(vrq, flags); } @@ -1697,7 +1665,7 @@ const gchar *tls_peers_name = "tls_peers"; /* Name of local cache */ PurpleCertificatePool *tls_peers; time_t now, activation, expiration; - PurpleCertificateInvalidityFlags flags = PURPLE_CERTIFICATE_NO_PROBLEMS; + PurpleCertificateVerificationStatus flags = PURPLE_CERTIFICATE_VALID; gboolean ret; g_return_if_fail(vrq);
--- a/libpurple/certificate.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/certificate.h Sat Feb 02 21:20:08 2013 +0100 @@ -36,8 +36,49 @@ typedef enum { - PURPLE_CERTIFICATE_INVALID = 0, - PURPLE_CERTIFICATE_VALID = 1 + PURPLE_CERTIFICATE_UNKNOWN_ERROR = -1, + + /* Not an error */ + PURPLE_CERTIFICATE_VALID = 0, + + /* Non-fatal */ + PURPLE_CERTIFICATE_NON_FATALS_MASK = 0x0000FFFF, + + /* The certificate is self-signed. */ + PURPLE_CERTIFICATE_SELF_SIGNED = 0x01, + + /* The CA is not in libpurple's pool of certificates. */ + PURPLE_CERTIFICATE_CA_UNKNOWN = 0x02, + + /* The current time is before the certificate's specified + * activation time. + */ + PURPLE_CERTIFICATE_NOT_ACTIVATED = 0x04, + + /* The current time is after the certificate's specified expiration time */ + PURPLE_CERTIFICATE_EXPIRED = 0x08, + + /* The certificate's subject name doesn't match the expected */ + PURPLE_CERTIFICATE_NAME_MISMATCH = 0x10, + + /* No CA pool was found. This shouldn't happen... */ + PURPLE_CERTIFICATE_NO_CA_POOL = 0x20, + + /* Fatal */ + PURPLE_CERTIFICATE_FATALS_MASK = 0xFFFF0000, + + /* The signature chain could not be validated. Due to limitations in the + * the current API, this also indicates one of the CA certificates in the + * chain is expired (or not yet activated). FIXME 3.0.0 */ + PURPLE_CERTIFICATE_INVALID_CHAIN = 0x10000, + + /* The signature has been revoked. */ + PURPLE_CERTIFICATE_REVOKED = 0x20000, + + /* The certificate was rejected by the user. */ + PURPLE_CERTIFICATE_REJECTED = 0x40000, + + PURPLE_CERTIFICATE_LAST = 0x80000, } PurpleCertificateVerificationStatus; typedef struct _PurpleCertificate PurpleCertificate;
--- a/libpurple/ciphers/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/ciphers/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -5,10 +5,7 @@ gchecksum.c \ hmac.c \ md4.c \ - md5.c \ - rc4.c \ - sha1.c \ - sha256.c + rc4.c INCLUDES = -I$(top_srcdir)/libpurple
--- a/libpurple/ciphers/gchecksum.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/ciphers/gchecksum.c Sat Feb 02 21:20:08 2013 +0100 @@ -1,7 +1,5 @@ #include <cipher.h> -#if GLIB_CHECK_VERSION(2,16,0) - static void purple_g_checksum_init(PurpleCipherContext *context, GChecksumType type) { @@ -19,13 +17,7 @@ checksum = purple_cipher_context_get_data(context); g_return_if_fail(checksum != NULL); -#if GLIB_CHECK_VERSION(2,18,0) g_checksum_reset(checksum); -#else - g_checksum_free(checksum); - checksum = g_checksum_new(type); - purple_cipher_context_set_data(context, checksum); -#endif } static void @@ -139,6 +131,3 @@ PURPLE_G_CHECKSUM_IMPLEMENTATION(md5, MD5, G_CHECKSUM_MD5, 64); PURPLE_G_CHECKSUM_IMPLEMENTATION(sha1, SHA1, G_CHECKSUM_SHA1, 64); PURPLE_G_CHECKSUM_IMPLEMENTATION(sha256, SHA256, G_CHECKSUM_SHA256, 64); - -#endif /* GLIB_CHECK_VERSION(2,16,0) */ -
--- a/libpurple/ciphers/md5.c Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -/* - * purple - * - * Purple 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. - * - * Original md5 - * Copyright (C) 2001-2003 Christophe Devine <c.devine@cr0.net> - * - * This program 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 <cipher.h> - -#if !GLIB_CHECK_VERSION(2,16,0) - -#define MD5_HMAC_BLOCK_SIZE 64 - -struct MD5Context { - guint32 total[2]; - guint32 state[4]; - guchar buffer[64]; -}; - -#define MD5_GET_GUINT32(n,b,i) { \ - (n) = ((guint32)(b) [(i) ] ) \ - | ((guint32)(b) [(i) + 1] << 8) \ - | ((guint32)(b) [(i) + 2] << 16) \ - | ((guint32)(b) [(i) + 3] << 24); \ -} -#define MD5_PUT_GUINT32(n,b,i) { \ - (b)[(i) ] = (guchar)((n) ); \ - (b)[(i) + 1] = (guchar)((n) >> 8); \ - (b)[(i) + 2] = (guchar)((n) >> 16); \ - (b)[(i) + 3] = (guchar)((n) >> 24); \ -} - -static size_t -md5_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return MD5_HMAC_BLOCK_SIZE; -} - -static void -md5_init(PurpleCipherContext *context, gpointer extra) { - struct MD5Context *md5_context; - - md5_context = g_new0(struct MD5Context, 1); - - purple_cipher_context_set_data(context, md5_context); - - purple_cipher_context_reset(context, extra); -} - -static void -md5_reset(PurpleCipherContext *context, gpointer extra) { - struct MD5Context *md5_context; - - md5_context = purple_cipher_context_get_data(context); - - md5_context->total[0] = 0; - md5_context->total[1] = 0; - - md5_context->state[0] = 0x67452301; - md5_context->state[1] = 0xEFCDAB89; - md5_context->state[2] = 0x98BADCFE; - md5_context->state[3] = 0x10325476; - - memset(md5_context->buffer, 0, sizeof(md5_context->buffer)); -} - -static void -md5_uninit(PurpleCipherContext *context) { - struct MD5Context *md5_context; - - purple_cipher_context_reset(context, NULL); - - md5_context = purple_cipher_context_get_data(context); - memset(md5_context, 0, sizeof(*md5_context)); - - g_free(md5_context); - md5_context = NULL; -} - -static void -md5_process(struct MD5Context *md5_context, const guchar data[64]) { - guint32 X[16], A, B, C, D; - - A = md5_context->state[0]; - B = md5_context->state[1]; - C = md5_context->state[2]; - D = md5_context->state[3]; - - MD5_GET_GUINT32(X[ 0], data, 0); - MD5_GET_GUINT32(X[ 1], data, 4); - MD5_GET_GUINT32(X[ 2], data, 8); - MD5_GET_GUINT32(X[ 3], data, 12); - MD5_GET_GUINT32(X[ 4], data, 16); - MD5_GET_GUINT32(X[ 5], data, 20); - MD5_GET_GUINT32(X[ 6], data, 24); - MD5_GET_GUINT32(X[ 7], data, 28); - MD5_GET_GUINT32(X[ 8], data, 32); - MD5_GET_GUINT32(X[ 9], data, 36); - MD5_GET_GUINT32(X[10], data, 40); - MD5_GET_GUINT32(X[11], data, 44); - MD5_GET_GUINT32(X[12], data, 48); - MD5_GET_GUINT32(X[13], data, 52); - MD5_GET_GUINT32(X[14], data, 56); - MD5_GET_GUINT32(X[15], data, 60); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) -#define P(a,b,c,d,k,s,t) { \ - a += F(b,c,d) + X[k] + t; \ - a = S(a,s) + b; \ -} - - /* first pass */ -#define F(x,y,z) (z ^ (x & (y ^ z))) - P(A, B, C, D, 0, 7, 0xD76AA478); - P(D, A, B, C, 1, 12, 0xE8C7B756); - P(C, D, A, B, 2, 17, 0x242070DB); - P(B, C, D, A, 3, 22, 0xC1BDCEEE); - P(A, B, C, D, 4, 7, 0xF57C0FAF); - P(D, A, B, C, 5, 12, 0x4787C62A); - P(C, D, A, B, 6, 17, 0xA8304613); - P(B, C, D, A, 7, 22, 0xFD469501); - P(A, B, C, D, 8, 7, 0x698098D8); - P(D, A, B, C, 9, 12, 0x8B44F7AF); - P(C, D, A, B, 10, 17, 0xFFFF5BB1); - P(B, C, D, A, 11, 22, 0x895CD7BE); - P(A, B, C, D, 12, 7, 0x6B901122); - P(D, A, B, C, 13, 12, 0xFD987193); - P(C, D, A, B, 14, 17, 0xA679438E); - P(B, C, D, A, 15, 22, 0x49B40821); -#undef F - - /* second pass */ -#define F(x,y,z) (y ^ (z & (x ^ y))) - P(A, B, C, D, 1, 5, 0xF61E2562); - P(D, A, B, C, 6, 9, 0xC040B340); - P(C, D, A, B, 11, 14, 0x265E5A51); - P(B, C, D, A, 0, 20, 0xE9B6C7AA); - P(A, B, C, D, 5, 5, 0xD62F105D); - P(D, A, B, C, 10, 9, 0x02441453); - P(C, D, A, B, 15, 14, 0xD8A1E681); - P(B, C, D, A, 4, 20, 0xE7D3FBC8); - P(A, B, C, D, 9, 5, 0x21E1CDE6); - P(D, A, B, C, 14, 9, 0xC33707D6); - P(C, D, A, B, 3, 14, 0xF4D50D87); - P(B, C, D, A, 8, 20, 0x455A14ED); - P(A, B, C, D, 13, 5, 0xA9E3E905); - P(D, A, B, C, 2, 9, 0xFCEFA3F8); - P(C, D, A, B, 7, 14, 0x676F02D9); - P(B, C, D, A, 12, 20, 0x8D2A4C8A); -#undef F - - /* third pass */ -#define F(x,y,z) (x ^ y ^ z) - P(A, B, C, D, 5, 4, 0xFFFA3942); - P(D, A, B, C, 8, 11, 0x8771F681); - P(C, D, A, B, 11, 16, 0x6D9D6122); - P(B, C, D, A, 14, 23, 0xFDE5380C); - P(A, B, C, D, 1, 4, 0xA4BEEA44); - P(D, A, B, C, 4, 11, 0x4BDECFA9); - P(C, D, A, B, 7, 16, 0xF6BB4B60); - P(B, C, D, A, 10, 23, 0xBEBFBC70); - P(A, B, C, D, 13, 4, 0x289B7EC6); - P(D, A, B, C, 0, 11, 0xEAA127FA); - P(C, D, A, B, 3, 16, 0xD4EF3085); - P(B, C, D, A, 6, 23, 0x04881D05); - P(A, B, C, D, 9, 4, 0xD9D4D039); - P(D, A, B, C, 12, 11, 0xE6DB99E5); - P(C, D, A, B, 15, 16, 0x1FA27CF8); - P(B, C, D, A, 2, 23, 0xC4AC5665); -#undef F - - /* forth pass */ -#define F(x,y,z) (y ^ (x | ~z)) - P(A, B, C, D, 0, 6, 0xF4292244); - P(D, A, B, C, 7, 10, 0x432AFF97); - P(C, D, A, B, 14, 15, 0xAB9423A7); - P(B, C, D, A, 5, 21, 0xFC93A039); - P(A, B, C, D, 12, 6, 0x655B59C3); - P(D, A, B, C, 3, 10, 0x8F0CCC92); - P(C, D, A, B, 10, 15, 0xFFEFF47D); - P(B, C, D, A, 1, 21, 0x85845DD1); - P(A, B, C, D, 8, 6, 0x6FA87E4F); - P(D, A, B, C, 15, 10, 0xFE2CE6E0); - P(C, D, A, B, 6, 15, 0xA3014314); - P(B, C, D, A, 13, 21, 0x4E0811A1); - P(A, B, C, D, 4, 6, 0xF7537E82); - P(D, A, B, C, 11, 10, 0xBD3AF235); - P(C, D, A, B, 2, 15, 0x2AD7D2BB); - P(B, C, D, A, 9, 21, 0xEB86D391); -#undef F -#undef P -#undef S - - md5_context->state[0] += A; - md5_context->state[1] += B; - md5_context->state[2] += C; - md5_context->state[3] += D; - } - -static void -md5_append(PurpleCipherContext *context, const guchar *data, size_t len) { - struct MD5Context *md5_context = NULL; - guint32 left = 0, fill = 0; - - g_return_if_fail(context != NULL); - - md5_context = purple_cipher_context_get_data(context); - g_return_if_fail(md5_context != NULL); - - left = md5_context->total[0] & 0x3F; - fill = 64 - left; - - md5_context->total[0] += len; - md5_context->total[0] &= 0xFFFFFFFF; - - if(md5_context->total[0] < len) - md5_context->total[1]++; - - if(left && len >= fill) { - memcpy((md5_context->buffer + left), data, fill); - md5_process(md5_context, md5_context->buffer); - len -= fill; - data += fill; - left = 0; - } - - while(len >= 64) { - md5_process(md5_context, data); - len -= 64; - data += 64; - } - - if(len) { - memcpy((md5_context->buffer + left), data, len); - } -} - - static gboolean -md5_digest(PurpleCipherContext *context, size_t in_len, guchar digest[16], - size_t *out_len) -{ - struct MD5Context *md5_context = NULL; - guint32 last, pad; - guint32 high, low; - guchar message[8]; - guchar padding[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - g_return_val_if_fail(in_len >= 16, FALSE); - - md5_context = purple_cipher_context_get_data(context); - - high = (md5_context->total[0] >> 29) - | (md5_context->total[1] << 3); - low = (md5_context->total[0] << 3); - - MD5_PUT_GUINT32(low, message, 0); - MD5_PUT_GUINT32(high, message, 4); - - last = md5_context->total[0] & 0x3F; - pad = (last < 56) ? (56 - last) : (120 - last); - - md5_append(context, padding, pad); - md5_append(context, message, 8); - - MD5_PUT_GUINT32(md5_context->state[0], digest, 0); - MD5_PUT_GUINT32(md5_context->state[1], digest, 4); - MD5_PUT_GUINT32(md5_context->state[2], digest, 8); - MD5_PUT_GUINT32(md5_context->state[3], digest, 12); - - if(out_len) - *out_len = 16; - - return TRUE; -} - -static PurpleCipherOps MD5Ops = { - NULL, /* Set Option */ - NULL, /* Get Option */ - md5_init, /* init */ - md5_reset, /* reset */ - md5_uninit, /* uninit */ - NULL, /* set iv */ - md5_append, /* append */ - md5_digest, /* digest */ - NULL, /* encrypt */ - NULL, /* decrypt */ - NULL, /* set salt */ - NULL, /* get salt size */ - NULL, /* set key */ - NULL, /* get key size */ - NULL, /* set batch mode */ - NULL, /* get batch mode */ - md5_get_block_size, /* get block size */ - NULL /* set key with len */ -}; - -PurpleCipherOps * -purple_md5_cipher_get_ops(void) { - return &MD5Ops; -} - -#endif /* !GLIB_CHECK_VERSION(2,16,0) */ -
--- a/libpurple/ciphers/sha1.c Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,281 +0,0 @@ -/* - * purple - * - * Purple 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 program 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 <cipher.h> -#include <util.h> - -#if !GLIB_CHECK_VERSION(2,16,0) - -#define SHA1_HMAC_BLOCK_SIZE 64 -#define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) - -struct SHA1Context { - guint32 H[5]; - guint32 W[80]; - - gint lenW; - - guint32 sizeHi; - guint32 sizeLo; -}; - -static size_t -sha1_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return SHA1_HMAC_BLOCK_SIZE; -} - -static void -sha1_hash_block(struct SHA1Context *sha1_ctx) { - gint i; - guint32 A, B, C, D, E, T; - - for(i = 16; i < 80; i++) { - sha1_ctx->W[i] = SHA1_ROTL(sha1_ctx->W[i - 3] ^ - sha1_ctx->W[i - 8] ^ - sha1_ctx->W[i - 14] ^ - sha1_ctx->W[i - 16], 1); - } - - A = sha1_ctx->H[0]; - B = sha1_ctx->H[1]; - C = sha1_ctx->H[2]; - D = sha1_ctx->H[3]; - E = sha1_ctx->H[4]; - - for(i = 0; i < 20; i++) { - T = (SHA1_ROTL(A, 5) + (((C ^ D) & B) ^ D) + E + sha1_ctx->W[i] + 0x5A827999) & 0xFFFFFFFF; - E = D; - D = C; - C = SHA1_ROTL(B, 30); - B = A; - A = T; - } - - for(i = 20; i < 40; i++) { - T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0x6ED9EBA1) & 0xFFFFFFFF; - E = D; - D = C; - C = SHA1_ROTL(B, 30); - B = A; - A = T; - } - - for(i = 40; i < 60; i++) { - T = (SHA1_ROTL(A, 5) + ((B & C) | (D & (B | C))) + E + sha1_ctx->W[i] + 0x8F1BBCDC) & 0xFFFFFFFF; - E = D; - D = C; - C = SHA1_ROTL(B, 30); - B = A; - A = T; - } - - for(i = 60; i < 80; i++) { - T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0xCA62C1D6) & 0xFFFFFFFF; - E = D; - D = C; - C = SHA1_ROTL(B, 30); - B = A; - A = T; - } - - sha1_ctx->H[0] += A; - sha1_ctx->H[1] += B; - sha1_ctx->H[2] += C; - sha1_ctx->H[3] += D; - sha1_ctx->H[4] += E; -} - -static void -sha1_set_opt(PurpleCipherContext *context, const gchar *name, void *value) { - struct SHA1Context *ctx; - - ctx = purple_cipher_context_get_data(context); - - if(purple_strequal(name, "sizeHi")) { - ctx->sizeHi = GPOINTER_TO_INT(value); - } else if(purple_strequal(name, "sizeLo")) { - ctx->sizeLo = GPOINTER_TO_INT(value); - } else if(purple_strequal(name, "lenW")) { - ctx->lenW = GPOINTER_TO_INT(value); - } -} - -static void * -sha1_get_opt(PurpleCipherContext *context, const gchar *name) { - struct SHA1Context *ctx; - - ctx = purple_cipher_context_get_data(context); - - if(purple_strequal(name, "sizeHi")) { - return GINT_TO_POINTER(ctx->sizeHi); - } else if(purple_strequal(name, "sizeLo")) { - return GINT_TO_POINTER(ctx->sizeLo); - } else if(purple_strequal(name, "lenW")) { - return GINT_TO_POINTER(ctx->lenW); - } - - return NULL; -} - -static void -sha1_init(PurpleCipherContext *context, void *extra) { - struct SHA1Context *sha1_ctx; - - sha1_ctx = g_new0(struct SHA1Context, 1); - - purple_cipher_context_set_data(context, sha1_ctx); - - purple_cipher_context_reset(context, extra); -} - -static void -sha1_reset(PurpleCipherContext *context, void *extra) { - struct SHA1Context *sha1_ctx; - gint i; - - sha1_ctx = purple_cipher_context_get_data(context); - - g_return_if_fail(sha1_ctx); - - sha1_ctx->lenW = 0; - sha1_ctx->sizeHi = 0; - sha1_ctx->sizeLo = 0; - - sha1_ctx->H[0] = 0x67452301; - sha1_ctx->H[1] = 0xEFCDAB89; - sha1_ctx->H[2] = 0x98BADCFE; - sha1_ctx->H[3] = 0x10325476; - sha1_ctx->H[4] = 0xC3D2E1F0; - - for(i = 0; i < 80; i++) - sha1_ctx->W[i] = 0; -} - -static void -sha1_uninit(PurpleCipherContext *context) { - struct SHA1Context *sha1_ctx; - - purple_cipher_context_reset(context, NULL); - - sha1_ctx = purple_cipher_context_get_data(context); - - memset(sha1_ctx, 0, sizeof(struct SHA1Context)); - - g_free(sha1_ctx); - sha1_ctx = NULL; -} - -static void -sha1_append(PurpleCipherContext *context, const guchar *data, size_t len) { - struct SHA1Context *sha1_ctx; - gint i; - - sha1_ctx = purple_cipher_context_get_data(context); - - g_return_if_fail(sha1_ctx); - - for(i = 0; i < len; i++) { - sha1_ctx->W[sha1_ctx->lenW / 4] <<= 8; - sha1_ctx->W[sha1_ctx->lenW / 4] |= data[i]; - - if((++sha1_ctx->lenW) % 64 == 0) { - sha1_hash_block(sha1_ctx); - sha1_ctx->lenW = 0; - } - - sha1_ctx->sizeLo += 8; - sha1_ctx->sizeHi += (sha1_ctx->sizeLo < 8); - } -} - -static gboolean -sha1_digest(PurpleCipherContext *context, size_t in_len, guchar digest[20], - size_t *out_len) -{ - struct SHA1Context *sha1_ctx; - guchar pad0x80 = 0x80, pad0x00 = 0x00; - guchar padlen[8]; - gint i; - - g_return_val_if_fail(in_len >= 20, FALSE); - - sha1_ctx = purple_cipher_context_get_data(context); - - g_return_val_if_fail(sha1_ctx, FALSE); - - padlen[0] = (guchar)((sha1_ctx->sizeHi >> 24) & 255); - padlen[1] = (guchar)((sha1_ctx->sizeHi >> 16) & 255); - padlen[2] = (guchar)((sha1_ctx->sizeHi >> 8) & 255); - padlen[3] = (guchar)((sha1_ctx->sizeHi >> 0) & 255); - padlen[4] = (guchar)((sha1_ctx->sizeLo >> 24) & 255); - padlen[5] = (guchar)((sha1_ctx->sizeLo >> 16) & 255); - padlen[6] = (guchar)((sha1_ctx->sizeLo >> 8) & 255); - padlen[7] = (guchar)((sha1_ctx->sizeLo >> 0) & 255); - - /* pad with a 1, then zeroes, then length */ - purple_cipher_context_append(context, &pad0x80, 1); - while(sha1_ctx->lenW != 56) - purple_cipher_context_append(context, &pad0x00, 1); - purple_cipher_context_append(context, padlen, 8); - - for(i = 0; i < 20; i++) { - digest[i] = (guchar)(sha1_ctx->H[i / 4] >> 24); - sha1_ctx->H[i / 4] <<= 8; - } - - purple_cipher_context_reset(context, NULL); - - if(out_len) - *out_len = 20; - - return TRUE; -} - -static PurpleCipherOps SHA1Ops = { - sha1_set_opt, /* Set Option */ - sha1_get_opt, /* Get Option */ - sha1_init, /* init */ - sha1_reset, /* reset */ - sha1_uninit, /* uninit */ - NULL, /* set iv */ - sha1_append, /* append */ - sha1_digest, /* digest */ - NULL, /* encrypt */ - NULL, /* decrypt */ - NULL, /* set salt */ - NULL, /* get salt size */ - NULL, /* set key */ - NULL, /* get key size */ - NULL, /* set batch mode */ - NULL, /* get batch mode */ - sha1_get_block_size, /* get block size */ - NULL /* set key with len */ -}; - -PurpleCipherOps * -purple_sha1_cipher_get_ops(void) { - return &SHA1Ops; -} - -#endif /* !GLIB_CHECK_VERSION(2,16,0) */ -
--- a/libpurple/ciphers/sha256.c Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +0,0 @@ -/* - * purple - * - * Purple 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 program 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 <cipher.h> - -#if !GLIB_CHECK_VERSION(2,16,0) - -#define SHA256_HMAC_BLOCK_SIZE 64 -#define SHA256_ROTR(X,n) ((((X) >> (n)) | ((X) << (32-(n)))) & 0xFFFFFFFF) - -static const guint32 sha256_K[64] = -{ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -struct SHA256Context { - guint32 H[8]; - guint32 W[64]; - - gint lenW; - - guint32 sizeHi; - guint32 sizeLo; -}; - -static size_t -sha256_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return SHA256_HMAC_BLOCK_SIZE; -} - -static void -sha256_hash_block(struct SHA256Context *sha256_ctx) { - gint i; - guint32 A, B, C, D, E, F, G, H, T1, T2; - - for(i = 16; i < 64; i++) { - sha256_ctx->W[i] = - (SHA256_ROTR(sha256_ctx->W[i-2], 17) ^ SHA256_ROTR(sha256_ctx->W[i-2], 19) ^ (sha256_ctx->W[i-2] >> 10)) - + sha256_ctx->W[i-7] - + (SHA256_ROTR(sha256_ctx->W[i-15], 7) ^ SHA256_ROTR(sha256_ctx->W[i-15], 18) ^ (sha256_ctx->W[i-15] >> 3)) - + sha256_ctx->W[i-16]; - } - - A = sha256_ctx->H[0]; - B = sha256_ctx->H[1]; - C = sha256_ctx->H[2]; - D = sha256_ctx->H[3]; - E = sha256_ctx->H[4]; - F = sha256_ctx->H[5]; - G = sha256_ctx->H[6]; - H = sha256_ctx->H[7]; - - for(i = 0; i < 64; i++) { - T1 = H - + (SHA256_ROTR(E, 6) ^ SHA256_ROTR(E, 11) ^ SHA256_ROTR(E, 25)) - + ((E & F) ^ ((~E) & G)) - + sha256_K[i] + sha256_ctx->W[i]; - T2 = (SHA256_ROTR(A, 2) ^ SHA256_ROTR(A, 13) ^ SHA256_ROTR(A, 22)) - + ((A & B) ^ (A & C) ^ (B & C)); - H = G; - G = F; - F = E; - E = D + T1; - D = C; - C = B; - B = A; - A = T1 + T2; - } - - sha256_ctx->H[0] += A; - sha256_ctx->H[1] += B; - sha256_ctx->H[2] += C; - sha256_ctx->H[3] += D; - sha256_ctx->H[4] += E; - sha256_ctx->H[5] += F; - sha256_ctx->H[6] += G; - sha256_ctx->H[7] += H; -} - -static void -sha256_set_opt(PurpleCipherContext *context, const gchar *name, void *value) { - struct SHA256Context *ctx; - - ctx = purple_cipher_context_get_data(context); - - if(!strcmp(name, "sizeHi")) { - ctx->sizeHi = GPOINTER_TO_INT(value); - } else if(!strcmp(name, "sizeLo")) { - ctx->sizeLo = GPOINTER_TO_INT(value); - } else if(!strcmp(name, "lenW")) { - ctx->lenW = GPOINTER_TO_INT(value); - } -} - -static void * -sha256_get_opt(PurpleCipherContext *context, const gchar *name) { - struct SHA256Context *ctx; - - ctx = purple_cipher_context_get_data(context); - - if(!strcmp(name, "sizeHi")) { - return GINT_TO_POINTER(ctx->sizeHi); - } else if(!strcmp(name, "sizeLo")) { - return GINT_TO_POINTER(ctx->sizeLo); - } else if(!strcmp(name, "lenW")) { - return GINT_TO_POINTER(ctx->lenW); - } - - return NULL; -} - -static void -sha256_init(PurpleCipherContext *context, void *extra) { - struct SHA256Context *sha256_ctx; - - sha256_ctx = g_new0(struct SHA256Context, 1); - - purple_cipher_context_set_data(context, sha256_ctx); - - purple_cipher_context_reset(context, extra); -} - -static void -sha256_reset(PurpleCipherContext *context, void *extra) { - struct SHA256Context *sha256_ctx; - gint i; - - sha256_ctx = purple_cipher_context_get_data(context); - - g_return_if_fail(sha256_ctx); - - sha256_ctx->lenW = 0; - sha256_ctx->sizeHi = 0; - sha256_ctx->sizeLo = 0; - - sha256_ctx->H[0] = 0x6a09e667; - sha256_ctx->H[1] = 0xbb67ae85; - sha256_ctx->H[2] = 0x3c6ef372; - sha256_ctx->H[3] = 0xa54ff53a; - sha256_ctx->H[4] = 0x510e527f; - sha256_ctx->H[5] = 0x9b05688c; - sha256_ctx->H[6] = 0x1f83d9ab; - sha256_ctx->H[7] = 0x5be0cd19; - - for(i = 0; i < 64; i++) - sha256_ctx->W[i] = 0; -} - -static void -sha256_uninit(PurpleCipherContext *context) { - struct SHA256Context *sha256_ctx; - - purple_cipher_context_reset(context, NULL); - - sha256_ctx = purple_cipher_context_get_data(context); - - memset(sha256_ctx, 0, sizeof(struct SHA256Context)); - - g_free(sha256_ctx); - sha256_ctx = NULL; -} - -static void -sha256_append(PurpleCipherContext *context, const guchar *data, size_t len) { - struct SHA256Context *sha256_ctx; - gint i; - - sha256_ctx = purple_cipher_context_get_data(context); - - g_return_if_fail(sha256_ctx); - - for(i = 0; i < len; i++) { - sha256_ctx->W[sha256_ctx->lenW / 4] <<= 8; - sha256_ctx->W[sha256_ctx->lenW / 4] |= data[i]; - - if((++sha256_ctx->lenW) % 64 == 0) { - sha256_hash_block(sha256_ctx); - sha256_ctx->lenW = 0; - } - - sha256_ctx->sizeLo += 8; - sha256_ctx->sizeHi += (sha256_ctx->sizeLo < 8); - } -} - -static gboolean -sha256_digest(PurpleCipherContext *context, size_t in_len, guchar digest[32], - size_t *out_len) -{ - struct SHA256Context *sha256_ctx; - guchar pad0x80 = 0x80, pad0x00 = 0x00; - guchar padlen[8]; - gint i; - - g_return_val_if_fail(in_len >= 32, FALSE); - - sha256_ctx = purple_cipher_context_get_data(context); - - g_return_val_if_fail(sha256_ctx, FALSE); - - padlen[0] = (guchar)((sha256_ctx->sizeHi >> 24) & 255); - padlen[1] = (guchar)((sha256_ctx->sizeHi >> 16) & 255); - padlen[2] = (guchar)((sha256_ctx->sizeHi >> 8) & 255); - padlen[3] = (guchar)((sha256_ctx->sizeHi >> 0) & 255); - padlen[4] = (guchar)((sha256_ctx->sizeLo >> 24) & 255); - padlen[5] = (guchar)((sha256_ctx->sizeLo >> 16) & 255); - padlen[6] = (guchar)((sha256_ctx->sizeLo >> 8) & 255); - padlen[7] = (guchar)((sha256_ctx->sizeLo >> 0) & 255); - - /* pad with a 1, then zeroes, then length */ - purple_cipher_context_append(context, &pad0x80, 1); - while(sha256_ctx->lenW != 56) - purple_cipher_context_append(context, &pad0x00, 1); - purple_cipher_context_append(context, padlen, 8); - - for(i = 0; i < 32; i++) { - digest[i] = (guchar)(sha256_ctx->H[i / 4] >> 24); - sha256_ctx->H[i / 4] <<= 8; - } - - purple_cipher_context_reset(context, NULL); - - if(out_len) - *out_len = 32; - - return TRUE; -} - -static PurpleCipherOps SHA256Ops = { - sha256_set_opt, /* Set Option */ - sha256_get_opt, /* Get Option */ - sha256_init, /* init */ - sha256_reset, /* reset */ - sha256_uninit, /* uninit */ - NULL, /* set iv */ - sha256_append, /* append */ - sha256_digest, /* digest */ - NULL, /* encrypt */ - NULL, /* decrypt */ - NULL, /* set salt */ - NULL, /* get salt size */ - NULL, /* set key */ - NULL, /* get key size */ - NULL, /* set batch mode */ - NULL, /* get batch mode */ - sha256_get_block_size, /* get block size */ - NULL /* set key with len */ -}; - -PurpleCipherOps * -purple_sha256_cipher_get_ops(void) { - return &SHA256Ops; -} - -#endif /* !GLIB_CHECK_VERSION(2,16,0) */ -
--- a/libpurple/core.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/core.c Sat Feb 02 21:20:08 2013 +0100 @@ -189,6 +189,9 @@ /* The UI may have registered some theme types, so refresh them */ purple_theme_manager_refresh(); + /* Load the buddy list after UI init */ + purple_blist_boot(); + return TRUE; } @@ -261,9 +264,11 @@ #endif purple_cmds_uninit(); - /* Everything after util_uninit cannot try to write things to the confdir */ + purple_log_uninit(); + /* Everything after util_uninit cannot try to write things to the + * confdir nor use purple_escape_js + */ purple_util_uninit(); - purple_log_uninit(); purple_signals_uninit();
--- a/libpurple/example/nullclient.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/example/nullclient.c Sat Feb 02 21:20:08 2013 +0100 @@ -103,11 +103,7 @@ glib_input_add, g_source_remove, NULL, -#if GLIB_CHECK_VERSION(2,14,0) g_timeout_add_seconds, -#else - NULL, -#endif /* padding */ NULL, @@ -218,19 +214,12 @@ abort(); } - /* Create and load the buddylist. */ - purple_set_blist(purple_blist_new()); - purple_blist_load(); - /* Load the preferences. */ purple_prefs_load(); /* Load the desired plugins. The client should save the list of loaded plugins in * the preferences using purple_plugins_save_loaded(PLUGIN_SAVE_PREF) */ purple_plugins_load_saved(PLUGIN_SAVE_PREF); - - /* Load the pounces. */ - purple_pounces_load(); } static void
--- a/libpurple/ft.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/ft.c Sat Feb 02 21:20:08 2013 +0100 @@ -303,7 +303,7 @@ if (print_thumbnail && thumbnail_data) { gchar *message_with_img; gpointer data = g_memdup(thumbnail_data, size); - int id = purple_imgstore_add_with_id(data, size, NULL); + int id = purple_imgstore_new_with_id(data, size, NULL); message_with_img = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'> %s",
--- a/libpurple/glibcompat.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/glibcompat.h Sat Feb 02 21:20:08 2013 +0100 @@ -25,10 +25,6 @@ * Also, any public API should not depend on this file. */ -#if !GLIB_CHECK_VERSION(2, 20, 0) - -#define G_OFFSET_FORMAT G_GINT64_FORMAT - #if !GLIB_CHECK_VERSION(2, 28, 0) static inline gint64 g_get_monotonic_time(void) @@ -53,6 +49,5 @@ } #endif /* 2.28.0 */ -#endif /* 2.20.0 */ #endif /* _PIDGINGLIBCOMPAT_H_ */
--- a/libpurple/http.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/http.c Sat Feb 02 21:20:08 2013 +0100 @@ -2016,14 +2016,22 @@ return response->contents->len; } -const gchar * purple_http_response_get_data(PurpleHttpResponse *response) +const gchar * purple_http_response_get_data(PurpleHttpResponse *response, size_t *len) { + const gchar *ret = ""; + g_return_val_if_fail(response != NULL, NULL); - if (response->contents == NULL) - return ""; - - return response->contents->str; + if (response->contents != NULL) { + ret = response->contents->str; + if(len) + *len = response->contents->len; + } else { + if(len) + *len = 0; + } + + return ret; } const GList * purple_http_response_get_all_headers(PurpleHttpResponse *response)
--- a/libpurple/http.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/http.h Sat Feb 02 21:20:08 2013 +0100 @@ -528,9 +528,10 @@ * Response data is not written, if writer callback was set for request. * * @param response The response. + * @param len Return address for the size of the data. Can be NULL. * @return The data. */ -const gchar * purple_http_response_get_data(PurpleHttpResponse *response); +const gchar * purple_http_response_get_data(PurpleHttpResponse *response, size_t *len); /** * Gets all headers got with response.
--- a/libpurple/imgstore.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/imgstore.c Sat Feb 02 21:20:08 2013 +0100 @@ -36,20 +36,20 @@ static unsigned int nextid = 0; /* - * NOTE: purple_imgstore_add() creates these without zeroing the memory, so + * NOTE: purple_imgstore_new() creates these without zeroing the memory, so * NOTE: make sure to update that function when adding members. */ struct _PurpleStoredImage { int id; guint8 refcount; - size_t size; /**< The image data's size. */ - char *filename; /**< The filename (for the UI) */ - gpointer data; /**< The image data. */ + size_t size; /**< The image data's size. */ + char *filename; /**< The filename (for the UI) */ + gpointer data; /**< The image data. */ }; PurpleStoredImage * -purple_imgstore_add(gpointer data, size_t size, const char *filename) +purple_imgstore_new(gpointer data, size_t size, const char *filename) { PurpleStoredImage *img; @@ -82,30 +82,33 @@ g_error_free(err); return NULL; } - return purple_imgstore_add(data, len, path); + return purple_imgstore_new(data, len, path); } int -purple_imgstore_add_with_id(gpointer data, size_t size, const char *filename) +purple_imgstore_new_with_id(gpointer data, size_t size, const char *filename) { - PurpleStoredImage *img = purple_imgstore_add(data, size, filename); - if (img) { - /* - * Use the next unused id number. We do it in a loop on the - * off chance that nextid wraps back around to 0 and the hash - * table still contains entries from the first time around. - */ - do { - img->id = ++nextid; - } while (img->id == 0 || g_hash_table_lookup(imgstore, &(img->id)) != NULL); - - g_hash_table_insert(imgstore, &(img->id), img); + PurpleStoredImage *img = purple_imgstore_new(data, size, filename); + if (!img) { + return 0; } - return (img ? img->id : 0); + /* + * Use the next unused id number. We do it in a loop on the + * off chance that nextid wraps back around to 0 and the hash + * table still contains entries from the first time around. + */ + do { + img->id = ++nextid; + } while (img->id == 0 || g_hash_table_lookup(imgstore, &(img->id)) != NULL); + + g_hash_table_insert(imgstore, &(img->id), img); + + return img->id; } -PurpleStoredImage *purple_imgstore_find_by_id(int id) { +PurpleStoredImage *purple_imgstore_find_by_id(int id) +{ PurpleStoredImage *img = g_hash_table_lookup(imgstore, &id); if (img != NULL) @@ -114,7 +117,8 @@ return img; } -gconstpointer purple_imgstore_get_data(PurpleStoredImage *img) { +gconstpointer purple_imgstore_get_data(PurpleStoredImage *img) +{ g_return_val_if_fail(img != NULL, NULL); return img->data;
--- a/libpurple/imgstore.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/imgstore.h Sat Feb 02 21:20:08 2013 +0100 @@ -1,5 +1,6 @@ /** - * @file imgstore.h IM Image Store API + * @file imgstore.h Utility functions for reference-counted in-memory + * image data. * @ingroup core * @see @ref imgstore-signals */ @@ -39,66 +40,89 @@ G_BEGIN_DECLS /** - * Add an image to the store. + * Create a new PurpleStoredImage. * - * The caller owns a reference to the image in the store, and must dereference - * the image with purple_imgstore_unref() for it to be freed. + * The image is not added to the image store and no ID is assigned. If you + * need to reference the image by an ID, use purple_imgstore_new_with_id() + * instead. * - * No ID is allocated when using this function. If you need to reference the - * image by an ID, use purple_imgstore_add_with_id() instead. + * The caller owns a reference to this image and must dereference it with + * purple_imgstore_unref() for it to be freed. * - * @param data Pointer to the image data, which the imgstore will take - * ownership of and free as appropriate. If you want a - * copy of the data, make it before calling this function. - * @param size Image data's size. - * @param filename Filename associated with image. This is for your + * @param data Pointer to the image data, which the imgstore will take + * ownership of and free as appropriate. If you want a + * copy of the data, make it before calling this function. + * @param size Image data's size. + * @param filename Filename associated with image. This is for your * convenience. It could be the full path to the * image or, more commonly, the filename of the image * without any directory information. It can also be * NULL, if you don't need to keep track of a filename. + * If you intend to use this filename to write the file to + * disk, make sure the filename is appropriately escaped. + * You may wish to use purple_escape_filename(). * - * @return The stored image. + * @return The image, or NULL if the image could not be created (because of + * empty data or size). */ PurpleStoredImage * -purple_imgstore_add(gpointer data, size_t size, const char *filename); +purple_imgstore_new(gpointer data, size_t size, const char *filename); /** - * Create an image and add it to the store. + * Create a PurpleStoredImage using purple_imgstore_new() by reading the + * given filename from disk. + * + * The image is not added to the image store and no ID is assigned. If you + * need to reference the image by an ID, use purple_imgstore_new_with_id() + * instead. * - * @param path The path to the image. + * Make sure the filename is appropriately escaped. You may wish to use + * purple_escape_filename(). The PurpleStoredImage's filename will be set + * to the given path. * - * @return The stored image. + * The caller owns a reference to this image and must dereference it with + * purple_imgstore_unref() for it to be freed. + * + * @param path The path to the image. + * + * @return The image, or NULL if the image could not be created (because of + * empty data or size). */ PurpleStoredImage * purple_imgstore_new_from_file(const char *path); /** - * Add an image to the store, allocating an ID. - * - * The caller owns a reference to the image in the store, and must dereference - * the image with purple_imgstore_unref_by_id() or purple_imgstore_unref() - * for it to be freed. + * Create a PurpleStoredImage using purple_imgstore_new() and add the + * image to the image store. A unique ID will be assigned to the image. * - * @param data Pointer to the image data, which the imgstore will take - * ownership of and free as appropriate. If you want a - * copy of the data, make it before calling this function. - * @param size Image data's size. - * @param filename Filename associated with image. This is for your + * The caller owns a reference to the image and must dereference it with + * purple_imgstore_unref() or purple_imgstore_unref_by_id() for it to be + * freed. + * + * @param data Pointer to the image data, which the imgstore will take + * ownership of and free as appropriate. If you want a + * copy of the data, make it before calling this function. + * @param size Image data's size. + * @param filename Filename associated with image. This is for your * convenience. It could be the full path to the * image or, more commonly, the filename of the image * without any directory information. It can also be * NULL, if you don't need to keep track of a filename. - + * If you intend to use this filename to write the file to + * disk, make sure the filename is appropriately escaped. + * You may wish to use purple_escape_filename() + * * @return ID for the image. This is a unique number that can be used - * within libpurple to reference the image. + * within libpurple to reference the image. 0 is returned if the + * image could not be created (because of empty data or size). */ -int purple_imgstore_add_with_id(gpointer data, size_t size, const char *filename); +int purple_imgstore_new_with_id(gpointer data, size_t size, const char *filename); /** * Retrieve an image from the store. The caller does not own a * reference to the image. * - * @param id The ID for the image. + * @param id The ID for the image. * * @return A pointer to the requested image, or NULL if it was not found. */ @@ -107,7 +131,7 @@ /** * Retrieves a pointer to the image's data. * - * @param img The Image + * @param img The Image. * * @return A pointer to the data, which must not * be freed or modified. @@ -117,7 +141,7 @@ /** * Retrieves the length of the image's data. * - * @param img The Image + * @param img The Image. * * @return The size of the data that the pointer returned by * purple_imgstore_get_data points to. @@ -125,9 +149,12 @@ size_t purple_imgstore_get_size(PurpleStoredImage *img); /** - * Retrieves a pointer to the image's filename. + * Retrieves a pointer to the image's filename. If you intend to use this + * filename to write the file to disk, make sure the filename was + * appropriately escaped when you created the PurpleStoredImage. You may + * wish to use purple_escape_filename(). * - * @param img The image + * @param img The image. * * @return A pointer to the filename, which must not * be freed or modified. @@ -138,7 +165,7 @@ * Looks at the magic numbers of the image data (the first few bytes) * and returns an extension corresponding to the image's file type. * - * @param img The image. + * @param img The image. * * @return The image's extension (for example "png") or "icon" * if unknown. @@ -174,7 +201,7 @@ * purple_imgstore_ref(), so if you have a PurpleStoredImage, it'll * be more efficient to call purple_imgstore_ref() directly. * - * @param id The ID for the image. + * @param id The ID for the image. */ void purple_imgstore_ref_by_id(int id); @@ -185,7 +212,7 @@ * purple_imgstore_unref(), so if you have a PurpleStoredImage, it'll * be more efficient to call purple_imgstore_unref() directly. * - * @param id The ID for the image. + * @param id The ID for the image. */ void purple_imgstore_unref_by_id(int id);
--- a/libpurple/log.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/log.c Sat Feb 02 21:20:08 2013 +0100 @@ -835,7 +835,10 @@ fclose(image_file); /* Attempt to not leave half-written files around. */ - unlink(path); + if (g_unlink(path)) { + purple_debug_error("log", "Error deleting partial " + "file %s: %s\n", path, g_strerror(errno)); + } } else { @@ -1763,7 +1766,7 @@ index_tmp = g_strdup_printf("%s.XXXXXX", pathstr); if ((index_fd = g_mkstemp(index_tmp)) == -1) { purple_debug_error("log", "Failed to open index temp file: %s\n", - g_strerror(errno)); + g_strerror(errno)); g_free(pathstr); g_free(index_tmp); index = NULL; @@ -1771,7 +1774,7 @@ if ((index = fdopen(index_fd, "wb")) == NULL) { purple_debug_error("log", "Failed to fdopen() index temp file: %s\n", - g_strerror(errno)); + g_strerror(errno)); close(index_fd); if (index_tmp != NULL) { @@ -1827,7 +1830,6 @@ log->logger_data = data; list = g_list_prepend(list, log); - /* XXX: There is apparently Is there a proper way to print a time_t? */ if (index != NULL) fprintf(index, "%d\t%d\t%lu\n", data->offset, data->length, (unsigned long)log->time); } @@ -1887,9 +1889,8 @@ log->logger_data = data; list = g_list_prepend(list, log); - /* XXX: Is there a proper way to print a time_t? */ if (index != NULL) - fprintf(index, "%d\t%d\t%d\n", data->offset, data->length, (int)log->time); + fprintf(index, "%d\t%d\t%lu\n", data->offset, data->length, (unsigned long)log->time); } } @@ -2022,7 +2023,7 @@ /* Search the buddy list to find the account and to determine if this is a buddy. */ for (gnode = purple_blist_get_root(); !found && gnode != NULL; - gnode = purple_blist_node_get_sibling_next(gnode)) + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; @@ -2036,7 +2037,7 @@ for (bnode = purple_blist_node_get_first_child(cnode); !found && bnode != NULL; - bnode = purple_blist_node_get_sibling_next(bnode)) + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *buddy = (PurpleBuddy *)bnode;
--- a/libpurple/media/backend-fs2.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/media/backend-fs2.c Sat Feb 02 21:20:08 2013 +0100 @@ -41,6 +41,7 @@ #include <farstream/fs-conference.h> #include <farstream/fs-element-added-notifier.h> #include <farstream/fs-utils.h> +#include <gst/gststructure.h> #endif /** @copydoc _PurpleMediaBackendFs2Class */ @@ -2366,14 +2367,44 @@ return TRUE; } +static const gchar ** +purple_media_backend_fs2_get_available_params(void) +{ + static const gchar *supported_params[] = { + "sdes-cname", "sdes-email", "sdes-location", "sdes-name", "sdes-note", + "sdes-phone", "sdes-tool", NULL + }; + + return supported_params; +} + +static const gchar* +param_to_sdes_type(const gchar *param) +{ + const gchar **supported = purple_media_backend_fs2_get_available_params(); + static const gchar *sdes_types[] = { + "cname", "email", "location", "name", "note", "phone", "tool", NULL + }; + guint i; + + for (i = 0; supported[i] != NULL; ++i) { + if (!strcmp(param, supported[i])) { + return sdes_types[i]; + } + } + + return NULL; +} + static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self, guint num_params, GParameter *params) { PurpleMediaBackendFs2Private *priv; - const gchar **supported = purple_media_backend_fs2_get_available_params(); - const gchar **p; guint i; +#ifndef HAVE_FARSIGHT + GstStructure *sdes; +#endif g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self)); @@ -2386,27 +2417,30 @@ return; } +#ifdef HAVE_FARSIGHT for (i = 0; i != num_params; ++i) { - for (p = supported; *p != NULL; ++p) { - if (!strcmp(params[i].name, *p)) { - g_object_set(priv->conference, - params[i].name, g_value_get_string(¶ms[i].value), - NULL); - break; - } + if (param_to_sdes_type(params[i].name)) { + g_object_set(priv->conference, + params[i].name, g_value_get_string(¶ms[i].value), + NULL); } } -} - -static const gchar ** -purple_media_backend_fs2_get_available_params(void) -{ - static const gchar *supported_params[] = { - "sdes-cname", "sdes-email", "sdes-location", "sdes-name", "sdes-note", - "sdes-phone", "sdes-tool", NULL - }; - - return supported_params; +#else + g_object_get(G_OBJECT(priv->conference), "sdes", &sdes, NULL); + + for (i = 0; i != num_params; ++i) { + const gchar *sdes_type = param_to_sdes_type(params[i].name); + if (!sdes_type) + continue; + + gst_structure_set(sdes, sdes_type, + G_TYPE_STRING, g_value_get_string(¶ms[i].value), + NULL); + } + + g_object_set(G_OBJECT(priv->conference), "sdes", sdes, NULL); + gst_structure_free(sdes); +#endif /* HAVE_FARSIGHT */ } #else GType
--- a/libpurple/ntlm.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/ntlm.c Sat Feb 02 21:20:08 2013 +0100 @@ -220,16 +220,39 @@ des_ecb_encrypt(plaintext, results + 16, key); } +/* + * TODO: We think we should be using cryptographically secure random numbers + * here. We think the rand() function is probably bad. We think + * /dev/urandom is a step up, but using a random function from an SSL + * library would probably be best. In Windows we could possibly also + * use CryptGenRandom. + */ static void -gensesskey(char *buffer, const char *oldkey) +gensesskey(char *buffer) { - int i = 0; - if(oldkey == NULL) { - for(i=0; i<16; i++) { - buffer[i] = (char)(rand() & 0xff); + int fd; + int i; + ssize_t red = 0; + + fd = open("/dev/urandom", O_RDONLY); + if (fd >= 0) { + red = read(fd, buffer, 16); + if (red < 0) { + purple_debug_warning("ntlm", "Error reading from /dev/urandom: %s." + " Falling back to inferior method.\n", g_strerror(errno)); + red = 0; + } else if (red < 16) { + purple_debug_warning("ntlm", "Tried reading 16 bytes from " + "/dev/urandom but only got %zd. Falling back to " + "inferior method\n", red); } } else { - memcpy(buffer, oldkey, 16); + purple_debug_warning("ntlm", "Error opening /dev/urandom: %s." + " Falling back to inferior method.\n", g_strerror(errno)); + } + + for (i = red; i < 16; i++) { + buffer[i] = (char)(rand() & 0xff); } } @@ -366,7 +389,7 @@ /* LCS Stuff */ if (flags) { tmsg->flags = GUINT32_TO_LE(0x409082d4); - gensesskey(sesskey, NULL); + gensesskey(sesskey); memcpy(tmp, sesskey, 0x10); }
--- a/libpurple/obsolete.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/obsolete.c Sat Feb 02 21:20:08 2013 +0100 @@ -80,12 +80,15 @@ PurpleHttpResponse *response, gpointer _wrap_data) { PurpleUtilLegacyWrapData *wrap_data = _wrap_data; + const char *data = NULL; + size_t len; - if (wrap_data->cb && !wrap_data->url_data->cancelled) - wrap_data->cb(wrap_data->url_data, wrap_data->user_data, - purple_http_response_get_data(response), - purple_http_response_get_data_len(response), + if (wrap_data->cb && !wrap_data->url_data->cancelled) { + data = purple_http_response_get_data(response, &len); + + wrap_data->cb(wrap_data->url_data, wrap_data->user_data, data, len, purple_http_response_get_error(response)); + } g_free(wrap_data->url_data); g_free(wrap_data);
--- a/libpurple/plugins/log_reader.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/log_reader.c Sat Feb 02 21:20:08 2013 +0100 @@ -921,7 +921,6 @@ xmlnode *to; enum name_guesses name_guessed = NAME_GUESS_UNKNOWN; const char *their_name; - time_t time_unix; struct tm *tm; char *timestamp; char *tmp; @@ -1101,7 +1100,7 @@ text = g_string_append(text, ";\">"); } - time_unix = msn_logger_parse_timestamp(message, &tm); + msn_logger_parse_timestamp(message, &tm); timestamp = g_strdup_printf("<font size=\"2\">(%02u:%02u:%02u)</font> ", tm->tm_hour, tm->tm_min, tm->tm_sec); @@ -2581,7 +2580,7 @@ /* Read talk.ini file to find the log directory. */ GError *error = NULL; -#if 0 && GLIB_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ +#if 0 /* FIXME: Not tested yet. */ GKeyFile *key_file; purple_debug_info("Trillian talk.ini read", "Reading %s\n", path); @@ -2608,7 +2607,7 @@ g_key_file_free(key_file); } -#else /* !GLIB_CHECK_VERSION(2,6,0) */ +#else gchar *contents = NULL; purple_debug_info("Trillian talk.ini read", @@ -2644,7 +2643,7 @@ g_free(contents); } g_free(path); -#endif /* !GLIB_CHECK_VERSION(2,6,0) */ +#endif } /* path */ if (!found) {
--- a/libpurple/plugins/perl/common/BuddyIcon.xs Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/BuddyIcon.xs Sat Feb 02 21:20:08 2013 +0100 @@ -7,7 +7,7 @@ purple_buddy_icon_ref(icon) Purple::Buddy::Icon icon -Purple::Buddy::Icon +void purple_buddy_icon_unref(icon) Purple::Buddy::Icon icon
--- a/libpurple/plugins/perl/common/BuddyList.xs Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/BuddyList.xs Sat Feb 02 21:20:08 2013 +0100 @@ -35,10 +35,6 @@ Purple::BuddyList purple_get_blist() -void -purple_set_blist(blist) - Purple::BuddyList blist - MODULE = Purple::BuddyList PACKAGE = Purple::Find PREFIX = purple_find_ PROTOTYPES: ENABLE @@ -176,9 +172,6 @@ Purple::BuddyList::Group group Purple::BuddyList::Node node -Purple::BuddyList -purple_blist_new() - void purple_blist_show() @@ -237,9 +230,6 @@ Purple::BuddyList::Group group void -purple_blist_load() - -void purple_blist_schedule_save() void
--- a/libpurple/plugins/perl/common/Certificate.xs Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/Certificate.xs Sat Feb 02 21:20:08 2013 +0100 @@ -43,8 +43,20 @@ static const constiv *civ, const_iv[] = { #define const_iv(name) {#name, (IV)PURPLE_CERTIFICATE_##name} - const_iv(INVALID), + const_iv(UNKNOWN_ERROR), const_iv(VALID), + const_iv(NON_FATALS_MASK), + const_iv(SELF_SIGNED), + const_iv(CA_UNKNOWN), + const_iv(NOT_ACTIVATED), + const_iv(EXPIRED), + const_iv(NAME_MISMATCH), + const_iv(NO_CA_POOL), + const_iv(FATALS_MASK), + const_iv(INVALID_CHAIN), + const_iv(REVOKED), + const_iv(REJECTED), + const_iv(LAST), }; for (civ = const_iv + sizeof(const_iv) / sizeof(const_iv[0]); civ-- > const_iv; )
--- a/libpurple/plugins/perl/common/ImgStore.xs Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/ImgStore.xs Sat Feb 02 21:20:08 2013 +0100 @@ -4,13 +4,13 @@ PROTOTYPES: ENABLE Purple::StoredImage -purple_imgstore_add(data, size, filename) +purple_imgstore_new(data, size, filename) void *data size_t size const char *filename int -purple_imgstore_add_with_id(data, size, filename) +purple_imgstore_new_with_id(data, size, filename) void *data size_t size const char *filename
--- a/libpurple/plugins/perl/common/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -112,7 +112,7 @@ $(PERL) -MAutoSplit -e 'autosplit("lib/Purple.pm")' $(TARGET).dll: $(PURPLE_DLL).a $(PURPLE_PERL_DLL).a $(FALLBACKS) $(OBJECTS) - $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) -o $(TARGET).dll + $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll ## ## CLEAN
--- a/libpurple/plugins/perl/common/Pounce.xs Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/perl/common/Pounce.xs Sat Feb 02 21:20:08 2013 +0100 @@ -121,9 +121,6 @@ Purple::Handle purple_pounces_get_handle() -gboolean -purple_pounces_load() - void purple_pounces_unregister_handler(ui) const char *ui
--- a/libpurple/plugins/signals-test.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/signals-test.c Sat Feb 02 21:20:08 2013 +0100 @@ -78,25 +78,25 @@ } static int -account_authorization_requested_cb(PurpleAccount *account, const char *user, gpointer data) +account_authorization_requested_cb(PurpleAccount *account, const char *user, const char *message, char *response, gpointer data) { - purple_debug_misc("signals test", "account-authorization-requested (%s, %s)\n", - purple_account_get_username(account), user); - return 0; + purple_debug_misc("signals test", "account-authorization-requested (%s, %s, %s)\n", + purple_account_get_username(account), user, message); + return PURPLE_ACCOUNT_RESPONSE_PASS; } static void -account_authorization_granted_cb(PurpleAccount *account, const char *user, gpointer data) +account_authorization_granted_cb(PurpleAccount *account, const char *user, const char *message, gpointer data) { - purple_debug_misc("signals test", "account-authorization-granted (%s, %s)\n", - purple_account_get_username(account), user); + purple_debug_misc("signals test", "account-authorization-granted (%s, %s, %s)\n", + purple_account_get_username(account), user, message); } static void -account_authorization_denied_cb(PurpleAccount *account, const char *user, gpointer data) +account_authorization_denied_cb(PurpleAccount *account, const char *user, const char *message, gpointer data) { - purple_debug_misc("signals test", "account-authorization-denied (%s, %s)\n", - purple_account_get_username(account), user); + purple_debug_misc("signals test", "account-authorization-denied (%s, %s, %s)\n", + purple_account_get_username(account), user, message); } /**************************************************************************
--- a/libpurple/plugins/ssl/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/ssl/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -19,7 +19,6 @@ $(NSS_TOP)/lib/libplc4.dll \ $(NSS_TOP)/lib/libplds4.dll \ $(NSS_TOP)/lib/nss3.dll \ - $(NSS_TOP)/lib/nssckbi.dll \ $(NSS_TOP)/lib/nssutil3.dll \ $(NSS_TOP)/lib/smime3.dll \ $(NSS_TOP)/lib/softokn3.dll \
--- a/libpurple/plugins/ssl/ssl-nss.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/ssl/ssl-nss.c Sat Feb 02 21:20:08 2013 +0100 @@ -125,18 +125,8 @@ static void ssl_nss_init_nss(void) { - char *lib; PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); NSS_NoDB_Init("."); - - /* TODO: Fix this so autoconf does the work trying to find this lib. */ -#ifndef _WIN32 - lib = g_strdup(LIBDIR "/libnssckbi.so"); -#else - lib = g_strdup("nssckbi.dll"); -#endif - SECMOD_AddNewModule("Builtins", lib, 0, 0); - g_free(lib); NSS_SetDomesticPolicy(); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1);
--- a/libpurple/plugins/tcl/signal-test.tcl Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/tcl/signal-test.tcl Sat Feb 02 21:20:08 2013 +0100 @@ -108,7 +108,7 @@ purple::debug -info "tcl signal" "plugin-unload [list $args]" } -purple::signal connect [purple::savedstatuses handle] savedstatus-changed args { +purple::signal connect [purple::savedstatus handle] savedstatus-changed args { purple::debug -info "tcl signal" "savedstatus-changed [list $args]" purple::debug -info "tcl signal" "purple::savedstatus current = [purple::savedstatus current]" }
--- a/libpurple/plugins/tcl/tcl.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/plugins/tcl/tcl.c Sat Feb 02 21:20:08 2013 +0100 @@ -174,37 +174,17 @@ Tcl_Interp *interp; Tcl_Parse parse; Tcl_Obj *result, **listitems; - struct stat st; - FILE *fp; - char *buf, *cur; + char *buf; const char *next; - int len, found = 0, err = 0, nelems; + int found = 0, err = 0, nelems; + gsize len; gboolean status = FALSE; - if ((fp = g_fopen(plugin->path, "r")) == NULL) - return FALSE; - if (fstat(fileno(fp), &st)) { - fclose(fp); + + if (!g_file_get_contents(plugin->path, &buf, &len, NULL)) { + purple_debug(PURPLE_DEBUG_INFO, "tcl", "Error opening plugin %s\n", + plugin->path); return FALSE; } - len = st.st_size; - - buf = g_malloc(len + 1); - - cur = buf; - while (fgets(cur, GPOINTER_TO_INT(buf) - (buf - cur), fp)) { - cur += strlen(cur); - if (feof(fp)) - break; - } - - if (ferror(fp)) { - purple_debug(PURPLE_DEBUG_ERROR, "tcl", "error reading %s (%s)\n", plugin->path, g_strerror(errno)); - g_free(buf); - fclose(fp); - return FALSE; - } - - fclose(fp); if ((interp = tcl_create_interp()) == NULL) { return FALSE;
--- a/libpurple/pounce.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/pounce.c Sat Feb 02 21:20:08 2013 +0100 @@ -572,7 +572,7 @@ NULL }; -gboolean +static gboolean purple_pounces_load(void) { gchar *filename = g_build_filename(purple_user_dir(), "pounces.xml", NULL); @@ -1190,6 +1190,8 @@ purple_signal_connect(conv_handle, "received-im-msg", handle, PURPLE_CALLBACK(received_message_cb), NULL); + + purple_pounces_load(); } void
--- a/libpurple/pounce.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/pounce.h Sat Feb 02 21:20:08 2013 +0100 @@ -289,14 +289,6 @@ PurplePounce *purple_find_pounce(const PurpleAccount *pouncer, const char *pouncee, PurplePounceEvent events); - -/** - * Loads the pounces. - * - * @return @c TRUE if the pounces could be loaded. - */ -gboolean purple_pounces_load(void); - /** * Registers a pounce handler for a UI. *
--- a/libpurple/protocols/bonjour/bonjour_ft.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/bonjour/bonjour_ft.c Sat Feb 02 21:20:08 2013 +0100 @@ -33,7 +33,7 @@ static void bonjour_bytestreams_init(PurpleXfer *xfer); static void -bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb); +bonjour_bytestreams_connect(PurpleXfer *xfer); static void bonjour_xfer_init(PurpleXfer *xfer); static void @@ -280,6 +280,25 @@ xep_iq_send_and_free(iq); } +/** + * Frees the whole tree of an xml node + * + * First determines the root of the xml tree and then frees the whole tree + * from there. + * + * @param node The node to free the tree from + */ +static void +xmlnode_free_tree(xmlnode *node) +{ + g_return_if_fail(node != NULL); + + while(xmlnode_get_parent(node)) + node = xmlnode_get_parent(node); + + xmlnode_free(node); +} + static void bonjour_free_xfer(PurpleXfer *xfer) { @@ -310,6 +329,9 @@ g_free(xf->proxy_host); g_free(xf->buddy_ip); g_free(xf->sid); + + xmlnode_free_tree(xf->streamhost); + g_free(xf); purple_xfer_set_protocol_data(xfer, NULL); } @@ -441,7 +463,7 @@ if (si && (profile = xmlnode_get_attrib(si, "profile")) && !strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer")) { const char *filename = NULL, *filesize_str = NULL; - int filesize = 0; + goffset filesize = 0; xmlnode *file; const char *sid = xmlnode_get_attrib(si, "id"); @@ -449,7 +471,7 @@ if ((file = xmlnode_get_child(si, "file"))) { filename = xmlnode_get_attrib(file, "name"); if((filesize_str = xmlnode_get_attrib(file, "size"))) - filesize = atoi(filesize_str); + filesize = g_ascii_strtoll(filesize_str, NULL, 10); } /* TODO: Make sure that it is advertising a bytestreams transfer */ @@ -547,19 +569,97 @@ return !strcmp(host, buddy_ip); } +static inline gint +xep_addr_differ(const char *buddy_ip, const char *host) +{ + return !xep_cmp_addr(host, buddy_ip); +} + +/** + * Create and insert an identical twin + * + * Creates a copy of the specified node and inserts it right after + * this original node. + * + * @param node The node to clone + * @return A pointer to the new, cloned twin if successful + * or NULL otherwise. + */ +static xmlnode * +xmlnode_insert_twin_copy(xmlnode *node) { + xmlnode *copy; + + g_return_val_if_fail(node != NULL, NULL); + + copy = xmlnode_copy(node); + g_return_val_if_fail(copy != NULL, NULL); + + copy->next = node->next; + node->next = copy; + + return copy; +} + +/** + * Tries to append an interface scope to an IPv6 link local address. + * + * If the given address is a link local IPv6 address (with no + * interface scope) then we try to determine all fitting interfaces + * from our Bonjour IP address list. + * + * For any such found matches we insert a copy of our current xml + * streamhost entry right after this streamhost entry and append + * the determined interface to the host address of this copy. + * + * @param cur_streamhost The XML streamhost node we examine + * @param host The host address to examine in text form + * @param pb Buddy to get the list of link local IPv6 addresses + * and their interface from + * @return Returns TRUE if the specified 'host' address is a + * link local IPv6 address with no interface scope. + * Otherwise returns FALSE. + */ static gboolean -__xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *query, +add_ipv6_link_local_ifaces(xmlnode *cur_streamhost, const char *host, + const PurpleBuddy *pb) { + xmlnode *new_streamhost = NULL; + struct in6_addr in6_addr; + BonjourBuddy *bb; + GSList *ip_elem; + + if (inet_pton(AF_INET6, host, &in6_addr) != 1 || + !IN6_IS_ADDR_LINKLOCAL(&in6_addr) || + strchr(host, '%')) + return FALSE; + + bb = purple_buddy_get_protocol_data(pb); + + for (ip_elem = bb->ips; + (ip_elem = g_slist_find_custom(ip_elem, host, (GCompareFunc)&xep_addr_differ)); + ip_elem = ip_elem->next) { + purple_debug_info("bonjour", "Inserting an xmlnode twin copy for %s with new host address %s\n", + host, (char*)ip_elem->data); + new_streamhost = xmlnode_insert_twin_copy(cur_streamhost); + xmlnode_set_attrib(new_streamhost, "host", ip_elem->data); + } + + if (!new_streamhost) + purple_debug_info("bonjour", "No interface for this IPv6 link local address found: %s\n", + host); + + return TRUE; +} + +static gboolean +__xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *streamhost, const char *iq_id) { + char *tmp_iq_id; const char *jid, *host, *port; int portnum; - xmlnode *streamhost; XepXfer *xf = purple_xfer_get_protocol_data(xfer); - for(streamhost = xmlnode_get_child(query, "streamhost"); - streamhost; - streamhost = xmlnode_get_next_twin(streamhost)) { - + for(; streamhost; streamhost = xmlnode_get_next_twin(streamhost)) { if(!(jid = xmlnode_get_attrib(streamhost, "jid")) || !(host = xmlnode_get_attrib(streamhost, "host")) || !(port = xmlnode_get_attrib(streamhost, "port")) || @@ -568,29 +668,36 @@ continue; } - if(!xep_cmp_addr(host, xf->buddy_ip)) + /* skip IPv6 link local addresses with no interface scope + * (but try to add a new one with an interface scope then) */ + if(add_ipv6_link_local_ifaces(streamhost, host, pb)) continue; + tmp_iq_id = g_strdup(iq_id); g_free(xf->iq_id); - xf->iq_id = g_strdup(iq_id); + g_free(xf->jid); + g_free(xf->proxy_host); + + xf->iq_id = tmp_iq_id; xf->jid = g_strdup(jid); - xf->proxy_host = g_strdup(xf->buddy_ip); + xf->proxy_host = g_strdup(host); xf->proxy_port = portnum; + xf->streamhost = streamhost; + xf->pb = pb; purple_debug_info("bonjour", "bytestream offer parse" "jid=%s host=%s port=%d.\n", jid, host, portnum); - bonjour_bytestreams_connect(xfer, pb); + bonjour_bytestreams_connect(xfer); return TRUE; } return FALSE; } - void xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb) { const char *type, *from, *iq_id, *sid; - xmlnode *query; + xmlnode *query, *streamhost; BonjourData *bd; PurpleXfer *xfer; @@ -610,6 +717,10 @@ if(!type) return; + query = xmlnode_copy(query); + if (!query) + return; + if(strcmp(type, "set")) { purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type); return; @@ -621,7 +732,9 @@ sid = xmlnode_get_attrib(query, "sid"); xfer = bonjour_si_xfer_find(bd, sid, from); - if(xfer && __xep_bytestreams_parse(pb, xfer, query, iq_id)) + streamhost = xmlnode_get_child(query, "streamhost"); + + if(xfer && streamhost && __xep_bytestreams_parse(pb, xfer, streamhost, iq_id)) return; /* success */ purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n"); @@ -864,15 +977,22 @@ XepIq *iq; xmlnode *q_node, *tmp_node; BonjourData *bd; + gboolean ret = FALSE; xf->proxy_connection = NULL; if(source < 0) { - purple_debug_error("bonjour", "Error connecting via SOCKS5 - %s\n", - error_message ? error_message : "(null)"); - xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); - /* Cancel the connection */ - purple_xfer_cancel_local(xfer); + purple_debug_error("bonjour", "Error connecting via SOCKS5 to %s - %s\n", + xf->proxy_host, error_message ? error_message : "(null)"); + + tmp_node = xmlnode_get_next_twin(xf->streamhost); + ret = __xep_bytestreams_parse(xf->pb, xfer, tmp_node, xf->iq_id); + + if (!ret) { + xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); + /* Cancel the connection */ + purple_xfer_cancel_local(xfer); + } return; } @@ -894,8 +1014,9 @@ } static void -bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb) +bonjour_bytestreams_connect(PurpleXfer *xfer) { + PurpleBuddy *pb; PurpleAccount *account = NULL; XepXfer *xf; char dstaddr[41]; @@ -913,6 +1034,7 @@ if(!xf) return; + pb = xf->pb; name = purple_buddy_get_name(pb); account = purple_buddy_get_account(pb);
--- a/libpurple/protocols/bonjour/bonjour_ft.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/bonjour/bonjour_ft.h Sat Feb 02 21:20:08 2013 +0100 @@ -50,6 +50,8 @@ char *jid; char *proxy_host; int proxy_port; + xmlnode *streamhost; + PurpleBuddy *pb; }; /**
--- a/libpurple/protocols/gg/image.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/gg/image.c Sat Feb 02 21:20:08 2013 +0100 @@ -175,7 +175,7 @@ GList *it; uint64_t id; - stored_id = purple_imgstore_add_with_id( + stored_id = purple_imgstore_new_with_id( g_memdup(image_reply->image, image_reply->size), image_reply->size, image_reply->filename);
--- a/libpurple/protocols/gg/lib/common.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/gg/lib/common.c Sat Feb 02 21:20:08 2013 +0100 @@ -78,7 +78,7 @@ size = 128; do { size *= 2; - if (!(tmp = realloc(buf, size))) { + if (!(tmp = realloc(buf, size + 1))) { free(buf); return NULL; } @@ -268,6 +268,7 @@ } } + memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); sin.sin_family = AF_INET; sin.sin_addr.s_addr = a->s_addr;
--- a/libpurple/protocols/gg/lib/dcc.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/gg/lib/dcc.c Sat Feb 02 21:20:08 2013 +0100 @@ -419,6 +419,7 @@ port = GG_DEFAULT_DCC_PORT; while (!bound) { + memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port);
--- a/libpurple/protocols/gg/lib/dcc7.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/gg/lib/dcc7.c Sat Feb 02 21:20:08 2013 +0100 @@ -140,7 +140,7 @@ for (tmp = sess->dcc7_list; tmp; tmp = tmp->next) { if (empty) { - if (tmp->peer_uin == uin && !tmp->state == GG_STATE_WAITING_FOR_ACCEPT) + if (tmp->peer_uin == uin /*&& tmp->state != GG_STATE_WAITING_FOR_ACCEPT*/) return tmp; } else { if (!memcmp(&tmp->cid, &id, sizeof(id))) @@ -239,6 +239,7 @@ return -1; } + memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = addr; sin.sin_port = htons(port); @@ -649,7 +650,7 @@ s.uin_to = gg_fix32(tmp->peer_uin); s.size = gg_fix32(tmp->size); - strncpy((char*) s.filename, (char*) tmp->filename, GG_DCC7_FILENAME_LEN); + memcpy((char*) s.filename, (char*) tmp->filename, GG_DCC7_FILENAME_LEN); tmp->state = GG_STATE_WAITING_FOR_ACCEPT; tmp->timeout = GG_DCC7_TIMEOUT_FILE_ACK;
--- a/libpurple/protocols/gg/lib/libgadu.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/gg/lib/libgadu.c Sat Feb 02 21:20:08 2013 +0100 @@ -509,7 +509,7 @@ while (sess->header_done < sizeof(h)) { ret = gg_read(sess, (char*) &h + sess->header_done, sizeof(h) - sess->header_done); - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() header recv(%d,%p,%d) = %d\n", sess->fd, &h + sess->header_done, sizeof(h) - sess->header_done, ret); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() header recv(%d,%p,%d) = %d\n", sess->fd, (char*)&h + sess->header_done, sizeof(h) - sess->header_done, ret); if (!ret) { errno = ECONNRESET;
--- a/libpurple/protocols/irc/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/irc/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -54,6 +54,13 @@ -lintl \ -lpurple + +ifeq ($(CYRUS_SASL), 1) +INCLUDE_PATHS += -I$(CYRUS_SASL_TOP)/include +LIB_PATHS += -L$(CYRUS_SASL_TOP)/bin +LIBS += -llibsasl +endif + include $(PIDGIN_COMMON_RULES) ##
--- a/libpurple/protocols/irc/irc.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/irc/irc.c Sat Feb 02 21:20:08 2013 +0100 @@ -155,6 +155,7 @@ char *tosend= g_strdup(buf); purple_signal_emit(_irc_plugin, "irc-sending-text", purple_account_get_connection(irc->account), &tosend); + if (tosend == NULL) return 0; @@ -393,9 +394,17 @@ const char *username, *realname; struct irc_conn *irc = purple_connection_get_protocol_data(gc); const char *pass = purple_connection_get_password(gc); +#ifdef HAVE_CYRUS_SASL + const gboolean use_sasl = purple_account_get_bool(irc->account, "sasl", FALSE); +#endif if (pass && *pass) { - buf = irc_format(irc, "v:", "PASS", pass); +#ifdef HAVE_CYRUS_SASL + if (use_sasl) + buf = irc_format(irc, "vv:", "CAP", "REQ", "sasl"); + else /* intended to fall through */ +#endif + buf = irc_format(irc, "v:", "PASS", pass); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; @@ -529,6 +538,17 @@ g_free(irc->mode_chars); g_free(irc->reqnick); +#ifdef HAVE_CYRUS_SASL + if (irc->sasl_conn) { + sasl_dispose(&irc->sasl_conn); + irc->sasl_conn = NULL; + } + g_free(irc->sasl_cb); + if(irc->sasl_mechs) + g_string_free(irc->sasl_mechs, TRUE); +#endif + + g_free(irc); } @@ -1047,6 +1067,16 @@ option = purple_account_option_bool_new(_("Use SSL"), "ssl", FALSE); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); +#ifdef HAVE_CYRUS_SASL + option = purple_account_option_bool_new(_("Authenticate with SASL"), "sasl", FALSE); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = purple_account_option_bool_new( + _("Allow plaintext SASL auth over unencrypted connection"), + "auth_plain_in_clear", FALSE); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); +#endif + _irc_plugin = plugin; purple_prefs_remove("/plugins/prpl/irc/quitmsg");
--- a/libpurple/protocols/irc/irc.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/irc/irc.h Sat Feb 02 21:20:08 2013 +0100 @@ -25,6 +25,10 @@ #include <glib.h> +#ifdef HAVE_CYRUS_SASL +#include <sasl/sasl.h> +#endif + #include "circbuffer.h" #include "ft.h" #include "roomlist.h" @@ -93,6 +97,13 @@ char *mode_chars; char *reqnick; gboolean nickused; +#ifdef HAVE_CYRUS_SASL + sasl_conn_t *sasl_conn; + const char *current_mech; + GString *sasl_mechs; + gboolean mech_works; + sasl_callback_t *sasl_cb; +#endif }; struct irc_buddy { @@ -163,11 +174,19 @@ void irc_msg_regonly(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_time(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_topic(struct irc_conn *irc, const char *name, const char *from, char **args); +void irc_msg_topicinfo(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_unavailable(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args); +#ifdef HAVE_CYRUS_SASL +void irc_msg_cap(struct irc_conn *irc, const char *name, const char *from, char **args); +void irc_msg_auth(struct irc_conn *irc, char *arg); +void irc_msg_authok(struct irc_conn *irc, const char *name, const char *from, char **args); +void irc_msg_authtryagain(struct irc_conn *irc, const char *name, const char *from, char **args); +void irc_msg_authfail(struct irc_conn *irc, const char *name, const char *from, char **args); +#endif void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args);
--- a/libpurple/protocols/irc/msgs.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/irc/msgs.c Sat Feb 02 21:20:08 2013 +0100 @@ -32,6 +32,10 @@ #include <stdio.h> #include <stdlib.h> +#ifdef HAVE_CYRUS_SASL +#include <sasl/sasl.h> +#endif + static char *irc_mask_nick(const char *mask); static char *irc_mask_userhost(const char *mask); static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2]); @@ -42,6 +46,10 @@ const char *from, const char *to, const char *rawmsg, gboolean notice); +#ifdef HAVE_CYRUS_SASL +static void irc_sasl_finish(struct irc_conn *irc); +#endif + static char *irc_mask_nick(const char *mask) { char *end, *buf; @@ -634,6 +642,38 @@ g_free(topic); } +void irc_msg_topicinfo(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + PurpleConversation *convo; + struct tm *tm; + time_t t; + char *msg, *timestamp, *datestamp; + + if (!args || !args[1] || !args[2] || !args[3]) + return; + + convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account); + if (!convo) { + purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got topic info for %s, which doesn't exist\n", args[1]); + return; + } + + t = (time_t)atol(args[3]); + if (t == 0) { + purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got apparently nonsensical topic timestamp %s\n", args[3]); + return; + } + tm = localtime(&t); + + timestamp = g_strdup(purple_time_format(tm)); + datestamp = g_strdup(purple_date_format_short(tm)); + msg = g_strdup_printf("Topic for %s set by %s at %s on %s", args[1], args[2], timestamp, datestamp); + purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL)); + g_free(timestamp); + g_free(datestamp); + g_free(msg); +} + void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args) { PurpleConnection *gc = purple_account_get_connection(irc->account); @@ -1422,6 +1462,379 @@ g_free(msg); } +#ifdef HAVE_CYRUS_SASL +static int +irc_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secret_t **secret) +{ + struct irc_conn *irc = ctx; + sasl_secret_t *sasl_secret; + const char *pw; + size_t len; + + pw = purple_account_get_password(irc->account); + + if (!conn || !secret || id != SASL_CB_PASS) + return SASL_BADPARAM; + + len = strlen(pw); + /* Not an off-by-one because sasl_secret_t defines char data[1] */ + /* TODO: This can probably be moved to glib's allocator */ + sasl_secret = malloc(sizeof(sasl_secret_t) + len); + if (!sasl_secret) + return SASL_NOMEM; + + sasl_secret->len = len; + strcpy((char*)sasl_secret->data, pw); + + *secret = sasl_secret; + return SASL_OK; +} + +static int +irc_sasl_cb_log(void *context, int level, const char *message) +{ + if(level <= SASL_LOG_TRACE) + purple_debug_info("sasl", "%s\n", message); + + return SASL_OK; +} + +static int +irc_sasl_cb_simple(void *ctx, int id, const char **res, unsigned *len) +{ + struct irc_conn *irc = ctx; + PurpleConnection *gc = purple_account_get_connection(irc->account); + + switch(id) { + case SASL_CB_AUTHNAME: + *res = purple_connection_get_display_name(gc); + break; + case SASL_CB_USER: + *res = ""; + break; + default: + return SASL_BADPARAM; + } + if (len) *len = strlen((char *)*res); + return SASL_OK; +} + +static void +irc_auth_start_cyrus(struct irc_conn *irc) +{ + int ret = 0; + char *buf; + sasl_security_properties_t secprops; + PurpleAccount *account = irc->account; + PurpleConnection *gc = purple_account_get_connection(account); + + gboolean plaintext; + gboolean again = FALSE; + + /* Set up security properties and options */ + secprops.min_ssf = 0; + secprops.security_flags = SASL_SEC_NOANONYMOUS; + + if (!irc->gsc) { + secprops.max_ssf = -1; + secprops.maxbufsize = 4096; + plaintext = purple_account_get_bool(account, "auth_plain_in_clear", FALSE); + if (!plaintext) + secprops.security_flags |= SASL_SEC_NOPLAINTEXT; + } else { + secprops.max_ssf = 0; + secprops.maxbufsize = 0; + plaintext = TRUE; + } + + secprops.property_names = 0; + secprops.property_values = 0; + + do { + gchar *tmp = NULL; + again = FALSE; + + ret = sasl_client_new("irc", irc->server, NULL, NULL, irc->sasl_cb, 0, &irc->sasl_conn); + + if (ret != SASL_OK) { + purple_debug_error("irc", "sasl_client_new failed: %d\n", ret); + tmp = g_strdup_printf(_("Failed to initialize SASL authentication: %s"), + sasl_errdetail(irc->sasl_conn)); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_OTHER_ERROR, tmp); + g_free(tmp); + return; + } + + sasl_setprop(irc->sasl_conn, SASL_AUTH_EXTERNAL, irc->account->username); + sasl_setprop(irc->sasl_conn, SASL_SEC_PROPS, &secprops); + + ret = sasl_client_start(irc->sasl_conn, irc->sasl_mechs->str, NULL, NULL, NULL, &irc->current_mech); + + switch (ret) { + case SASL_OK: + case SASL_CONTINUE: + irc->mech_works = FALSE; + break; + case SASL_NOMECH: + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, + _("SASL authentication failed: No worthy authentication mechanisms found.")); + + irc_sasl_finish(irc); + return; + case SASL_BADPARAM: + case SASL_NOMEM: + tmp = g_strdup_printf(_("SASL authentication failed: %s"), sasl_errdetail(irc->sasl_conn)); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_OTHER_ERROR, tmp); + g_free(tmp); + + irc_sasl_finish(irc); + return; + default: + purple_debug_error("irc", "sasl_client_start failed: %s\n", sasl_errdetail(irc->sasl_conn)); + + if (irc->current_mech && *irc->current_mech) { + char *pos; + if ((pos = strstr(irc->sasl_mechs->str, irc->current_mech))) { + size_t index = pos - irc->sasl_mechs->str; + g_string_erase(irc->sasl_mechs, index, strlen(irc->current_mech)); + + /* Remove space which separated this mech from the next */ + if ((irc->sasl_mechs->str)[index] == ' ') { + g_string_erase(irc->sasl_mechs, index, 1); + } + } + + again = TRUE; + } + irc_sasl_finish(irc); + } + } while (again); + + purple_debug_info("irc", "Using SASL: %s\n", irc->current_mech); + + buf = irc_format(irc, "vv", "AUTHENTICATE", irc->current_mech); + irc_send(irc, buf); + g_free(buf); +} + +/* SASL authentication */ +void +irc_msg_cap(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + int ret = 0; + int id = 0; + PurpleConnection *gc = purple_account_get_connection(irc->account); + const char *mech_list = NULL; + + if (!args[1] || !args[2] || strncmp(args[2], "sasl ", 6)) + return; + if (strncmp(args[1], "ACK", 4)) { + const char *tmp = _("SASL authentication failed: Server does not support SASL authentication."); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, tmp); + + irc_sasl_finish(irc); + return; + } + + if ((ret = sasl_client_init(NULL)) != SASL_OK) { + const char *tmp = _("SASL authentication failed: Initializing SASL failed."); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_OTHER_ERROR, tmp); + return; + } + + irc->sasl_cb = g_new0(sasl_callback_t, 5); + + irc->sasl_cb[id].id = SASL_CB_AUTHNAME; + irc->sasl_cb[id].proc = irc_sasl_cb_simple; + irc->sasl_cb[id].context = (void *)irc; + id++; + + irc->sasl_cb[id].id = SASL_CB_USER; + irc->sasl_cb[id].proc = irc_sasl_cb_simple; + irc->sasl_cb[id].context = (void *)irc; + id++; + + irc->sasl_cb[id].id = SASL_CB_PASS; + irc->sasl_cb[id].proc = irc_sasl_cb_secret; + irc->sasl_cb[id].context = (void *)irc; + id++; + + irc->sasl_cb[id].id = SASL_CB_LOG; + irc->sasl_cb[id].proc = irc_sasl_cb_log; + irc->sasl_cb[id].context = (void *)irc; + id++; + + irc->sasl_cb[id].id = SASL_CB_LIST_END; + + /* We need to do this to be able to list the mechanisms. */ + ret = sasl_client_new("irc", irc->server, NULL, NULL, irc->sasl_cb, 0, &irc->sasl_conn); + + sasl_listmech(irc->sasl_conn, NULL, "", " ", "", &mech_list, NULL, NULL); + purple_debug_info("irc", "SASL: we have available: %s\n", mech_list); + + if (ret != SASL_OK) { + gchar *tmp; + + purple_debug_error("irc", "sasl_client_new failed: %d\n", ret); + tmp = g_strdup_printf(_("Failed to initialize SASL authentication: %s"), + sasl_errdetail(irc->sasl_conn)); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_OTHER_ERROR, tmp); + g_free(tmp); + + return; + } + + irc->sasl_mechs = g_string_new(mech_list); + + irc_auth_start_cyrus(irc); +} + +void +irc_msg_auth(struct irc_conn *irc, char *arg) +{ + PurpleConnection *gc = purple_account_get_connection(irc->account); + char *buf, *authinfo; + char *serverin = NULL; + unsigned serverinlen = 0; + const gchar *c_out; + unsigned int clen; + int ret; + + irc->mech_works = TRUE; + + if (!arg) + return; + + if (arg[0] != '+') { + serverin = arg; + serverinlen = strlen(serverin); + } + + ret = sasl_client_step(irc->sasl_conn, serverin, serverinlen, + NULL, &c_out, &clen); + + if (ret != SASL_OK && ret != SASL_CONTINUE) { + + gchar *tmp = g_strdup_printf(_("SASL authentication failed: %s"), + sasl_errdetail(irc->sasl_conn)); + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, tmp); + g_free(tmp); + + irc_sasl_finish(irc); + + return; + } + + authinfo = purple_base64_encode((const guchar*)c_out, clen); + + buf = irc_format(irc, "vv", "AUTHENTICATE", authinfo); + irc_send(irc, buf); + g_free(buf); + g_free(authinfo); +} + +void +irc_msg_authok(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + char *buf; + + sasl_dispose(&irc->sasl_conn); + irc->sasl_conn = NULL; + purple_debug_info("irc", "Succesfully authenticated using SASL.\n"); + + /* Finish auth session */ + buf = irc_format(irc, "vv", "CAP", "END"); + irc_send(irc, buf); + g_free(buf); +} + +void +irc_msg_authtryagain(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + PurpleConnection *gc = purple_account_get_connection(irc->account); + + /* We already received at least one AUTHENTICATE reply from the + * server. This suggests it supports this mechanism, but the + * password was incorrect. It would be better to abort and inform + * the user than to try again with a different mechanism, so they + * aren't told the server supports no worthy mechanisms. + */ + if (irc->mech_works) { + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect Password")); + + irc_sasl_finish(irc); + + return; + } + + if (irc->current_mech) { + char *pos; + if ((pos = strstr(irc->sasl_mechs->str, irc->current_mech))) { + size_t index = pos - irc->sasl_mechs->str; + g_string_erase(irc->sasl_mechs, index, strlen(irc->current_mech)); + + /* Remove space which separated this mech from the next */ + if ((irc->sasl_mechs->str)[index] == ' ') { + g_string_erase(irc->sasl_mechs, index, 1); + } + } + } + if (*irc->sasl_mechs->str) { + sasl_dispose(&irc->sasl_conn); + + purple_debug_info("irc", "Now trying with %s\n", irc->sasl_mechs->str); + irc_auth_start_cyrus(irc); + } else { + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, + _("SASL authentication failed: No worthy mechanisms found")); + + irc_sasl_finish(irc); + } +} + +void +irc_msg_authfail(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + PurpleConnection *gc = purple_account_get_connection(irc->account); + + /* Only show an error if we did not abort ourselves. */ + if (irc->sasl_conn) { + purple_debug_info("irc", "SASL authentication failed: %s", sasl_errdetail(irc->sasl_conn)); + + purple_connection_error_reason (gc, + PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect Password")); + } + + irc_sasl_finish(irc); +} + +static void +irc_sasl_finish(struct irc_conn *irc) +{ + char *buf; + + sasl_dispose(&irc->sasl_conn); + irc->sasl_conn = NULL; + + g_free(irc->sasl_cb); + irc->sasl_cb = NULL; + + /* Auth failed, abort */ + buf = irc_format(irc, "vv", "CAP", "END"); + irc_send(irc, buf); + g_free(buf); +} +#endif + void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args) { return;
--- a/libpurple/protocols/irc/parse.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/irc/parse.c Sat Feb 02 21:20:08 2013 +0100 @@ -73,7 +73,7 @@ { "324", "ncv:", irc_msg_chanmode }, /* Channel modes */ { "331", "nc:", irc_msg_topic }, /* No channel topic */ { "332", "nc:", irc_msg_topic }, /* Channel topic */ - { "333", "*", irc_msg_ignore }, /* Topic setter stuff */ + { "333", "ncvv", irc_msg_topicinfo }, /* Topic setter stuff */ { "352", "ncvvvnv:", irc_msg_who }, /* Channel WHO */ { "353", "nvc:", irc_msg_names }, /* Names list */ { "366", "nc:", irc_msg_names }, /* End of names */ @@ -102,6 +102,14 @@ { "501", "n:", irc_msg_badmode }, /* Unknown mode flag */ { "506", "nc:", irc_msg_nosend }, /* Must identify to send */ { "515", "nc:", irc_msg_regonly }, /* Registration required */ +#ifdef HAVE_CYRUS_SASL + { "903", "*", irc_msg_authok}, /* SASL auth successful */ + { "904", "*", irc_msg_authtryagain }, /* SASL auth failed, can recover */ + { "905", "*", irc_msg_authfail }, /* SASL auth failed */ + { "906", "*", irc_msg_authfail }, /* SASL auth failed */ + { "907", "*", irc_msg_authfail }, /* SASL auth failed */ + { "cap", "vv:", irc_msg_cap }, /* SASL capable */ +#endif { "invite", "n:", irc_msg_invite }, /* Invited */ { "join", ":", irc_msg_join }, /* Joined a channel */ { "kick", "cn:", irc_msg_kick }, /* KICK */ @@ -678,6 +686,11 @@ PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Disconnected.")); return; +#ifdef HAVE_CYRUS_SASL + } else if (!strncmp(input, "AUTHENTICATE ", 13)) { + irc_msg_auth(irc, input + 13); + return; +#endif } if (input[0] != ':' || (cur = strchr(input, ' ')) == NULL) {
--- a/libpurple/protocols/jabber/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -31,6 +31,8 @@ google/gmail.h \ google/google.c \ google/google.h \ + google/google_p2p.c \ + google/google_p2p.h \ google/google_presence.c \ google/google_presence.h \ google/google_roster.c \
--- a/libpurple/protocols/jabber/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -113,21 +113,9 @@ -lpurple ifeq ($(CYRUS_SASL), 1) -CYRUS_SASL_TOP := $(WIN32_DEV_TOP)/cyrus-sasl-2.1.25 INCLUDE_PATHS += -I$(CYRUS_SASL_TOP)/include LIB_PATHS += -L$(CYRUS_SASL_TOP)/bin LIBS += -llibsasl -CYRUS_SASL_DLLS = \ - $(CYRUS_SASL_TOP)/bin/libsasl.dll - -CYRUS_SASL_PLUGINS = \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslANONYMOUS.dll \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslCRAMMD5.dll \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslDIGESTMD5.dll \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslGSSAPI.dll \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslLOGIN.dll \ - $(CYRUS_SASL_TOP)/bin/sasl2/saslPLAIN.dll - endif include $(PIDGIN_COMMON_RULES) @@ -144,11 +132,6 @@ cp $(GTALK_TARGET).dll $(DLL_INSTALL_DIR) cp $(XMPP_TARGET).dll $(DLL_INSTALL_DIR) cp $(TARGET).dll $(PURPLE_INSTALL_DIR) -ifeq ($(CYRUS_SASL), 1) - mkdir -p $(PURPLE_INSTALL_DIR)/sasl2 - cp $(CYRUS_SASL_DLLS) $(PURPLE_INSTALL_DIR) - cp $(CYRUS_SASL_PLUGINS) $(PURPLE_INSTALL_DIR)/sasl2 -endif $(OBJECTS): $(PURPLE_CONFIG_H)
--- a/libpurple/protocols/jabber/auth_scram.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/auth_scram.c Sat Feb 02 21:20:08 2013 +0100 @@ -168,11 +168,6 @@ guchar *salted_password; guchar *client_key, *stored_key, *client_signature, *server_key; - client_key = g_new0(guchar, hash_len); - stored_key = g_new0(guchar, hash_len); - client_signature = g_new0(guchar, hash_len); - server_key = g_new0(guchar, hash_len); - data->client_proof = g_string_sized_new(hash_len); data->client_proof->len = hash_len; data->server_signature = g_string_sized_new(hash_len); @@ -186,6 +181,11 @@ if (!salted_password) return FALSE; + client_key = g_new0(guchar, hash_len); + stored_key = g_new0(guchar, hash_len); + client_signature = g_new0(guchar, hash_len); + server_key = g_new0(guchar, hash_len); + /* client_key = HMAC(salted_password, "Client Key") */ hmac(data->hash, client_key, salted_password, "Client Key"); /* server_key = HMAC(salted_password, "Server Key") */
--- a/libpurple/protocols/jabber/buddy.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/buddy.c Sat Feb 02 21:20:08 2013 +0100 @@ -1203,7 +1203,7 @@ char *img_text; char *hash; - jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png"))); + jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_new_with_id(g_memdup(data, size), size, "logo.png"))); img_text = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_p2p.c Sat Feb 02 21:20:08 2013 +0100 @@ -0,0 +1,442 @@ +/** + * @file google_p2p.c + * + * purple + * + * Purple 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 program 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 "internal.h" + +#include "google_p2p.h" +#include "jingle/jingle.h" +#include "debug.h" + +#include <string.h> + +struct _JingleGoogleP2PPrivate +{ + GList *local_candidates; + GList *remote_candidates; +}; + +#define JINGLE_GOOGLE_P2P_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2PPrivate)) + +static void jingle_google_p2p_class_init (JingleGoogleP2PClass *klass); +static void jingle_google_p2p_init (JingleGoogleP2P *google_p2p); +static void jingle_google_p2p_finalize (GObject *object); +static void jingle_google_p2p_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void jingle_google_p2p_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static JingleTransport *jingle_google_p2p_parse_internal(xmlnode *google_p2p); +static xmlnode *jingle_google_p2p_to_xml_internal(JingleTransport *transport, xmlnode *content, JingleActionType action); +static void jingle_google_p2p_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); +static GList *jingle_google_p2p_get_remote_candidates(JingleTransport *transport); + +static JingleTransportClass *parent_class = NULL; + +enum { + PROP_0, + PROP_LOCAL_CANDIDATES, + PROP_REMOTE_CANDIDATES, +}; + +static JingleGoogleP2PCandidate * +jingle_google_p2p_candidate_copy(JingleGoogleP2PCandidate *candidate) +{ + JingleGoogleP2PCandidate *new_candidate = g_new0(JingleGoogleP2PCandidate, 1); + new_candidate->id = g_strdup(candidate->id); + new_candidate->address = g_strdup(candidate->address); + new_candidate->port = candidate->port; + new_candidate->preference = candidate->preference; + new_candidate->type = g_strdup(candidate->type); + new_candidate->protocol = g_strdup(candidate->protocol); + new_candidate->username = g_strdup(candidate->username); + new_candidate->password = g_strdup(candidate->password); + new_candidate->generation = candidate->generation; + + new_candidate->rem_known = candidate->rem_known; + + return new_candidate; +} + +static void +jingle_google_p2p_candidate_free(JingleGoogleP2PCandidate *candidate) +{ + g_free(candidate->id); + g_free(candidate->address); + g_free(candidate->type); + g_free(candidate->protocol); + g_free(candidate->username); + g_free(candidate->password); +} + +GType +jingle_google_p2p_candidate_get_type(void) +{ + static GType type = 0; + + if (type == 0) { + type = g_boxed_type_register_static("JingleGoogleP2PCandidate", + (GBoxedCopyFunc)jingle_google_p2p_candidate_copy, + (GBoxedFreeFunc)jingle_google_p2p_candidate_free); + } + return type; +} + +JingleGoogleP2PCandidate * +jingle_google_p2p_candidate_new(const gchar *id, guint generation, + const gchar *address, guint port, guint preference, + const gchar *type, const gchar *protocol, + const gchar *username, const gchar *password) +{ + JingleGoogleP2PCandidate *candidate = g_new0(JingleGoogleP2PCandidate, 1); + candidate->id = g_strdup(id); + candidate->address = g_strdup(address); + candidate->port = port; + candidate->preference = preference; + candidate->type = g_strdup(type); + candidate->protocol = g_strdup(protocol); + candidate->username = g_strdup(username); + candidate->password = g_strdup(password); + candidate->generation = generation; + + candidate->rem_known = FALSE; + return candidate; +} + +GType +jingle_google_p2p_get_type(void) +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = { + sizeof(JingleGoogleP2PClass), + NULL, + NULL, + (GClassInitFunc) jingle_google_p2p_class_init, + NULL, + NULL, + sizeof(JingleGoogleP2P), + 0, + (GInstanceInitFunc) jingle_google_p2p_init, + NULL + }; + type = g_type_register_static(JINGLE_TYPE_TRANSPORT, "JingleGoogleP2P", &info, 0); + } + return type; +} + +static void +jingle_google_p2p_class_init(JingleGoogleP2PClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *)klass; + parent_class = g_type_class_peek_parent(klass); + + gobject_class->finalize = jingle_google_p2p_finalize; + gobject_class->set_property = jingle_google_p2p_set_property; + gobject_class->get_property = jingle_google_p2p_get_property; + klass->parent_class.to_xml = jingle_google_p2p_to_xml_internal; + klass->parent_class.parse = jingle_google_p2p_parse_internal; + klass->parent_class.transport_type = NS_GOOGLE_TRANSPORT_P2P; + klass->parent_class.add_local_candidate = jingle_google_p2p_add_local_candidate; + klass->parent_class.get_remote_candidates = jingle_google_p2p_get_remote_candidates; + + g_object_class_install_property(gobject_class, PROP_LOCAL_CANDIDATES, + g_param_spec_pointer("local-candidates", + "Local candidates", + "The local candidates for this transport.", + G_PARAM_READABLE)); + + g_object_class_install_property(gobject_class, PROP_REMOTE_CANDIDATES, + g_param_spec_pointer("remote-candidates", + "Remote candidates", + "The remote candidates for this transport.", + G_PARAM_READABLE)); + + g_type_class_add_private(klass, sizeof(JingleGoogleP2PPrivate)); +} + +static void +jingle_google_p2p_init(JingleGoogleP2P *google_p2p) +{ + google_p2p->priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); + google_p2p->priv->local_candidates = NULL; + google_p2p->priv->remote_candidates = NULL; +} + +static void +jingle_google_p2p_finalize(GObject *google_p2p) +{ +/* JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); */ + purple_debug_info("jingle","jingle_google_p2p_finalize\n"); + + G_OBJECT_CLASS(parent_class)->finalize(google_p2p); +} + +static void +jingle_google_p2p_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + JingleGoogleP2P *google_p2p; + + g_return_if_fail(object != NULL); + g_return_if_fail(JINGLE_IS_GOOGLE_P2P(object)); + + google_p2p = JINGLE_GOOGLE_P2P(object); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + google_p2p->priv->local_candidates = g_value_get_pointer(value); + break; + case PROP_REMOTE_CANDIDATES: + google_p2p->priv->remote_candidates = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +jingle_google_p2p_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + JingleGoogleP2P *google_p2p; + + g_return_if_fail(object != NULL); + g_return_if_fail(JINGLE_IS_GOOGLE_P2P(object)); + + google_p2p = JINGLE_GOOGLE_P2P(object); + + switch (prop_id) { + case PROP_LOCAL_CANDIDATES: + g_value_set_pointer(value, google_p2p->priv->local_candidates); + break; + case PROP_REMOTE_CANDIDATES: + g_value_set_pointer(value, google_p2p->priv->remote_candidates); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +jingle_google_p2p_add_local_candidate(JingleTransport *transport, const gchar *id, + guint generation, PurpleMediaCandidate *candidate) +{ + JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(transport); + JingleGoogleP2PCandidate *google_p2p_candidate; + gchar *ip; + gchar *username; + gchar *password; + PurpleMediaCandidateType type; + PurpleMediaNetworkProtocol protocol; + GList *iter; + + ip = purple_media_candidate_get_ip(candidate); + username = purple_media_candidate_get_username(candidate); + password = purple_media_candidate_get_password(candidate); + type = purple_media_candidate_get_candidate_type(candidate); + protocol = purple_media_candidate_get_protocol(candidate); + + google_p2p_candidate = jingle_google_p2p_candidate_new(id, generation, + ip, purple_media_candidate_get_port(candidate), + purple_media_candidate_get_priority(candidate), + type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : + "", + protocol == PURPLE_MEDIA_NETWORK_PROTOCOL_UDP ? "udp" : "tcp", + username, password); + + g_free(password); + g_free(username); + g_free(ip); + + for (iter = google_p2p->priv->local_candidates; iter; iter = g_list_next(iter)) { + JingleGoogleP2PCandidate *c = iter->data; + if (!strcmp(c->id, id)) { + generation = c->generation + 1; + + g_boxed_free(JINGLE_TYPE_GOOGLE_P2P_CANDIDATE, c); + google_p2p->priv->local_candidates = g_list_delete_link( + google_p2p->priv->local_candidates, iter); + + google_p2p_candidate->generation = generation; + + google_p2p->priv->local_candidates = g_list_append( + google_p2p->priv->local_candidates, candidate); + return; + } + } + + google_p2p->priv->local_candidates = g_list_append( + google_p2p->priv->local_candidates, google_p2p_candidate); +} + +static GList * +jingle_google_p2p_get_remote_candidates(JingleTransport *transport) +{ + JingleGoogleP2P *google_p2p = JINGLE_GOOGLE_P2P(transport); + GList *candidates = google_p2p->priv->remote_candidates; + GList *ret = NULL; + + for (; candidates; candidates = g_list_next(candidates)) { + JingleGoogleP2PCandidate *candidate = candidates->data; + PurpleMediaCandidate *new_candidate = purple_media_candidate_new("", 0, + !strcmp(candidate->type, "host") ? + PURPLE_MEDIA_CANDIDATE_TYPE_HOST : + !strcmp(candidate->type, "srflx") ? + PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX : + !strcmp(candidate->type, "prflx") ? + PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX : + !strcmp(candidate->type, "relay") ? + PURPLE_MEDIA_CANDIDATE_TYPE_RELAY : 0, + !strcmp(candidate->protocol, "udp") ? + PURPLE_MEDIA_NETWORK_PROTOCOL_UDP : + PURPLE_MEDIA_NETWORK_PROTOCOL_TCP, + candidate->address, candidate->port); + g_object_set(new_candidate, + "username", candidate->username, + "password", candidate->password, + "priority", candidate->preference, + NULL); + ret = g_list_append(ret, new_candidate); + } + + return ret; +} + +static JingleGoogleP2PCandidate * +jingle_google_p2p_get_remote_candidate_by_id(JingleGoogleP2P *google_p2p, + const gchar *id) +{ + GList *iter = google_p2p->priv->remote_candidates; + for (; iter; iter = g_list_next(iter)) { + JingleGoogleP2PCandidate *candidate = iter->data; + if (!strcmp(candidate->id, id)) { + return candidate; + } + } + return NULL; +} + +static void +jingle_google_p2p_add_remote_candidate(JingleGoogleP2P *google_p2p, JingleGoogleP2PCandidate *candidate) +{ + JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(google_p2p); + JingleGoogleP2PCandidate *google_p2p_candidate = + jingle_google_p2p_get_remote_candidate_by_id(google_p2p, + candidate->id); + if (google_p2p_candidate != NULL) { + priv->remote_candidates = g_list_remove(priv->remote_candidates, + google_p2p_candidate); + g_boxed_free(JINGLE_TYPE_GOOGLE_P2P_CANDIDATE, google_p2p_candidate); + } + priv->remote_candidates = g_list_append(priv->remote_candidates, candidate); +} + +static JingleTransport * +jingle_google_p2p_parse_internal(xmlnode *google_p2p) +{ + JingleTransport *transport = parent_class->parse(google_p2p); + xmlnode *candidate = xmlnode_get_child(google_p2p, "candidate"); + JingleGoogleP2PCandidate *google_p2p_candidate = NULL; + + for (; candidate; candidate = xmlnode_get_next_twin(candidate)) { + const gchar *generation = xmlnode_get_attrib(candidate, "generation"); + const gchar *id = xmlnode_get_attrib(candidate, "name"); + const gchar *address = xmlnode_get_attrib(candidate, "address"); + const gchar *port = xmlnode_get_attrib(candidate, "port"); + const gchar *preference = xmlnode_get_attrib(candidate, "preference"); + const gchar *type = xmlnode_get_attrib(candidate, "type"); + const gchar *protocol = xmlnode_get_attrib(candidate, "protocol"); + const gchar *username = xmlnode_get_attrib(candidate, "username"); + const gchar *password = xmlnode_get_attrib(candidate, "password"); + + if (!generation || !id || !address || !port || !preference || + !type || !protocol || !username || !password) + continue; + + google_p2p_candidate = jingle_google_p2p_candidate_new(id, + atoi(generation), + address, + atoi(port), + atoi(preference), + type, + protocol, + username, password); + google_p2p_candidate->rem_known = TRUE; + jingle_google_p2p_add_remote_candidate(JINGLE_GOOGLE_P2P(transport), google_p2p_candidate); + } + + return transport; +} + +static xmlnode * +jingle_google_p2p_to_xml_internal(JingleTransport *transport, xmlnode *content, JingleActionType action) +{ + xmlnode *node = parent_class->to_xml(transport, content, action); + + if (action == JINGLE_SESSION_INITIATE || + action == JINGLE_SESSION_ACCEPT || + action == JINGLE_TRANSPORT_INFO || + action == JINGLE_CONTENT_ADD || + action == JINGLE_TRANSPORT_REPLACE) { + JingleGoogleP2PPrivate *priv = JINGLE_GOOGLE_P2P_GET_PRIVATE(transport); + GList *iter = priv->local_candidates; + + for (; iter; iter = g_list_next(iter)) { + JingleGoogleP2PCandidate *candidate = iter->data; + xmlnode *xmltransport; + gchar *generation, *network, *port, *preference; + + if (candidate->rem_known == TRUE) + continue; + + candidate->rem_known = TRUE; + + xmltransport = xmlnode_new_child(node, "candidate"); + generation = g_strdup_printf("%d", candidate->generation); + network = g_strdup_printf("%d", candidate->network); + port = g_strdup_printf("%d", candidate->port); + preference = g_strdup_printf("%d", candidate->preference); + + xmlnode_set_attrib(xmltransport, "generation", generation); + xmlnode_set_attrib(xmltransport, "name", candidate->id); + xmlnode_set_attrib(xmltransport, "address", candidate->address); + xmlnode_set_attrib(xmltransport, "network", network); + xmlnode_set_attrib(xmltransport, "port", port); + xmlnode_set_attrib(xmltransport, "preference", preference); + xmlnode_set_attrib(xmltransport, "protocol", candidate->protocol); + xmlnode_set_attrib(xmltransport, "type", candidate->type); + xmlnode_set_attrib(xmltransport, "username", candidate->username); + xmlnode_set_attrib(xmltransport, "password", candidate->password); + + g_free(generation); + g_free(network); + g_free(port); + g_free(preference); + } + } + + return node; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_p2p.h Sat Feb 02 21:20:08 2013 +0100 @@ -0,0 +1,102 @@ +/** + * @file google_p2p.h + * + * purple + * + * Purple 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 program 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 + */ + +#ifndef PURPLE_JABBER_JINGLE_GOOGLE_P2P_H +#define PURPLE_JABBER_JINGLE_GOOGLE_P2P_H + +#include <glib.h> +#include <glib-object.h> + +#include "jingle/transport.h" + +G_BEGIN_DECLS + +#define JINGLE_TYPE_GOOGLE_P2P (jingle_google_p2p_get_type()) +#define JINGLE_TYPE_GOOGLE_P2P_CANDIDATE (jingle_google_p2p_candidate_get_type()) +#define JINGLE_GOOGLE_P2P(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2P)) +#define JINGLE_GOOGLE_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2PClass)) +#define JINGLE_IS_GOOGLE_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JINGLE_TYPE_GOOGLE_P2P)) +#define JINGLE_IS_GOOGLE_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), JINGLE_TYPE_GOOGLE_P2P)) +#define JINGLE_GOOGLE_P2P_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), JINGLE_TYPE_GOOGLE_P2P, JingleGoogleP2PClass)) + +/** @copydoc _JingleGoogleP2P */ +typedef struct _JingleGoogleP2P JingleGoogleP2P; +/** @copydoc _JingleGoogleP2PClass */ +typedef struct _JingleGoogleP2PClass JingleGoogleP2PClass; +/** @copydoc _JingleGoogleP2PPrivate */ +typedef struct _JingleGoogleP2PPrivate JingleGoogleP2PPrivate; +/** @copydoc _JingleGoogleP2PCandidate */ +typedef struct _JingleGoogleP2PCandidate JingleGoogleP2PCandidate; + +/** The Google P2P class */ +struct _JingleGoogleP2PClass +{ + JingleTransportClass parent_class; /**< The parent class. */ + + xmlnode *(*to_xml) (JingleTransport *transport, xmlnode *content, JingleActionType action); + JingleTransport *(*parse) (xmlnode *transport); +}; + +/** The Google P2P class's private data */ +struct _JingleGoogleP2P +{ + JingleTransport parent; /**< The parent of this object. */ + JingleGoogleP2PPrivate *priv; /**< The private data of this object. */ +}; + +struct _JingleGoogleP2PCandidate +{ + gchar *id; + gchar *address; + guint port; + guint preference; + gchar *type; + gchar *protocol; + guint network; + gchar *username; + gchar *password; + guint generation; + + gboolean rem_known; /* TRUE if the remote side knows + * about this candidate */ +}; + +GType jingle_google_p2p_candidate_get_type(void); + +/** + * Gets the Google P2P class's GType + * + * @return The Google P2P class's GType. + */ +GType jingle_google_p2p_get_type(void); + +JingleGoogleP2PCandidate *jingle_google_p2p_candidate_new(const gchar *id, + guint generation, const gchar *address, guint port, guint preference, + const gchar *type, const gchar *protocol, + const gchar *username, const gchar *password); + +G_END_DECLS + +#endif /* PURPLE_JABBER_JINGLE_GOOGLE_P2P_H */ +
--- a/libpurple/protocols/jabber/jingle/content.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/content.h Sat Feb 02 21:20:08 2013 +0100 @@ -68,10 +68,6 @@ JingleContentPrivate *priv; /**< The private data of this object. */ }; -#ifdef __cplusplus -extern "C" { -#endif - /** * Gets the content class's GType * @@ -111,10 +107,6 @@ xmlnode *jingle_content_to_xml(JingleContent *content, xmlnode *jingle, JingleActionType action); void jingle_content_handle_action(JingleContent *content, xmlnode *xmlcontent, JingleActionType action); -#ifdef __cplusplus -} -#endif - G_END_DECLS #endif /* PURPLE_JABBER_JINGLE_CONTENT_H */
--- a/libpurple/protocols/jabber/jingle/iceudp.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/iceudp.c Sat Feb 02 21:20:08 2013 +0100 @@ -45,6 +45,8 @@ static void jingle_iceudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static JingleTransport *jingle_iceudp_parse_internal(xmlnode *iceudp); static xmlnode *jingle_iceudp_to_xml_internal(JingleTransport *transport, xmlnode *content, JingleActionType action); +static void jingle_iceudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); +static GList *jingle_iceudp_get_remote_candidates(JingleTransport *transport); static JingleTransportClass *parent_class = NULL; @@ -58,10 +60,10 @@ jingle_iceudp_candidate_copy(JingleIceUdpCandidate *candidate) { JingleIceUdpCandidate *new_candidate = g_new0(JingleIceUdpCandidate, 1); + new_candidate->id = g_strdup(candidate->id); new_candidate->component = candidate->component; new_candidate->foundation = g_strdup(candidate->foundation); new_candidate->generation = candidate->generation; - new_candidate->id = g_strdup(candidate->id); new_candidate->ip = g_strdup(candidate->ip); new_candidate->network = candidate->network; new_candidate->port = candidate->port; @@ -105,17 +107,18 @@ } JingleIceUdpCandidate * -jingle_iceudp_candidate_new(guint component, const gchar *foundation, - guint generation, const gchar *id, const gchar *ip, +jingle_iceudp_candidate_new(const gchar *id, + guint component, const gchar *foundation, + guint generation, const gchar *ip, guint network, guint port, guint priority, const gchar *protocol, const gchar *type, const gchar *username, const gchar *password) { JingleIceUdpCandidate *candidate = g_new0(JingleIceUdpCandidate, 1); + candidate->id = g_strdup(id); candidate->component = component; candidate->foundation = g_strdup(foundation); candidate->generation = generation; - candidate->id = g_strdup(id); candidate->ip = g_strdup(ip); candidate->network = network; candidate->port = port; @@ -165,6 +168,8 @@ klass->parent_class.to_xml = jingle_iceudp_to_xml_internal; klass->parent_class.parse = jingle_iceudp_parse_internal; klass->parent_class.transport_type = JINGLE_TRANSPORT_ICEUDP; + klass->parent_class.add_local_candidate = jingle_iceudp_add_local_candidate; + klass->parent_class.get_remote_candidates = jingle_iceudp_get_remote_candidates; g_object_class_install_property(gobject_class, PROP_LOCAL_CANDIDATES, g_param_spec_pointer("local-candidates", @@ -246,36 +251,93 @@ } } -void -jingle_iceudp_add_local_candidate(JingleIceUdp *iceudp, JingleIceUdpCandidate *candidate) +static void +jingle_iceudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) { - GList *iter = iceudp->priv->local_candidates; + JingleIceUdp *iceudp = JINGLE_ICEUDP(transport); + PurpleMediaCandidateType type; + gchar *ip; + gchar *username; + gchar *password; + JingleIceUdpCandidate *iceudp_candidate; + GList *iter; + + ip = purple_media_candidate_get_ip(candidate); + username = purple_media_candidate_get_username(candidate); + password = purple_media_candidate_get_password(candidate); + type = purple_media_candidate_get_candidate_type(candidate); - for (; iter; iter = g_list_next(iter)) { + iceudp_candidate = jingle_iceudp_candidate_new(id, + purple_media_candidate_get_component_id(candidate), + purple_media_candidate_get_foundation(candidate), + generation, ip, 0, + purple_media_candidate_get_port(candidate), + purple_media_candidate_get_priority(candidate), "udp", + type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : + type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : + "", username, password); + iceudp_candidate->reladdr = purple_media_candidate_get_base_ip(candidate); + iceudp_candidate->relport = purple_media_candidate_get_base_port(candidate); + + g_free(password); + g_free(username); + g_free(ip); + + for (iter = iceudp->priv->local_candidates; iter; iter = g_list_next(iter)) { JingleIceUdpCandidate *c = iter->data; - if (!strcmp(c->id, candidate->id)) { - guint generation = c->generation + 1; + if (!strcmp(c->id, id)) { + generation = c->generation + 1; g_boxed_free(JINGLE_TYPE_ICEUDP_CANDIDATE, c); iceudp->priv->local_candidates = g_list_delete_link( iceudp->priv->local_candidates, iter); - candidate->generation = generation; + iceudp_candidate->generation = generation; iceudp->priv->local_candidates = g_list_append( - iceudp->priv->local_candidates, candidate); + iceudp->priv->local_candidates, iceudp_candidate); return; } } iceudp->priv->local_candidates = g_list_append( - iceudp->priv->local_candidates, candidate); + iceudp->priv->local_candidates, iceudp_candidate); } -GList * -jingle_iceudp_get_remote_candidates(JingleIceUdp *iceudp) +static GList * +jingle_iceudp_get_remote_candidates(JingleTransport *transport) { - return g_list_copy(iceudp->priv->remote_candidates); + JingleIceUdp *iceudp = JINGLE_ICEUDP(transport); + GList *candidates = iceudp->priv->remote_candidates; + GList *ret = NULL; + + for (; candidates; candidates = g_list_next(candidates)) { + JingleIceUdpCandidate *candidate = candidates->data; + PurpleMediaCandidate *new_candidate = purple_media_candidate_new( + candidate->foundation, candidate->component, + !strcmp(candidate->type, "host") ? + PURPLE_MEDIA_CANDIDATE_TYPE_HOST : + !strcmp(candidate->type, "srflx") ? + PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX : + !strcmp(candidate->type, "prflx") ? + PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX : + !strcmp(candidate->type, "relay") ? + PURPLE_MEDIA_CANDIDATE_TYPE_RELAY : 0, + PURPLE_MEDIA_NETWORK_PROTOCOL_UDP, + candidate->ip, candidate->port); + g_object_set(new_candidate, + "base-ip", candidate->reladdr, + "base-port", candidate->relport, + "username", candidate->username, + "password", candidate->password, + "priority", candidate->priority, + NULL); + ret = g_list_append(ret, new_candidate); + } + + return ret; } static JingleIceUdpCandidate * @@ -335,10 +397,10 @@ continue; iceudp_candidate = jingle_iceudp_candidate_new( + id, atoi(component), foundation, atoi(generation), - id, ip, atoi(network), atoi(port),
--- a/libpurple/protocols/jabber/jingle/iceudp.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/iceudp.h Sat Feb 02 21:20:08 2013 +0100 @@ -67,10 +67,10 @@ struct _JingleIceUdpCandidate { + gchar *id; guint component; gchar *foundation; guint generation; - gchar *id; gchar *ip; guint network; guint port; @@ -87,10 +87,6 @@ * about this candidate */ }; -#ifdef __cplusplus -extern "C" { -#endif - GType jingle_iceudp_candidate_get_type(void); /** @@ -100,17 +96,11 @@ */ GType jingle_iceudp_get_type(void); -JingleIceUdpCandidate *jingle_iceudp_candidate_new(guint component, - const gchar *foundation, guint generation, const gchar *id, +JingleIceUdpCandidate *jingle_iceudp_candidate_new(const gchar *id, + guint component, const gchar *foundation, guint generation, const gchar *ip, guint network, guint port, guint priority, const gchar *protocol, const gchar *type, const gchar *username, const gchar *password); -void jingle_iceudp_add_local_candidate(JingleIceUdp *iceudp, JingleIceUdpCandidate *candidate); -GList *jingle_iceudp_get_remote_candidates(JingleIceUdp *iceudp); - -#ifdef __cplusplus -} -#endif G_END_DECLS
--- a/libpurple/protocols/jabber/jingle/jingle.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/jingle.c Sat Feb 02 21:20:08 2013 +0100 @@ -29,6 +29,7 @@ #include "content.h" #include "debug.h" #include "jingle.h" +#include "google/google_p2p.h" #include "session.h" #include "iceudp.h" #include "rawudp.h" @@ -58,6 +59,8 @@ #ifdef USE_VV else if (!strcmp(type, JINGLE_APP_RTP)) return JINGLE_TYPE_RTP; + else if (!strcmp(type, NS_GOOGLE_TRANSPORT_P2P)) + return JINGLE_TYPE_GOOGLE_P2P; #endif #if 0 else if (!strcmp(type, JINGLE_APP_FT))
--- a/libpurple/protocols/jabber/jingle/jingle.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/jingle.h Sat Feb 02 21:20:08 2013 +0100 @@ -30,10 +30,6 @@ G_BEGIN_DECLS -#ifdef __cplusplus -extern "C" { -#endif - #define JINGLE "urn:xmpp:jingle:1" #define JINGLE_ERROR "urn:xmpp:jingle:errors:0" #define JINGLE_APP_FT "urn:xmpp:jingle:apps:file-transfer:1" @@ -86,10 +82,6 @@ const gchar *relay_username, const gchar *relay_password, guint *num_params); #endif -#ifdef __cplusplus -} -#endif - G_END_DECLS #endif /* PURPLE_JABBER_JINGLE_H */
--- a/libpurple/protocols/jabber/jingle/rawudp.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/rawudp.c Sat Feb 02 21:20:08 2013 +0100 @@ -45,6 +45,8 @@ static void jingle_rawudp_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static JingleTransport *jingle_rawudp_parse_internal(xmlnode *rawudp); static xmlnode *jingle_rawudp_to_xml_internal(JingleTransport *transport, xmlnode *content, JingleActionType action); +static void jingle_rawudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); +static GList *jingle_rawudp_get_remote_candidates(JingleTransport *transport); static JingleTransportClass *parent_class = NULL; @@ -137,6 +139,8 @@ klass->parent_class.to_xml = jingle_rawudp_to_xml_internal; klass->parent_class.parse = jingle_rawudp_parse_internal; klass->parent_class.transport_type = JINGLE_TRANSPORT_RAWUDP; + klass->parent_class.add_local_candidate = jingle_rawudp_add_local_candidate; + klass->parent_class.get_remote_candidates = jingle_rawudp_get_remote_candidates; g_object_class_install_property(gobject_class, PROP_LOCAL_CANDIDATES, g_param_spec_pointer("local-candidates", @@ -218,36 +222,58 @@ } } -void -jingle_rawudp_add_local_candidate(JingleRawUdp *rawudp, JingleRawUdpCandidate *candidate) +static void +jingle_rawudp_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) { - GList *iter = rawudp->priv->local_candidates; + JingleRawUdp *rawudp = JINGLE_RAWUDP(transport); + gchar *ip; + JingleRawUdpCandidate *rawudp_candidate; + GList *iter; - for (; iter; iter = g_list_next(iter)) { + ip = purple_media_candidate_get_ip(candidate); + rawudp_candidate = jingle_rawudp_candidate_new(id, generation, + purple_media_candidate_get_component_id(candidate), + ip, purple_media_candidate_get_port(candidate)); + g_free(ip); + + for (iter = rawudp->priv->local_candidates; iter; iter = g_list_next(iter)) { JingleRawUdpCandidate *c = iter->data; - if (!strcmp(c->id, candidate->id)) { - guint generation = c->generation + 1; + if (!strcmp(c->id, id)) { + generation = c->generation + 1; g_boxed_free(JINGLE_TYPE_RAWUDP_CANDIDATE, c); rawudp->priv->local_candidates = g_list_delete_link( rawudp->priv->local_candidates, iter); - candidate->generation = generation; + rawudp_candidate->generation = generation; rawudp->priv->local_candidates = g_list_append( - rawudp->priv->local_candidates, candidate); + rawudp->priv->local_candidates, rawudp_candidate); return; } } rawudp->priv->local_candidates = g_list_append( - rawudp->priv->local_candidates, candidate); + rawudp->priv->local_candidates, rawudp_candidate); } -GList * -jingle_rawudp_get_remote_candidates(JingleRawUdp *rawudp) +static GList * +jingle_rawudp_get_remote_candidates(JingleTransport *transport) { - return g_list_copy(rawudp->priv->remote_candidates); + JingleRawUdp *rawudp = JINGLE_RAWUDP(transport); + GList *candidates = rawudp->priv->remote_candidates; + GList *ret = NULL; + + for (; candidates; candidates = g_list_next(candidates)) { + JingleRawUdpCandidate *candidate = candidates->data; + ret = g_list_append(ret, purple_media_candidate_new("", + candidate->component, + PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX, + PURPLE_MEDIA_NETWORK_PROTOCOL_UDP, + candidate->ip, candidate->port)); + } + + return ret; } static JingleRawUdpCandidate *
--- a/libpurple/protocols/jabber/jingle/rawudp.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/rawudp.h Sat Feb 02 21:20:08 2013 +0100 @@ -77,10 +77,6 @@ * about this candidate */ }; -#ifdef __cplusplus -extern "C" { -#endif - GType jingle_rawudp_candidate_get_type(void); /** @@ -92,12 +88,6 @@ JingleRawUdpCandidate *jingle_rawudp_candidate_new(const gchar *id, guint generation, guint component, const gchar *ip, guint port); -void jingle_rawudp_add_local_candidate(JingleRawUdp *rawudp, JingleRawUdpCandidate *candidate); -GList *jingle_rawudp_get_remote_candidates(JingleRawUdp *rawudp); - -#ifdef __cplusplus -} -#endif G_END_DECLS
--- a/libpurple/protocols/jabber/jingle/rtp.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/rtp.c Sat Feb 02 21:20:08 2013 +0100 @@ -28,6 +28,7 @@ #include "jabber.h" #include "jingle.h" +#include "google/google_p2p.h" #include "media.h" #include "mediamanager.h" #include "iceudp.h" @@ -226,134 +227,23 @@ return media; } -static JingleRawUdpCandidate * -jingle_rtp_candidate_to_rawudp(JingleSession *session, guint generation, - PurpleMediaCandidate *candidate) -{ - gchar *id = jabber_get_next_id(jingle_session_get_js(session)); - gchar *ip = purple_media_candidate_get_ip(candidate); - JingleRawUdpCandidate *rawudp_candidate = - jingle_rawudp_candidate_new(id, generation, - purple_media_candidate_get_component_id(candidate), - ip, purple_media_candidate_get_port(candidate)); - g_free(ip); - g_free(id); - return rawudp_candidate; -} - -static JingleIceUdpCandidate * -jingle_rtp_candidate_to_iceudp(JingleSession *session, guint generation, - PurpleMediaCandidate *candidate) -{ - gchar *id = jabber_get_next_id(jingle_session_get_js(session)); - gchar *ip = purple_media_candidate_get_ip(candidate); - gchar *username = purple_media_candidate_get_username(candidate); - gchar *password = purple_media_candidate_get_password(candidate); - PurpleMediaCandidateType type = - purple_media_candidate_get_candidate_type(candidate); - - JingleIceUdpCandidate *iceudp_candidate = jingle_iceudp_candidate_new( - purple_media_candidate_get_component_id(candidate), - purple_media_candidate_get_foundation(candidate), - generation, id, ip, 0, - purple_media_candidate_get_port(candidate), - purple_media_candidate_get_priority(candidate), "udp", - type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : - type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : - type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : - type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : - "", username, password); - iceudp_candidate->reladdr = - purple_media_candidate_get_base_ip(candidate); - iceudp_candidate->relport = - purple_media_candidate_get_base_port(candidate); - g_free(password); - g_free(username); - g_free(ip); - g_free(id); - return iceudp_candidate; -} - static JingleTransport * -jingle_rtp_candidates_to_transport(JingleSession *session, GType type, guint generation, GList *candidates) +jingle_rtp_candidates_to_transport(JingleSession *session, const gchar *type, guint generation, GList *candidates) { - if (type == JINGLE_TYPE_RAWUDP) { - JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_RAWUDP); - JingleRawUdpCandidate *rawudp_candidate; - for (; candidates; candidates = g_list_next(candidates)) { - PurpleMediaCandidate *candidate = candidates->data; - rawudp_candidate = jingle_rtp_candidate_to_rawudp( - session, generation, candidate); - jingle_rawudp_add_local_candidate( - JINGLE_RAWUDP(transport), - rawudp_candidate); - } - return transport; - } else if (type == JINGLE_TYPE_ICEUDP) { - JingleTransport *transport = jingle_transport_create(JINGLE_TRANSPORT_ICEUDP); - JingleIceUdpCandidate *iceudp_candidate; - for (; candidates; candidates = g_list_next(candidates)) { - PurpleMediaCandidate *candidate = candidates->data; - iceudp_candidate = jingle_rtp_candidate_to_iceudp( - session, generation, candidate); - jingle_iceudp_add_local_candidate( - JINGLE_ICEUDP(transport), - iceudp_candidate); - } - return transport; - } else { + JingleTransport *transport; + + transport = jingle_transport_create(type); + if (!transport) return NULL; - } -} - -static GList * -jingle_rtp_transport_to_candidates(JingleTransport *transport) -{ - const gchar *type = jingle_transport_get_transport_type(transport); - GList *ret = NULL; - if (!strcmp(type, JINGLE_TRANSPORT_RAWUDP)) { - GList *candidates = jingle_rawudp_get_remote_candidates(JINGLE_RAWUDP(transport)); - for (; candidates; candidates = g_list_delete_link(candidates, candidates)) { - JingleRawUdpCandidate *candidate = candidates->data; - ret = g_list_append(ret, purple_media_candidate_new( - "", candidate->component, - PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX, - PURPLE_MEDIA_NETWORK_PROTOCOL_UDP, - candidate->ip, candidate->port)); - } - - return ret; - } else if (!strcmp(type, JINGLE_TRANSPORT_ICEUDP)) { - GList *candidates = jingle_iceudp_get_remote_candidates(JINGLE_ICEUDP(transport)); + for (; candidates; candidates = g_list_next(candidates)) { + PurpleMediaCandidate *candidate = candidates->data; + gchar *id = jabber_get_next_id(jingle_session_get_js(session)); + jingle_transport_add_local_candidate(transport, id, generation, candidate); + g_free(id); + } - for (; candidates; candidates = g_list_delete_link(candidates, candidates)) { - JingleIceUdpCandidate *candidate = candidates->data; - PurpleMediaCandidate *new_candidate = purple_media_candidate_new( - candidate->foundation, candidate->component, - !strcmp(candidate->type, "host") ? - PURPLE_MEDIA_CANDIDATE_TYPE_HOST : - !strcmp(candidate->type, "srflx") ? - PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX : - !strcmp(candidate->type, "prflx") ? - PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX : - !strcmp(candidate->type, "relay") ? - PURPLE_MEDIA_CANDIDATE_TYPE_RELAY : 0, - PURPLE_MEDIA_NETWORK_PROTOCOL_UDP, - candidate->ip, candidate->port); - g_object_set(new_candidate, - "base-ip", candidate->reladdr, - "base-port", candidate->relport, - "username", candidate->username, - "password", candidate->password, - "priority", candidate->priority, NULL); - ret = g_list_append(ret, new_candidate); - } - - return ret; - } else { - return NULL; - } + return transport; } static void jingle_rtp_ready(JingleSession *session); @@ -378,10 +268,9 @@ oldtransport = jingle_content_get_transport(content); candidates = purple_media_get_local_candidates(media, sid, name); - transport = JINGLE_TRANSPORT(jingle_rtp_candidates_to_transport( - session, JINGLE_IS_RAWUDP(oldtransport) ? - JINGLE_TYPE_RAWUDP : JINGLE_TYPE_ICEUDP, - 0, candidates)); + transport = jingle_rtp_candidates_to_transport( + session, jingle_transport_get_transport_type(oldtransport), + 0, candidates); g_list_free(candidates); g_object_unref(oldtransport); @@ -404,9 +293,9 @@ static void jingle_rtp_new_candidate_cb(PurpleMedia *media, gchar *sid, gchar *name, PurpleMediaCandidate *candidate, JingleSession *session) { - JingleContent *content = jingle_session_find_content( - session, sid, NULL); + JingleContent *content = jingle_session_find_content(session, sid, NULL); JingleTransport *transport; + gchar *id; purple_debug_info("jingle-rtp", "jingle_rtp_new_candidate_cb\n"); @@ -419,19 +308,13 @@ transport = jingle_content_get_transport(content); - if (JINGLE_IS_ICEUDP(transport)) - jingle_iceudp_add_local_candidate(JINGLE_ICEUDP(transport), - jingle_rtp_candidate_to_iceudp( - session, 1, candidate)); - else if (JINGLE_IS_RAWUDP(transport)) - jingle_rawudp_add_local_candidate(JINGLE_RAWUDP(transport), - jingle_rtp_candidate_to_rawudp( - session, 1, candidate)); + id = jabber_get_next_id(jingle_session_get_js(session)); + jingle_transport_add_local_candidate(transport, id, 1, candidate); + g_free(id); g_object_unref(transport); - jabber_iq_send(jingle_session_to_packet(session, - JINGLE_TRANSPORT_INFO)); + jabber_iq_send(jingle_session_to_packet(session, JINGLE_TRANSPORT_INFO)); } static void @@ -604,6 +487,8 @@ transmitter = "rawudp"; else if (JINGLE_IS_ICEUDP(transport)) transmitter = "nice"; + else if (JINGLE_IS_GOOGLE_P2P(transport)) + transmitter = "nice"; else transmitter = "notransmitter"; g_object_unref(transport); @@ -827,7 +712,7 @@ transport = jingle_transport_parse( xmlnode_get_child(xmlcontent, "transport")); description = xmlnode_get_child(xmlcontent, "description"); - candidates = jingle_rtp_transport_to_candidates(transport); + candidates = jingle_transport_get_remote_candidates(transport); codecs = jingle_rtp_parse_codecs(description); name = jingle_content_get_name(content); remote_jid = jingle_session_get_remote_jid(session); @@ -863,7 +748,7 @@ JingleSession *session = jingle_content_get_session(content); JingleTransport *transport = jingle_transport_parse( xmlnode_get_child(xmlcontent, "transport")); - GList *candidates = jingle_rtp_transport_to_candidates(transport); + GList *candidates = jingle_transport_get_remote_candidates(transport); gchar *name = jingle_content_get_name(content); gchar *remote_jid = jingle_session_get_remote_jid(session); @@ -973,6 +858,8 @@ transport_type = JINGLE_TRANSPORT_ICEUDP; } else if (jabber_resource_has_capability(jbr, JINGLE_TRANSPORT_RAWUDP)) { transport_type = JINGLE_TRANSPORT_RAWUDP; + } else if (jabber_resource_has_capability(jbr, NS_GOOGLE_TRANSPORT_P2P)) { + transport_type = NS_GOOGLE_TRANSPORT_P2P; } else { purple_debug_error("jingle-rtp", "Resource doesn't support " "the same transport types\n");
--- a/libpurple/protocols/jabber/jingle/rtp.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/rtp.h Sat Feb 02 21:20:08 2013 +0100 @@ -65,10 +65,6 @@ JingleRtpPrivate *priv; /**< The private data of this object. */ }; -#ifdef __cplusplus -extern "C" { -#endif - /** * Gets the rtp class's GType * @@ -84,10 +80,6 @@ PurpleMediaSessionType type); void jingle_rtp_terminate_session(JabberStream *js, const gchar *who); -#ifdef __cplusplus -} -#endif - G_END_DECLS #endif /* USE_VV */
--- a/libpurple/protocols/jabber/jingle/session.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/session.h Sat Feb 02 21:20:08 2013 +0100 @@ -62,10 +62,6 @@ struct _JingleContent; -#ifdef __cplusplus -extern "C" { -#endif - /** * Gets the session class's GType * @@ -109,10 +105,6 @@ JabberIq *jingle_session_terminate_packet(JingleSession *session, const gchar *reason); JabberIq *jingle_session_redirect_packet(JingleSession *session, const gchar *sid); -#ifdef __cplusplus -} -#endif - G_END_DECLS #endif /* PURPLE_JABBER_JINGLE_SESSION_H */
--- a/libpurple/protocols/jabber/jingle/transport.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/transport.c Sat Feb 02 21:20:08 2013 +0100 @@ -44,6 +44,8 @@ static void jingle_transport_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); JingleTransport *jingle_transport_parse_internal(xmlnode *transport); xmlnode *jingle_transport_to_xml_internal(JingleTransport *transport, xmlnode *content, JingleActionType action); +static void jingle_transport_add_local_candidate_internal(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); +static GList *jingle_transport_get_remote_candidates_internal(JingleTransport *transport); static GObjectClass *parent_class = NULL; @@ -85,6 +87,8 @@ gobject_class->get_property = jingle_transport_get_property; klass->to_xml = jingle_transport_to_xml_internal; klass->parse = jingle_transport_parse_internal; + klass->add_local_candidate = jingle_transport_add_local_candidate_internal; + klass->get_remote_candidates = jingle_transport_get_remote_candidates_internal; g_type_class_add_private(klass, sizeof(JingleTransportPrivate)); } @@ -143,6 +147,32 @@ return JINGLE_TRANSPORT_GET_CLASS(transport)->transport_type; } +void +jingle_transport_add_local_candidate(JingleTransport *transport, const gchar *id, + guint generation, PurpleMediaCandidate *candidate) +{ + JINGLE_TRANSPORT_GET_CLASS(transport)->add_local_candidate(transport, id, + generation, candidate); +} + +void +jingle_transport_add_local_candidate_internal(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate) +{ + /* Nothing to do */ +} + +GList * +jingle_transport_get_remote_candidates(JingleTransport *transport) +{ + return JINGLE_TRANSPORT_GET_CLASS(transport)->get_remote_candidates(transport); +} + +static GList * +jingle_transport_get_remote_candidates_internal(JingleTransport *transport) +{ + return NULL; +} + JingleTransport * jingle_transport_parse_internal(xmlnode *transport) {
--- a/libpurple/protocols/jabber/jingle/transport.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/jingle/transport.h Sat Feb 02 21:20:08 2013 +0100 @@ -55,6 +55,8 @@ const gchar *transport_type; xmlnode *(*to_xml) (JingleTransport *transport, xmlnode *content, JingleActionType action); JingleTransport *(*parse) (xmlnode *transport); + void (*add_local_candidate) (JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); + GList *(*get_remote_candidates) (JingleTransport *transport); }; /** The transport class's private data */ @@ -64,10 +66,6 @@ JingleTransportPrivate *priv; /**< The private data of this object. */ }; -#ifdef __cplusplus -extern "C" { -#endif - /** * Gets the transport class's GType * @@ -77,15 +75,13 @@ JingleTransport *jingle_transport_create(const gchar *type); const gchar *jingle_transport_get_transport_type(JingleTransport *transport); -void jingle_transport_add_candidate(); + +void jingle_transport_add_local_candidate(JingleTransport *transport, const gchar *id, guint generation, PurpleMediaCandidate *candidate); +GList *jingle_transport_get_remote_candidates(JingleTransport *transport); JingleTransport *jingle_transport_parse(xmlnode *transport); xmlnode *jingle_transport_to_xml(JingleTransport *transport, xmlnode *content, JingleActionType action); -#ifdef __cplusplus -} -#endif - G_END_DECLS #endif /* PURPLE_JABBER_JINGLE_TRANSPORT_H */
--- a/libpurple/protocols/jabber/message.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/message.c Sat Feb 02 21:20:08 2013 +0100 @@ -219,6 +219,7 @@ { JabberID *jid = jabber_id_new(jm->from); JabberChat *chat; + PurpleMessageFlags messageFlags = 0; if(!jid) return; @@ -231,6 +232,7 @@ if(jm->subject) { purple_conv_chat_set_topic(PURPLE_CONV_CHAT(chat->conv), jid->resource, jm->subject); + messageFlags |= PURPLE_MESSAGE_NO_LOG; if(!jm->xhtml && !jm->body) { char *msg, *tmp, *tmp2; tmp = g_markup_escape_text(jm->subject, -1); @@ -239,7 +241,7 @@ msg = g_strdup_printf(_("%s has set the topic to: %s"), jid->resource, tmp2); else msg = g_strdup_printf(_("The topic is: %s"), tmp2); - purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", msg, PURPLE_MESSAGE_SYSTEM, jm->sent); + purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", msg, messageFlags | PURPLE_MESSAGE_SYSTEM, jm->sent); g_free(tmp); g_free(tmp2); g_free(msg); @@ -249,12 +251,12 @@ if(jm->xhtml || jm->body) { if(jid->resource) serv_got_chat_in(jm->js->gc, chat->id, jid->resource, - jm->delayed ? PURPLE_MESSAGE_DELAYED : 0, + messageFlags | (jm->delayed ? PURPLE_MESSAGE_DELAYED : 0), jm->xhtml ? jm->xhtml : jm->body, jm->sent); else if(chat->muc) purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", jm->xhtml ? jm->xhtml : jm->body, - PURPLE_MESSAGE_SYSTEM, jm->sent); + messageFlags | PURPLE_MESSAGE_SYSTEM, jm->sent); } jabber_id_free(jid);
--- a/libpurple/protocols/jabber/namespaces.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/namespaces.h Sat Feb 02 21:20:08 2013 +0100 @@ -109,6 +109,8 @@ #define NS_GOOGLE_SESSION_PHONE "http://www.google.com/session/phone" #define NS_GOOGLE_SESSION_VIDEO "http://www.google.com/session/video" +#define NS_GOOGLE_TRANSPORT_P2P "http://www.google.com/transport/p2p" + /* Apple extension(s) */ #define NS_APPLE_IDLE "http://www.apple.com/xmpp/idle"
--- a/libpurple/protocols/jabber/oob.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/oob.c Sat Feb 02 21:20:08 2013 +0100 @@ -211,6 +211,7 @@ jox = g_new0(JabberOOBXfer, 1); if (!purple_url_parse(url, &jox->address, &jox->port, &jox->page, NULL, NULL)) { g_free(url); + g_free(jox); return; } g_free(url);
--- a/libpurple/protocols/jabber/presence.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/jabber/presence.c Sat Feb 02 21:20:08 2013 +0100 @@ -384,7 +384,7 @@ char *who; }; -static void authorize_add_cb(gpointer data) +static void authorize_add_cb(const char *message, gpointer data) { struct _jabber_add_permit *jap = data; if(PURPLE_CONNECTION_IS_VALID(jap->gc)) @@ -394,7 +394,7 @@ g_free(jap); } -static void deny_add_cb(gpointer data) +static void deny_add_cb(const char *message, gpointer data) { struct _jabber_add_permit *jap = data; if(PURPLE_CONNECTION_IS_VALID(jap->gc))
--- a/libpurple/protocols/msn/msn.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/msn/msn.c Sat Feb 02 21:20:08 2013 +0100 @@ -2783,7 +2783,7 @@ { char buf[1024]; purple_debug_info("msn", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len); - id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL); + id = purple_imgstore_new_with_id(g_memdup(url_text, len), len, NULL); g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id); purple_notify_user_info_prepend_pair_html(user_info, NULL, buf); }
--- a/libpurple/protocols/msn/notification.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/msn/notification.c Sat Feb 02 21:20:08 2013 +0100 @@ -1592,7 +1592,7 @@ /* Disconnect others, if MPOP is disabled */ if (is_me && !session->enable_mpop - && strncasecmp(id + 1, session->guid, 36) != 0) { + && g_ascii_strncasecmp(id + 1, session->guid, 36) != 0) { purple_debug_info("msn", "Disconnecting Endpoint %s\n", id); tmp = g_strdup_printf("%s;%s", user->passport, id);
--- a/libpurple/protocols/msn/switchboard.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/msn/switchboard.c Sat Feb 02 21:20:08 2013 +0100 @@ -827,7 +827,7 @@ return; } - imgid = purple_imgstore_add_with_id(image_data, image_len, NULL); + imgid = purple_imgstore_new_with_id(image_data, image_len, NULL); image_msg = g_strdup_printf("<IMG SRC='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>", imgid);
--- a/libpurple/protocols/msn/user.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/msn/user.c Sat Feb 02 21:20:08 2013 +0100 @@ -761,17 +761,7 @@ str = purple_normalize_nocase(NULL, msn_user_get_passport(user)); pass = g_strdup(str); -#if GLIB_CHECK_VERSION(2,16,0) result = g_strcmp0(pass, purple_normalize_nocase(NULL, passport)); -#else - str = purple_normalize_nocase(NULL, passport); - if (!pass) - result = -(pass != str); - else if (!str) - result = pass != str; - else - result = strcmp(pass, str); -#endif /* GLIB < 2.16.0 */ g_free(pass);
--- a/libpurple/protocols/msn/userlist.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/msn/userlist.c Sat Feb 02 21:20:08 2013 +0100 @@ -46,7 +46,7 @@ * Callbacks **************************************************************************/ static void -msn_accept_add_cb(gpointer data) +msn_accept_add_cb(const char *message, gpointer data) { MsnPermitAdd *pa = data; @@ -71,7 +71,7 @@ } static void -msn_cancel_add_cb(gpointer data) +msn_cancel_add_cb(const char *message, gpointer data) { MsnPermitAdd *pa = data;
--- a/libpurple/protocols/mxit/actions.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/actions.c Sat Feb 02 21:20:08 2013 +0100 @@ -43,11 +43,12 @@ */ static void mxit_profile_cb( PurpleConnection* gc, PurpleRequestFields* fields ) { - struct MXitSession* session = purple_connection_get_protocol_data( gc ) ; + struct MXitSession* session = purple_connection_get_protocol_data( gc ); PurpleRequestField* field = NULL; const char* name = NULL; const char* bday = NULL; const char* err = NULL; + GList* entry = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_profile_cb\n" ); @@ -166,6 +167,14 @@ g_string_append( attributes, attrib ); acount++; + /* relationship status */ + field = purple_request_fields_get_field( fields, "relationship" ); + entry = g_list_first( purple_request_field_list_get_selected( field ) ); + profile->relationship = atoi( purple_request_field_list_get_data( field, entry->data ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%i", CP_PROFILE_RELATIONSHIP, CP_PROFILE_TYPE_SHORT, profile->relationship ); + g_string_append( attributes, attrib ); + acount++; + /* update flags */ field = purple_request_fields_get_field( fields, "searchable" ); if ( purple_request_field_bool_get_value( field ) ) /* is searchable -> clear not-searchable flag */ @@ -253,6 +262,22 @@ field = purple_request_field_string_new( "whereami", _( "Where I Live" ), profile->whereami, FALSE); purple_request_field_group_add_field( public_group, field ); + /* relationship status */ + field = purple_request_field_list_new( "relationship", _( "Relationship Status" ) ); + purple_request_field_list_set_multi_select( field, FALSE ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_UNKNOWN ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_UNKNOWN ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_DONTSAY ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_DONTSAY ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_SINGLE ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_SINGLE ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_INVOLVED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_INVOLVED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_ENGAGED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_ENGAGED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_MARRIED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_MARRIED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_COMPLICATED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_COMPLICATED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_WIDOWED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_WIDOWED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_SEPARATED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_SEPARATED ) ); + purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_DIVORCED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_DIVORCED ) ); + purple_request_field_list_add_selected( field, mxit_relationship_to_name( profile->relationship ) ); + purple_request_field_group_add_field( public_group, field ); + purple_request_fields_add_group( fields, public_group ); }
--- a/libpurple/protocols/mxit/cipher.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/cipher.c Sat Feb 02 21:20:08 2013 +0100 @@ -163,6 +163,10 @@ /* base64 decode the message */ raw_message = purple_base64_decode( message, &raw_len ); + /* AES-encrypted data is always blocks of 16 bytes */ + if ( ( raw_len == 0 ) || ( raw_len % 16 != 0 ) ) + return NULL; + /* build the AES key */ ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
--- a/libpurple/protocols/mxit/formcmds.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/formcmds.c Sat Feb 02 21:20:08 2013 +0100 @@ -107,7 +107,7 @@ } /* we now have the inline image, store a copy in the imagestore */ - id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL); + id = purple_imgstore_new_with_id(g_memdup(url_text, len), len, NULL); /* map the inline image id to purple image id */ intptr = g_malloc(sizeof(int)); @@ -335,7 +335,7 @@ if (img) { rawimg = purple_base64_decode(img, &rawimglen); //purple_util_write_data_to_file_absolute("/tmp/mxitinline.png", (char*) rawimg, rawimglen); - imgid = purple_imgstore_add_with_id(rawimg, rawimglen, NULL); + imgid = purple_imgstore_new_with_id(rawimg, rawimglen, NULL); g_string_append_printf(msg, "<img src=\"" PURPLE_STORED_IMAGE_PROTOCOL "%i\">", imgid);
--- a/libpurple/protocols/mxit/markup.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/markup.c Sat Feb 02 21:20:08 2013 +0100 @@ -60,7 +60,9 @@ }; -#define MXIT_VIBE_MSG_COLOR "#9933FF" +#define MXIT_VIBE_MSG_COLOR "#9933FF" +#define MXIT_FAREWELL_MSG_COLOR "#949494" + /* vibes */ static const char* vibes[] = { @@ -594,7 +596,7 @@ } /* we now have the emoticon, store it in the imagestore */ - id = purple_imgstore_add_with_id( em_data, em_size, NULL ); + id = purple_imgstore_new_with_id( em_data, em_size, NULL ); /* map the mxit emoticon id to purple image id */ intptr = g_malloc( sizeof( int ) ); @@ -1004,6 +1006,12 @@ break; } } + + if ( msgflags & CP_MSG_FAREWELL ) { + /* this is a farewell message */ + g_string_prepend( mx->msg, "<font color=\""MXIT_FAREWELL_MSG_COLOR"\"><i>" ); + g_string_append( mx->msg, "</i></font>" ); + } }
--- a/libpurple/protocols/mxit/multimx.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/multimx.c Sat Feb 02 21:20:08 2013 +0100 @@ -514,7 +514,7 @@ } /* Send Subscription Reject to MXit */ - mxit_send_deny_sub(session, multimx->roomid); + mxit_send_deny_sub(session, multimx->roomid, NULL); /* Remove from our list of rooms */ room_remove(session, multimx);
--- a/libpurple/protocols/mxit/mxit.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/mxit.c Sat Feb 02 21:20:08 2013 +0100 @@ -427,7 +427,7 @@ char* statusmsg2; /* Handle mood changes */ - if ( purple_status_type_get_primitive(purple_status_get_type( status ) ) == PURPLE_STATUS_MOOD ) { + if ( purple_status_type_get_primitive( purple_status_get_type( status ) ) == PURPLE_STATUS_MOOD ) { const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME ); int mood; @@ -669,7 +669,7 @@ static PurplePluginProtocolInfo proto_info = { sizeof( PurplePluginProtocolInfo ), /* struct_size */ - OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE, /* options */ + OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE, /* options */ NULL, /* user_splits */ NULL, /* protocol_options */ { /* icon_spec */
--- a/libpurple/protocols/mxit/profile.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/profile.c Sat Feb 02 21:20:08 2013 +0100 @@ -35,6 +35,40 @@ /*------------------------------------------------------------------------ + * Return the MXit Relationship status as a string. + * + * @param id The Relationship status value (see profile.h) + * @return The relationship status as a text string. + */ +const char* mxit_relationship_to_name( short id ) +{ + switch ( id ) { + case MXIT_RELATIONSHIP_UNKNOWN : + return _( "Unknown" ); + case MXIT_RELATIONSHIP_DONTSAY : + return _( "Don't want to say" ); + case MXIT_RELATIONSHIP_SINGLE : + return _( "Single" ); + case MXIT_RELATIONSHIP_INVOLVED : + return _( "In a relationship" ); + case MXIT_RELATIONSHIP_ENGAGED : + return _( "Engaged" ); + case MXIT_RELATIONSHIP_MARRIED : + return _( "Married" ); + case MXIT_RELATIONSHIP_COMPLICATED : + return _( "It's complicated" ); + case MXIT_RELATIONSHIP_WIDOWED : + return _( "Widowed" ); + case MXIT_RELATIONSHIP_SEPARATED : + return _( "Separated" ); + case MXIT_RELATIONSHIP_DIVORCED : + return _( "Divorced" ); + default : + return ""; + } +} + +/*------------------------------------------------------------------------ * Returns true if it is a valid date. * * @param bday Date-of-Birth string (YYYY-MM-DD) @@ -130,7 +164,7 @@ age = now.tm_year - bdate.tm_year; if ( now.tm_mon < bdate.tm_mon ) /* is before month of birth */ age--; - else if ( (now.tm_mon == bdate.tm_mon ) && ( now.tm_mday < bdate.tm_mday ) ) /* before birthday in current month */ + else if ( ( now.tm_mon == bdate.tm_mon ) && ( now.tm_mday < bdate.tm_mday ) ) /* before birthday in current month */ age--; return age; @@ -195,6 +229,8 @@ if ( *profile->whereami ) purple_notify_user_info_add_pair_plaintext( info, _( "Where I Live" ), profile->whereami ); + purple_notify_user_info_add_pair_plaintext( info, _( "Relationship Status" ), mxit_relationship_to_name( profile->relationship ) ); + purple_notify_user_info_add_section_break( info ); if ( contact ) { @@ -236,7 +272,7 @@ img_text = g_strdup_printf( "<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'>", contact->imgid ); purple_notify_user_info_add_pair_html( info, _( "Photo" ), img_text ); - g_free(img_text); + g_free( img_text ); } if ( contact->statusMsg ) {
--- a/libpurple/protocols/mxit/profile.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/profile.h Sat Feb 02 21:20:08 2013 +0100 @@ -29,6 +29,18 @@ #include <glib.h> +/* MXit relationship status types */ +#define MXIT_RELATIONSHIP_UNKNOWN 0 +#define MXIT_RELATIONSHIP_DONTSAY 1 +#define MXIT_RELATIONSHIP_SINGLE 2 +#define MXIT_RELATIONSHIP_INVOLVED 3 +#define MXIT_RELATIONSHIP_ENGAGED 4 +#define MXIT_RELATIONSHIP_MARRIED 5 +#define MXIT_RELATIONSHIP_COMPLICATED 6 +#define MXIT_RELATIONSHIP_WIDOWED 7 +#define MXIT_RELATIONSHIP_SEPARATED 8 +#define MXIT_RELATIONSHIP_DIVORCED 9 + struct MXitProfile { /* required */ char loginname[64]; /* name user uses to log into MXit with (aka 'mxitid') */ @@ -47,6 +59,7 @@ char regcountry[3]; /* user's registered country code */ char whereami[51]; /* where am I / where I live */ char aboutme[513]; /* about me */ + int relationship; /* relationship status */ int flags; /* user's profile flags */ gint64 lastonline; /* user's last-online timestamp */ @@ -55,6 +68,7 @@ struct MXitSession; void mxit_show_profile( struct MXitSession* session, const char* username, struct MXitProfile* profile ); void mxit_show_search_results( struct MXitSession* session, int searchType, int maxResults, GList* entries ); +const char* mxit_relationship_to_name( short id ); gboolean validateDate( const char* bday );
--- a/libpurple/protocols/mxit/protocol.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/protocol.c Sat Feb 02 21:20:08 2013 +0100 @@ -459,7 +459,7 @@ packet->headerlen = 0; /* create generic packet header */ - hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc), CP_REC_TERM ); /* client msisdn */ + hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM ); /* client msisdn */ if ( session->http ) { /* http connection only */ @@ -1065,8 +1065,9 @@ * * @param session The MXit session object * @param username The username of the contact being denied + * @param reason The message describing the reason for the rejection (can be NULL). */ -void mxit_send_deny_sub( struct MXitSession* session, const char* username ) +void mxit_send_deny_sub( struct MXitSession* session, const char* username, const char* reason ) { char data[CP_MAX_PACKET]; int datalen; @@ -1077,6 +1078,10 @@ username ); + /* append reason (if one is set) */ + if ( reason ) + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, reason ); + /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_DENY ); } @@ -1136,7 +1141,7 @@ * @param id The identifier of the event (received in message) * @param event Identified the type of event */ -void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event) +void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event ) { char data[CP_MAX_PACKET]; int datalen; @@ -1451,7 +1456,7 @@ const char* statusmsg; const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL, - CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS }; + CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_RELATIONSHIP, CP_PROFILE_FLAGS }; purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); @@ -1878,6 +1883,10 @@ /* about me */ g_strlcpy( profile->aboutme, fvalue, sizeof( profile->aboutme ) ); } + else if ( strcmp( CP_PROFILE_RELATIONSHIP, fname ) == 0) { + /* relatinship status */ + profile->relationship = strtol( fvalue, NULL, 10 ); + } else { /* invalid profile attribute */ purple_debug_error( MXIT_PLUGIN_ID, "Invalid profile attribute received '%s' \n", fname ); @@ -2031,6 +2040,47 @@ g_list_foreach( entries, (GFunc)g_free, NULL ); } +/*------------------------------------------------------------------------ + * Process a received message event packet. + * + * @param session The MXit session object + * @param records The packet's data records + * @param rcount The number of data records + */ +static void mxit_parse_cmd_msgevent( struct MXitSession* session, struct record** records, int rcount ) +{ + int event; + + /* + * contactAddress \1 dateTime \1 id \1 event + */ + + /* strip off dummy domain */ + mxit_strip_domain( records[0]->fields[0]->data ); + + event = atoi( records[0]->fields[3]->data ); + + switch ( event ) { + case CP_MSGEVENT_TYPING : /* user is typing */ + case CP_MSGEVENT_ANGRY : /* user is typing angrily */ + serv_got_typing( session->con, records[0]->fields[0]->data, 0, PURPLE_TYPING ); + break; + + case CP_MSGEVENT_STOPPED : /* user has stopped typing */ + serv_got_typing_stopped( session->con, records[0]->fields[0]->data ); + break; + + case CP_MSGEVENT_ERASING : /* user is erasing text */ + case CP_MSGEVENT_DELIVERED : /* message was delivered */ + case CP_MSGEVENT_DISPLAYED : /* message was viewed */ + /* these are currently not supported by libPurple */ + break; + + default: + purple_debug_error( MXIT_PLUGIN_ID, "Unknown message event received (%i)\n", event ); + } +} + /*------------------------------------------------------------------------ * Return the length of a multimedia chunk @@ -2137,7 +2187,7 @@ contact = get_mxit_invite_contact( session, chunk.mxitid ); if ( contact ) { /* this is an invite (add image to the internal image store) */ - contact->imgid = purple_imgstore_add_with_id( g_memdup( chunk.data, chunk.length ), chunk.length, NULL ); + contact->imgid = purple_imgstore_new_with_id( g_memdup( chunk.data, chunk.length ), chunk.length, NULL ); /* show the profile */ mxit_show_profile( session, chunk.mxitid, contact->profile ); } @@ -2310,6 +2360,11 @@ mxit_parse_cmd_suggestcontacts( session, &packet->records[2], packet->rcount - 2 ); break; + case CP_CMD_GOT_MSGEVENT : + /* received message event */ + mxit_parse_cmd_msgevent( session, &packet->records[2], packet->rcount - 2 ); + break; + case CP_CMD_MOOD : /* mood update */ case CP_CMD_UPDATE :
--- a/libpurple/protocols/mxit/protocol.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/protocol.h Sat Feb 02 21:20:08 2013 +0100 @@ -77,9 +77,12 @@ #define MXIT_CF_VOICE 0x1000000 #define MXIT_CF_VIDEO 0x2000000 #define MXIT_CF_TOUCHSCREEN 0x4000000 +#define MXIT_CF_SVC_CONNECTION 0x8000000 +#define MXIT_CF_MXML 0x10000000 +#define MXIT_CF_TYPING_NOTIFY 0x20000000 /* Client features supported by this implementation */ -#define MXIT_CP_FEATURES ( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 ) +#define MXIT_CP_FEATURES ( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 | MXIT_CF_TYPING_NOTIFY ) #define MXIT_PING_INTERVAL ( 5 * 60 ) /* ping the server after X seconds of being idle (5 minutes) */ @@ -132,6 +135,7 @@ #define CP_CMD_SPLASHCLICK 0x001F /* (31) splash-screen clickthrough */ #define CP_CMD_STATUS 0x0020 /* (32) set shown presence & status */ #define CP_CMD_MSGEVENT 0x0023 /* (35) Raise message event */ +#define CP_CMD_GOT_MSGEVENT 0x0024 /* (36) Get message event */ #define CP_CMD_MOOD 0x0029 /* (41) set mood */ #define CP_CMD_KICK 0x002B /* (43) login kick */ #define CP_CMD_GRPCHAT_CREATE 0x002C /* (44) create new groupchat */ @@ -161,6 +165,7 @@ #define CP_MSG_RPLY_TL_ENCRYPT 0x0080 /* reply should be transport encrypted */ #define CP_MSG_MARKUP 0x0200 /* message may contain markup */ #define CP_MSG_EMOTICON 0x0400 /* message may contain custom emoticons */ +#define CP_MSG_FAREWELL 0x0800 /* this is a farewell message */ /* redirect types */ #define CP_REDIRECT_PERMANENT 1 /* permanent redirect */ @@ -178,6 +183,10 @@ /* message event types */ #define CP_MSGEVENT_DELIVERED 0x02 /* message was delivered */ #define CP_MSGEVENT_DISPLAYED 0x04 /* message was viewed */ +#define CP_MSGEVENT_TYPING 0x10 /* user is typing */ +#define CP_MSGEVENT_STOPPED 0x20 /* user has stopped typing */ +#define CP_MSGEVENT_ANGRY 0x40 /* user is typing angrily */ +#define CP_MSGEVENT_ERASING 0x80 /* user is erasing text */ /* extended profile attribute fields */ #define CP_PROFILE_BIRTHDATE "birthdate" /* Birthdate (String - ISO 8601 format) */ @@ -198,9 +207,11 @@ #define CP_PROFILE_LASTSEEN "lastseen" /* Last-Online timestamp */ #define CP_PROFILE_WHEREAMI "whereami" /* Where am I / Where I live */ #define CP_PROFILE_ABOUTME "aboutme" /* About me */ +#define CP_PROFILE_RELATIONSHIP "relationship" /* Relationship Status */ /* extended profile field types */ #define CP_PROFILE_TYPE_BOOL 0x02 /* boolean (0 or 1) */ +#define CP_PROFILE_TYPE_SHORT 0x04 /* short (16-bit) */ #define CP_PROFILE_TYPE_INT 0x05 /* integer (32-bit) */ #define CP_PROFILE_TYPE_LONG 0x06 /* long (64-bit) */ #define CP_PROFILE_TYPE_UTF8 0x0A /* UTF8 string */ @@ -315,7 +326,7 @@ void mxit_send_invite( struct MXitSession* session, const char* username, gboolean mxitid, const char* alias, const char* groupname, const char* message ); void mxit_send_remove( struct MXitSession* session, const char* username ); void mxit_send_allow_sub( struct MXitSession* session, const char* username, const char* alias ); -void mxit_send_deny_sub( struct MXitSession* session, const char* username ); +void mxit_send_deny_sub( struct MXitSession* session, const char* username, const char* reason ); void mxit_send_update_contact( struct MXitSession* session, const char* username, const char* alias, const char* groupname ); void mxit_send_splashclick( struct MXitSession* session, const char* splashid ); void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event);
--- a/libpurple/protocols/mxit/roster.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/roster.c Sat Feb 02 21:20:08 2013 +0100 @@ -583,7 +583,7 @@ * * @param user_data Object associated with the invite */ -static void mxit_cb_buddy_auth( gpointer user_data ) +static void mxit_cb_buddy_auth( const char *message, gpointer user_data ) { struct contact_invite* invite = (struct contact_invite*) user_data; @@ -612,14 +612,14 @@ * * @param user_data Object associated with the invite */ -static void mxit_cb_buddy_deny( gpointer user_data ) +static void mxit_cb_buddy_deny( const char *message, gpointer user_data ) { struct contact_invite* invite = (struct contact_invite*) user_data; purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_buddy_deny '%s'\n", invite->contact->username ); /* send a deny subscription packet to MXit */ - mxit_send_deny_sub( invite->session, invite->contact->username ); + mxit_send_deny_sub( invite->session, invite->contact->username, message ); /* remove the invite from our internal invites list */ invite->session->invites = g_list_remove( invite->session->invites, invite->contact );
--- a/libpurple/protocols/mxit/roster.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/roster.h Sat Feb 02 21:20:08 2013 +0100 @@ -82,6 +82,7 @@ /* MXit presence flags */ #define MXIT_PFLAG_VOICE 0x1 #define MXIT_PFLAG_VIDEO 0x2 +#define MXIT_PFLAG_TYPING 0x4 /* Subscription types */
--- a/libpurple/protocols/mxit/splashscreen.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/mxit/splashscreen.c Sat Feb 02 21:20:08 2013 +0100 @@ -184,7 +184,7 @@ char buf[128]; /* Add splash-image to imagestore */ - imgid = purple_imgstore_add_with_id(g_memdup(imgdata, imglen), imglen, NULL); + imgid = purple_imgstore_new_with_id(g_memdup(imgdata, imglen), imglen, NULL); /* Generate and display message */ g_snprintf(buf, sizeof(buf),
--- a/libpurple/protocols/myspace/message.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/myspace/message.c Sat Feb 02 21:20:08 2013 +0100 @@ -129,7 +129,7 @@ * * @param first_key The first argument (a key), or NULL to take all arguments * from argp. - * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d. + * @param argp A va_list of variadic arguments, already started with va_start(). * @return New MsimMessage *, must be freed with msim_msg_free(). * * For internal use - users probably want msim_msg_new() or msim_send(). @@ -211,7 +211,6 @@ break; } } while(key); - va_end(argp); return msg; } @@ -227,14 +226,16 @@ MsimMessage * msim_msg_new(gchar *first_key, ...) { + MsimMessage *ret = NULL; va_list argp; if (first_key) { - va_start(argp, first_key); - return msim_msg_new_v(first_key, argp); - } else { - return NULL; + va_start(argp, first_key); + ret = msim_msg_new_v(first_key, argp); + va_end(argp); } + + return ret; } /** @@ -960,6 +961,7 @@ va_start(argp, session); msg = msim_msg_new_v(NULL, argp); + va_end(argp); /* Actually send the message. */ success = msim_msg_send(session, msg);
--- a/libpurple/protocols/myspace/myspace.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/myspace/myspace.c Sat Feb 02 21:20:08 2013 +0100 @@ -3577,7 +3577,10 @@ gc = purple_account_get_connection(account); session = purple_connection_get_protocol_data(gc); - g_return_val_if_fail(session != NULL, FALSE); + if (session == NULL) { + g_free(cid_str); + return FALSE; + } /* Lookup userid to username. TODO: push this down, to IM sending/contact * adding functions. */ @@ -3595,6 +3598,7 @@ return TRUE; } + g_free(cid_str); return FALSE; }
--- a/libpurple/protocols/oscar/authorization.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/authorization.c Sat Feb 02 21:20:08 2013 +0100 @@ -67,7 +67,7 @@ } static void -oscar_auth_grant(gpointer cbdata) +oscar_auth_grant(const char *message, gpointer cbdata) { struct name_data *data = cbdata; PurpleConnection *gc = data->gc; @@ -79,8 +79,9 @@ } static void -oscar_auth_dontgrant(struct name_data *data, char *msg) +oscar_auth_dontgrant(const char *msg, gpointer cbdata) { + struct name_data *data = cbdata; PurpleConnection *gc = data->gc; OscarData *od = purple_connection_get_protocol_data(gc); @@ -89,18 +90,6 @@ oscar_free_name_data(data); } -static void -oscar_auth_dontgrant_msgprompt(gpointer cbdata) -{ - struct name_data *data = cbdata; - purple_request_input(data->gc, NULL, _("Authorization Denied Message:"), - NULL, _("No reason given."), TRUE, FALSE, NULL, - _("_OK"), G_CALLBACK(oscar_auth_dontgrant), - _("_Cancel"), G_CALLBACK(oscar_free_name_data), - purple_connection_get_account(data->gc), data->name, NULL, - data); -} - void oscar_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored) { @@ -127,5 +116,5 @@ purple_account_request_authorization(account, data->name, NULL, data->nick, reason, purple_find_buddy(account, data->name) != NULL, - oscar_auth_grant, oscar_auth_dontgrant_msgprompt, data); + oscar_auth_grant, oscar_auth_dontgrant, data); }
--- a/libpurple/protocols/oscar/family_feedbag.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/family_feedbag.c Sat Feb 02 21:20:08 2013 +0100 @@ -605,9 +605,10 @@ if (od->ssi.pending) { for (cur=od->ssi.pending; cur->next; cur=cur->next); cur->next = new; - } else + } else { od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1); + } + aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1); } } } @@ -626,9 +627,10 @@ if (od->ssi.pending) { for (cur=od->ssi.pending; cur->next; cur=cur->next); cur->next = new; - } else + } else { od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Adding item ", cur1); + } + aim_ssi_item_debug_append(debugstr, "Adding item ", cur1); } } } @@ -648,20 +650,23 @@ if (od->ssi.pending) { for (cur=od->ssi.pending; cur->next; cur=cur->next); cur->next = new; - } else + } else { od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1); + } + aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1); } } } if (debugstr->len > 0) { purple_debug_info("oscar", "%s", debugstr->str); if (purple_debug_is_verbose()) { + PurpleAccount *account = purple_connection_get_account(od->gc); g_string_truncate(debugstr, 0); - for (cur1 = od->ssi.local.data; cur1; cur1 = cur1->next) + for (cur1 = od->ssi.local.data; cur1; cur1 = cur1->next) { aim_ssi_item_debug_append(debugstr, "\t", cur1); + } purple_debug_misc("oscar", "Dumping item list of account %s:\n%s", - purple_account_get_username(purple_connection_get_account(od->gc)), debugstr->str); + purple_account_get_username(account), debugstr->str); } } g_string_free(debugstr, TRUE);
--- a/libpurple/protocols/oscar/libaim.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/libaim.c Sat Feb 02 21:20:08 2013 +0100 @@ -30,7 +30,7 @@ static PurplePluginProtocolInfo prpl_info = { sizeof(PurplePluginProtocolInfo), /* struct_size */ - OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE, + OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE, NULL, /* user_splits */ NULL, /* protocol_options */ {"gif,jpeg,bmp,ico", 0, 0, 64, 64, 7168, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
--- a/libpurple/protocols/oscar/libicq.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/libicq.c Sat Feb 02 21:20:08 2013 +0100 @@ -39,7 +39,7 @@ static PurplePluginProtocolInfo prpl_info = { sizeof(PurplePluginProtocolInfo), /* struct_size */ - OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE, + OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE, NULL, /* user_splits */ NULL, /* protocol_options */ {"gif,jpeg,bmp,ico", 0, 0, 64, 64, 7168, PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
--- a/libpurple/protocols/oscar/odc.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/odc.c Sat Feb 02 21:20:08 2013 +0100 @@ -356,7 +356,7 @@ if ((embedded_data != NULL) && (embedded_data->size == size)) { - imgid = purple_imgstore_add_with_id(g_memdup(embedded_data->data, size), size, src); + imgid = purple_imgstore_new_with_id(g_memdup(embedded_data->data, size), size, src); /* Record the image number */ images = g_slist_append(images, GINT_TO_POINTER(imgid));
--- a/libpurple/protocols/oscar/oscar.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/oscar/oscar.c Sat Feb 02 21:20:08 2013 +0100 @@ -633,15 +633,6 @@ return subtype1 - subtype2; } -#if !GLIB_CHECK_VERSION(2,14,0) -static void hash_table_get_list_of_keys(gpointer key, gpointer value, gpointer user_data) -{ - GList **handlers = (GList **)user_data; - - *handlers = g_list_prepend(*handlers, key); -} -#endif /* GLIB < 2.14.0 */ - void oscar_login(PurpleAccount *account) { @@ -711,12 +702,7 @@ oscar_data_addhandler(od, SNAC_FAMILY_USERLOOKUP, 0x0003, purple_parse_searchreply, 0); g_string_append(msg, "Registered handlers: "); -#if GLIB_CHECK_VERSION(2,14,0) handlers = g_hash_table_get_keys(od->handlerlist); -#else - handlers = NULL; - g_hash_table_foreach(od->handlerlist, hash_table_get_list_of_keys, &handlers); -#endif /* GLIB < 2.14.0 */ sorted_handlers = g_list_sort(g_list_copy(handlers), compare_handlers); for (cur = sorted_handlers; cur; cur = cur->next) { guint x = GPOINTER_TO_UINT(cur->data); @@ -2317,6 +2303,7 @@ va_list ap; guint16 chan, reason; char *who; + int ret = 1; va_start(ap, fr); chan = (guint16)va_arg(ap, unsigned int); @@ -2325,7 +2312,7 @@ if (chan == 0x0002) { /* File transfer declined */ guchar *cookie = va_arg(ap, guchar *); - return purple_parse_clientauto_ch2(od, who, reason, cookie); + ret = purple_parse_clientauto_ch2(od, who, reason, cookie); } else if (chan == 0x0004) { /* ICQ message */ guint32 state = 0; char *msg = NULL; @@ -2333,12 +2320,12 @@ state = va_arg(ap, guint32); msg = va_arg(ap, char *); } - return purple_parse_clientauto_ch4(od, who, reason, state, msg); + ret = purple_parse_clientauto_ch4(od, who, reason, state, msg); } va_end(ap); - return 1; + return ret; } static int purple_parse_genericerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
--- a/libpurple/protocols/sametime/sametime.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/sametime/sametime.c Sat Feb 02 21:20:08 2013 +0100 @@ -2780,7 +2780,7 @@ cid = make_cid(cid); /* add image to the purple image store */ - img = purple_imgstore_add_with_id(d_dat, d_len, cid); + img = purple_imgstore_new_with_id(d_dat, d_len, cid); /* map the cid to the image store identifier */ g_hash_table_insert(img_by_cid, cid, GINT_TO_POINTER(img));
--- a/libpurple/protocols/silc/ops.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/silc/ops.c Sat Feb 02 21:20:08 2013 +0100 @@ -207,7 +207,7 @@ if (channel && !convo) goto out; - imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, ""); + imgid = purple_imgstore_new_with_id(g_memdup(data, data_len), data_len, ""); if (imgid) { cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV; g_snprintf(tmp, sizeof(tmp),
--- a/libpurple/protocols/silc/util.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/silc/util.c Sat Feb 02 21:20:08 2013 +0100 @@ -309,6 +309,13 @@ if (fd != -1) close(fd); +#ifdef _WIN32 + /* on win32, we calloc pw so pass it to free + * (see the getpwuid code below) + */ + free(pw); +#endif + return TRUE; }
--- a/libpurple/protocols/yahoo/libyahoo.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/libyahoo.c Sat Feb 02 21:20:08 2013 +0100 @@ -195,7 +195,7 @@ static PurplePluginProtocolInfo prpl_info = { sizeof(PurplePluginProtocolInfo), /* struct_size */ - OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, + OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE, NULL, /* user_splits */ NULL, /* protocol_options */ {"png,gif,jpeg", 96, 96, 96, 96, 0, PURPLE_ICON_SCALE_SEND},
--- a/libpurple/protocols/yahoo/libyahoojp.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/libyahoojp.c Sat Feb 02 21:20:08 2013 +0100 @@ -91,7 +91,7 @@ static PurplePluginProtocolInfo prpl_info = { sizeof(PurplePluginProtocolInfo), /* struct_size */ - OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, + OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC | OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE, NULL, /* user_splits */ NULL, /* protocol_options */ {"png,gif,jpeg", 96, 96, 96, 96, 0, PURPLE_ICON_SCALE_SEND},
--- a/libpurple/protocols/yahoo/libymsg.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/libymsg.c Sat Feb 02 21:20:08 2013 +0100 @@ -1197,7 +1197,7 @@ }; static void -yahoo_buddy_add_authorize_cb(gpointer data) +yahoo_buddy_add_authorize_cb(const char *message, gpointer data) { struct yahoo_add_request *add_req = data; struct yahoo_packet *pkt; @@ -1230,7 +1230,7 @@ } static void -yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg) +yahoo_buddy_add_deny_cb(const char *msg, struct yahoo_add_request *add_req) { YahooData *yd = purple_connection_get_protocol_data(add_req->gc); struct yahoo_packet *pkt; @@ -1274,23 +1274,6 @@ g_free(add_req); } -static void -yahoo_buddy_add_deny_noreason_cb(struct yahoo_add_request *add_req, const char*msg) -{ - yahoo_buddy_add_deny_cb(add_req, NULL); -} - -static void -yahoo_buddy_add_deny_reason_cb(gpointer data) { - struct yahoo_add_request *add_req = data; - purple_request_input(add_req->gc, NULL, _("Authorization denied message:"), - NULL, _("No reason given."), TRUE, FALSE, NULL, - _("OK"), G_CALLBACK(yahoo_buddy_add_deny_cb), - _("Cancel"), G_CALLBACK(yahoo_buddy_add_deny_noreason_cb), - purple_connection_get_account(add_req->gc), add_req->who, NULL, - add_req); -} - static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason) { char *notify_msg; @@ -1453,7 +1436,7 @@ alias, dec_msg, purple_find_buddy(account, add_req->who) != NULL, yahoo_buddy_add_authorize_cb, - yahoo_buddy_add_deny_reason_cb, + yahoo_buddy_add_deny_cb, add_req); g_free(alias); g_free(dec_msg); @@ -1518,7 +1501,7 @@ NULL, dec_msg, purple_find_buddy(account,add_req->who) != NULL, yahoo_buddy_add_authorize_cb, - yahoo_buddy_add_deny_reason_cb, add_req); + yahoo_buddy_add_deny_cb, add_req); g_free(dec_msg); } else { g_free(add_req->id); @@ -2954,7 +2937,7 @@ msg = pair->value; break; case 232: - /* weird number (md5 hash?), like 8ebab9094156135f5dcbaccbeee662a5c5fd1420 */ + /* SHA-1 hash of audible SWF file (eg: 4e8691499d9c0fb8374478ff9720f4a9ea4a4915) */ break; } @@ -2975,7 +2958,7 @@ return; } if (id) { - /* "http://us.dl1.yimg.com/download.yahoo.com/dl/aud/"+locale+"/"+id+".swf" */ + /* "http://l.yimg.com/pu/dl/aud/"+locale+"/"+id+".swf" */ char **audible_locale = g_strsplit(id, ".", 0); char *buf = g_strdup_printf(_("[ Audible %s/%s/%s.swf ] %s"), YAHOO_AUDIBLE_URL, audible_locale[1], id, msg); g_strfreev(audible_locale);
--- a/libpurple/protocols/yahoo/libymsg.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/libymsg.h Sat Feb 02 21:20:08 2013 +0100 @@ -61,7 +61,7 @@ #define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/" #define YAHOOJP_ROOMLIST_LOCALE "ja" -#define YAHOO_AUDIBLE_URL "http://us.dl1.yimg.com/download.yahoo.com/dl/aud" +#define YAHOO_AUDIBLE_URL "http://l.yimg.com/pu/dl/aud" #define WEBMESSENGER_URL "http://login.yahoo.com/config/login?.src=pg" @@ -96,6 +96,7 @@ #define YAHOOJP_CLIENT_VERSION "9.0.0.1727" #define YAHOO_CLIENT_USERAGENT "Mozilla/5.0" +#define YAHOO_CLIENT_USERAGENT_ALIAS "Mozilla/4.0 (compatible; MSIE 5.5)" /* Index into attention types list. */ #define YAHOO_BUZZ 0
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Sat Feb 02 21:20:08 2013 +0100 @@ -1420,6 +1420,7 @@ purple_debug_warning("yahoo","p2p-ft: Wrong HEAD/GET request from peer, disconnecting host\n"); purple_input_remove(xd->input_event); purple_xfer_cancel_remote(xfer); + g_free(url_get); g_free(url_head); return; }
--- a/libpurple/protocols/yahoo/yahoo_profile.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/yahoo/yahoo_profile.c Sat Feb 02 21:20:08 2013 +0100 @@ -1046,7 +1046,7 @@ } else { purple_debug_info("yahoo", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len); - id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL); + id = purple_imgstore_new_with_id(g_memdup(url_text, len), len, NULL); tmp = g_strdup_printf("<img id=\"" PURPLE_STORED_IMAGE_PROTOCOL "%d\"><br>", id);
--- a/libpurple/protocols/zephyr/zephyr.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/protocols/zephyr/zephyr.c Sat Feb 02 21:20:08 2013 +0100 @@ -1501,6 +1501,7 @@ } fclose(f); } + g_free(fname); } static void process_anyone(PurpleConnection *gc) @@ -2166,11 +2167,15 @@ len = strlen(zsendstr); result = write(zephyr->totzc[ZEPHYR_FD_WRITE], zsendstr, len); if (result != len) { + g_free(tzc_sig); + g_free(tzc_body); g_free(zsendstr); g_free(html_buf2); g_free(html_buf); return errno; } + g_free(tzc_sig); + g_free(tzc_body); g_free(zsendstr); } else if (use_zeph02(zephyr)) { ZNotice_t notice; @@ -2591,6 +2596,7 @@ const char *cmd, char **args, char **error, void *data) { char *recipient; + PurpleCmdRet ret; PurpleConnection *gc = purple_conversation_get_connection(conv); zephyr_account *zephyr = purple_connection_get_protocol_data(gc);; if (!g_ascii_strcasecmp(args[0],"*")) @@ -2598,13 +2604,17 @@ else recipient = local_zephyr_normalize(zephyr,args[0]); - if (strlen(recipient) < 1) + if (strlen(recipient) < 1) { + g_free(recipient); return PURPLE_CMD_RET_FAILED; /* a null recipient is a chat message, not an IM */ + } if (zephyr_send_message(zephyr,"MESSAGE","PERSONAL",recipient,args[1],zephyr_get_signature(),"")) - return PURPLE_CMD_RET_OK; + ret = PURPLE_CMD_RET_OK; else - return PURPLE_CMD_RET_FAILED; + ret = PURPLE_CMD_RET_FAILED; + g_free(recipient); + return ret; } static PurpleCmdRet zephyr_purple_cmd_zlocate(PurpleConversation *conv, @@ -2808,10 +2818,12 @@ title = g_strdup_printf("Server subscriptions for %s", zephyr->username); if (zephyr->port == 0) { + g_free(title); purple_debug_error("zephyr", "error while retrieving port\n"); return; } if ((retval = ZRetrieveSubscriptions(zephyr->port,&nsubs)) != ZERR_NONE) { + g_free(title); /* XXX better error handling */ purple_debug_error("zephyr", "error while retrieving subscriptions from server\n"); return; @@ -2820,6 +2832,7 @@ one = 1; if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) { /* XXX better error handling */ + g_free(title); purple_debug_error("zephyr", "error while retrieving individual subscription\n"); return; } @@ -2828,6 +2841,8 @@ subs.zsub_recipient); } purple_notify_formatted(gc, title, title, NULL, subout->str, NULL, NULL); + g_free(title); + g_string_free(subout, TRUE); } else { /* XXX fix */ purple_notify_error(gc,"","tzc doesn't support this action",NULL);
--- a/libpurple/prpl.h Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/prpl.h Sat Feb 02 21:20:08 2013 +0100 @@ -193,7 +193,19 @@ * Indicates that this protocol supports sending a user-supplied message * along with an invitation. */ - OPT_PROTO_INVITE_MESSAGE = 0x00000800 + OPT_PROTO_INVITE_MESSAGE = 0x00000800, + + /** + * Indicates that this protocol supports sending a user-supplied message + * along with an authorization acceptance. + */ + OPT_PROTO_AUTHORIZATION_GRANTED_MESSAGE = 0x00001000, + + /** + * Indicates that this protocol supports sending a user-supplied message + * along with an authorization denial. + */ + OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE = 0x00002000 } PurpleProtocolOptions; @@ -475,7 +487,7 @@ * On the other hand, both of these are invalid for protocols with * number-based usernames, so function should return NULL in such case. * - * @param account The account, that username is related with. Can + * @param account The account the username is related to. Can * be NULL. * @param who The username to convert. * @return Normalized username, or NULL, if it's invalid.
--- a/libpurple/smiley.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/smiley.c Sat Feb 02 21:20:08 2013 +0100 @@ -272,9 +272,8 @@ smiley_node = xmlnode_get_child(smileyset_node, XML_SMILEY_TAG); for (; smiley_node != NULL; smiley_node = xmlnode_get_next_twin(smiley_node)) { - PurpleSmiley *smiley; - smiley = parse_smiley(smiley_node); + parse_smiley(smiley_node); } } @@ -608,7 +607,7 @@ return NULL; } - stored_img = purple_imgstore_add(smiley_data, smiley_data_len, filename); + stored_img = purple_imgstore_new(smiley_data, smiley_data_len, filename); g_free(filename);
--- a/libpurple/stringref.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/stringref.c Sat Feb 02 21:20:08 2013 +0100 @@ -73,7 +73,9 @@ len = strlen(value); newref = g_malloc(sizeof(PurpleStringref) + len); - g_strlcpy(newref->value, value, len); + /* g_strlcpy() takes the size of the buffer, including the NUL. + strlen() returns the length of the string, without the NUL. */ + g_strlcpy(newref->value, value, len + 1); newref->ref = 1; return newref;
--- a/libpurple/tests/check_libpurple.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/tests/check_libpurple.c Sat Feb 02 21:20:08 2013 +0100 @@ -25,11 +25,7 @@ purple_check_input_add, g_source_remove, NULL, /* input_get_error */ -#if GLIB_CHECK_VERSION(2,14,0) g_timeout_add_seconds, -#else - NULL, -#endif NULL, NULL, NULL
--- a/libpurple/upnp.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/upnp.c Sat Feb 02 21:20:08 2013 +0100 @@ -257,9 +257,12 @@ } /* get the baseURL of the device */ + baseURL = NULL; if((baseURLNode = xmlnode_get_child(xmlRootNode, "URLBase")) != NULL) { baseURL = xmlnode_get_data(baseURLNode); - } else { + } + /* fixes upnp-descriptions with empty urlbase-element */ + if(baseURL == NULL){ baseURL = g_strdup(httpURL); }
--- a/libpurple/util.c Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/util.c Sat Feb 02 21:20:08 2013 +0100 @@ -32,6 +32,8 @@ #include "prefs.h" #include "util.h" +#include <json-glib/json-glib.h> + struct _PurpleMenuAction { char *label; @@ -43,6 +45,8 @@ static char *custom_user_dir = NULL; static char *user_dir = NULL; +static JsonNode *escape_js_node = NULL; +static JsonGenerator *escape_js_gen = NULL; PurpleMenuAction * purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data, @@ -124,8 +128,8 @@ void purple_util_init(void) { - /* This does nothing right now. It exists for symmetry with - * purple_util_uninit() and forwards compatibility. */ + escape_js_node = json_node_new(JSON_NODE_VALUE); + escape_js_gen = json_generator_new(); } void @@ -138,6 +142,12 @@ g_free(user_dir); user_dir = NULL; + + json_node_free(escape_js_node); + escape_js_node = NULL; + + g_object_unref(escape_js_gen); + escape_js_gen = NULL; } /************************************************************************** @@ -2990,6 +3000,15 @@ return FALSE; } +#ifndef _WIN32 + /* Set file permissions */ + if (fchmod(fileno(file), S_IRUSR | S_IWUSR) == -1) + { + purple_debug_error("util", "Error setting permissions of %s: %s\n", + filename_temp, g_strerror(errno)); + } +#endif + /* Write to file */ real_size = (size == -1) ? strlen(data) : (size_t) size; byteswritten = fwrite(data, 1, real_size, file); @@ -3069,15 +3088,6 @@ return FALSE; } -#ifndef _WIN32 - /* Set file permissions */ - if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1) - { - purple_debug_error("util", "Error setting permissions of file %s: %s\n", - filename_temp, g_strerror(errno)); - } -#endif - /* Rename to the REAL name */ if (g_rename(filename_temp, filename_full) == -1) { @@ -3389,12 +3399,7 @@ gboolean purple_strequal(const gchar *left, const gchar *right) { -#if GLIB_CHECK_VERSION(2,16,0) return (g_strcmp0(left, right) == 0); -#else - return ((left == NULL && right == NULL) || - (left != NULL && right != NULL && strcmp(left, right) == 0)); -#endif } const char * @@ -4694,23 +4699,14 @@ gchar * purple_escape_js(const gchar *str) { - gchar *tmp, *esc; - - esc = tmp = purple_utf8_try_convert(str); - - esc = purple_strreplace(esc, "\\", "\\\\"); - g_free(tmp); tmp = esc; - - esc = purple_strreplace(esc, "'", "\\'"); - g_free(tmp); tmp = esc; - - esc = purple_strreplace(esc, "\n", "\\n"); - g_free(tmp); tmp = esc; - - esc = purple_strreplace(esc, "\r", ""); - g_free(tmp); tmp = esc; - - return esc; + gchar *escaped; + + json_node_set_string(escape_js_node, str); + json_generator_set_root(escape_js_gen, escape_js_node); + escaped = json_generator_to_data(escape_js_gen, NULL); + json_node_set_boolean(escape_js_node, FALSE); + + return escaped; } void purple_restore_default_signal_handlers(void)
--- a/libpurple/win32/global.mak Sat Feb 02 18:29:35 2013 +0100 +++ b/libpurple/win32/global.mak Sat Feb 02 21:20:08 2013 +0100 @@ -15,13 +15,15 @@ GTK_TOP ?= $(WIN32_DEV_TOP)/gtk_2_0-2.14 GTK_BIN ?= $(GTK_TOP)/bin BONJOUR_TOP ?= $(WIN32_DEV_TOP)/Bonjour_SDK -LIBXML2_TOP ?= $(WIN32_DEV_TOP)/libxml2-2.7.4 -MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa2 +LIBXML2_TOP ?= $(WIN32_DEV_TOP)/libxml2-2.9.0 +MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa3 NSS_TOP ?= $(WIN32_DEV_TOP)/nss-3.13.6-nspr-4.9.2 PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl-5.10.0 SILC_TOOLKIT ?= $(WIN32_DEV_TOP)/silc-toolkit-1.1.10 TCL_LIB_TOP ?= $(WIN32_DEV_TOP)/tcl-8.4.5 GSTREAMER_TOP ?= $(WIN32_DEV_TOP)/gstreamer-0.10.13 +GCC_SSP_TOP ?= $(WIN32_DEV_TOP)/gcc-core-4.4.0-mingw32-dll +CYRUS_SASL_TOP ?= $(WIN32_DEV_TOP)/cyrus-sasl-2.1.25 # Where we installing this stuff to? PIDGIN_INSTALL_DIR := $(PIDGIN_TREE_TOP)/win32-install-dir @@ -57,6 +59,10 @@ GCCWARNINGS ?= -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wundef +CC_HARDENING_OPTIONS ?= -Wstack-protector -fwrapv -fno-strict-overflow -Wno-missing-field-initializers -Wformat-security -fstack-protector-all --param ssp-buffer-size=1 +LD_HARDENING_OPTIONS ?= -Wl,--dynamicbase -Wl,--nxcompat + + # parse the version number from the configure.ac file if it is newer #m4_define([purple_major_version], [2]) #m4_define([purple_minor_version], [0]) @@ -84,17 +90,14 @@ DEFINES += -DHAVE_CONFIG_H -DWIN32_LEAN_AND_MEAN -# Use -g flag when building debug version of Pidgin (including plugins). -# Use -fnative-struct instead of -mms-bitfields when using mingw 1.1 -# (gcc 2.95) -CFLAGS += -O2 -Wall $(GCCWARNINGS) -pipe -mno-cygwin -mms-bitfields -g +CFLAGS += -O2 -Wall $(GCCWARNINGS) $(CC_HARDENING_OPTIONS) -pipe -mms-bitfields -g # If not specified, dlls are built with the default base address of 0x10000000. # When loaded into a process address space a dll will be rebased if its base # address colides with the base address of an existing dll. To avoid rebasing # we do the following. Rebasing can slow down the load time of dlls and it # also renders debug info useless. -DLL_LD_FLAGS += -Wl,--enable-auto-image-base +DLL_LD_FLAGS += -Wl,--enable-auto-image-base -Wl,--enable-auto-import $(LD_HARDENING_OPTIONS) -lssp # Build programs ifeq "$(origin CC)" "default" @@ -106,6 +109,8 @@ WINDRES ?= windres STRIP ?= strip INTLTOOL_MERGE ?= $(WIN32_DEV_TOP)/intltool_0.40.4-1_win32/bin/intltool-merge +MONO_SIGNCODE ?= signcode +GPG_SIGN ?= gpg PIDGIN_COMMON_RULES := $(PURPLE_TOP)/win32/rules.mak PIDGIN_COMMON_TARGETS := $(PURPLE_TOP)/win32/targets.mak
--- a/pidgin.spec.in Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin.spec.in Sat Feb 02 21:20:08 2013 +0100 @@ -368,7 +368,7 @@ %doc ChangeLog %doc NEWS %doc README -%doc README.MTN +%doc README.hg %doc doc/the_penguin.txt %doc %{_mandir}/man1/pidgin.* %doc %{_mandir}/man3*/*
--- a/pidgin/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -18,7 +18,7 @@ WINAPP := -mwindows -LDFLAGS := $(WINAPP) +LDFLAGS := $(WINAPP) $(LD_HARDENING_OPTIONS) -Wl,--enable-auto-import -lssp ## ## INCLUDE PATHS @@ -163,7 +163,7 @@ $(CC) -shared $(PIDGIN_OBJECTS) $(LIB_PATHS) $(PIDGIN_LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(PIDGIN_TARGET).def,--out-implib,$(PIDGIN_TARGET).dll.a -o $(PIDGIN_TARGET).dll $(EXE_TARGET).exe: $(PIDGIN_CONFIG_H) $(PIDGIN_DLL).a $(EXE_OBJECTS) $(PIDGIN_TARGET).dll - $(CC) $(LDFLAGS) $(EXE_OBJECTS) -o $(EXE_TARGET).exe + $(CC) $(EXE_OBJECTS) $(LDFLAGS) -o $(EXE_TARGET).exe ## ## CLEAN RULES
--- a/pidgin/gtk3compat.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtk3compat.h Sat Feb 02 21:20:08 2013 +0100 @@ -97,88 +97,6 @@ GTK_WIDGET_UNSET_FLAGS(x, GTK_REALIZED); \ } while(0) -#if !GTK_CHECK_VERSION(2,18,0) - -#define gtk_widget_get_state GTK_WIDGET_STATE -#define gtk_widget_is_drawable GTK_WIDGET_DRAWABLE -#define gtk_widget_get_visible GTK_WIDGET_VISIBLE -#define gtk_widget_has_focus GTK_WIDGET_HAS_FOCUS -#define gtk_widget_is_sensitive GTK_WIDGET_IS_SENSITIVE -#define gtk_widget_get_has_window(x) !GTK_WIDGET_NO_WINDOW(x) -#define gtk_widget_set_has_window(x,y) do { \ - if (!y) \ - GTK_WIDGET_SET_FLAGS(x, GTK_NO_WINDOW); \ - else \ - GTK_WIDGET_UNSET_FLAGS(x, GTK_NO_WINDOW); \ -} while(0) -#define gtk_widget_get_allocation(x,y) *(y) = (x)->allocation -#define gtk_widget_set_allocation(x,y) (x)->allocation = *(y) -#define gtk_widget_set_window(x,y) ((x)->window = (y)) -#define gtk_widget_set_can_default(w,y) do { \ - if (y) \ - GTK_WIDGET_SET_FLAGS((w), GTK_CAN_DEFAULT); \ - else \ - GTK_WIDGET_UNSET_FLAGS((w), GTK_CAN_DEFAULT); \ -} while (0) -#define gtk_widget_set_can_focus(x,y) do {\ - if (y) \ - GTK_WIDGET_SET_FLAGS(x, GTK_CAN_FOCUS); \ - else \ - GTK_WIDGET_UNSET_FLAGS(x, GTK_CAN_FOCUS); \ -} while(0) -#define gtk_cell_renderer_set_padding(x,y,z) do { \ - (x)->xpad = (y); \ - (x)->ypad = (z); \ -} while (0) -#define gtk_cell_renderer_get_padding(x,y,z) do { \ - *(y) = (x)->xpad; \ - *(z) = (x)->ypad; \ -} while (0) -#define gtk_cell_renderer_get_alignment(x,y,z) do { \ - *(y) = (x)->xalign; \ - *(z) = (x)->yalign; \ -} while (0) - -#if !GTK_CHECK_VERSION(2,16,0) - -#define gtk_status_icon_set_tooltip_text gtk_status_icon_set_tooltip - -#if !GTK_CHECK_VERSION(2,14,0) - -#define gtk_widget_get_window(x) (x)->window -#define gtk_widget_set_style(x,y) (x)->style = (y) -#define gtk_selection_data_get_data(x) (x)->data -#define gtk_selection_data_get_length(x) (x)->length -#define gtk_selection_data_get_format(x) (x)->format -#define gtk_selection_data_get_target(x) (x)->target -#define gtk_dialog_get_content_area(x) GTK_DIALOG(x)->vbox -#define gtk_dialog_get_action_area(x) GTK_DIALOG(x)->action_area -#define gtk_adjustment_get_page_size(x) (x)->page_size -#define gtk_adjustment_get_lower(x) (x)->lower -#define gtk_adjustment_get_upper(x) (x)->upper -#define gtk_font_selection_get_size_entry(x) (x)->size_entry -#define gtk_font_selection_get_family_list(x) (x)->family_list -#define gtk_font_selection_dialog_get_ok_button(x) (x)->ok_button -#define gtk_font_selection_dialog_get_cancel_button(x) (x)->cancel_button -#define gtk_color_selection_dialog_get_color_selection(x) (x)->colorsel -#define gtk_menu_item_get_accel_path(x) (x)->accel_path - -#if !GTK_CHECK_VERSION(2,12,0) - -#ifdef GTK_TOOLTIPS_VAR -#define gtk_widget_set_tooltip_text(w, t) gtk_tooltips_set_tip(GTK_TOOLTIPS_VAR, (w), (t), NULL) -#else -#define gtk_widget_set_tooltip_text(w, t) gtk_tooltips_set_tip(tooltips, (w), (t), NULL) -#endif - -#endif /* 2.12.0 */ - -#endif /* 2.14.0 */ - -#endif /* 2.16.0 */ - -#endif /* 2.18.0 */ - #endif /* 2.20.0 */ #endif /* 2.22.0 */
--- a/pidgin/gtkaccount.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkaccount.c Sat Feb 02 21:20:08 2013 +0100 @@ -119,6 +119,11 @@ GtkWidget *protocol_menu; GtkWidget *password_box; GtkWidget *username_entry; +#if GTK_CHECK_VERSION(3,0,0) + GdkRGBA username_entry_hint_color; +#else + GdkColor *username_entry_hint_color; +#endif GtkWidget *password_entry; GtkWidget *alias_entry; GtkWidget *remember_pass_check; @@ -184,7 +189,7 @@ if (data != NULL) { if (len > 0) - dialog->icon_img = purple_imgstore_add(data, len, new_icon_path); + dialog->icon_img = purple_imgstore_new(data, len, new_icon_path); else g_free(data); } @@ -266,30 +271,6 @@ } } -static gboolean -username_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) -{ - GHashTable *table; - const char *label; - - if (!dialog->prpl_info || ! PURPLE_PROTOCOL_PLUGIN_HAS_FUNC( - dialog->prpl_info, get_account_text_table)) { - return FALSE; - } - - table = dialog->prpl_info->get_account_text_table(NULL); - label = g_hash_table_lookup(table, "login_label"); - - if(!strcmp(gtk_entry_get_text(GTK_ENTRY(widget)), label)) { - gtk_entry_set_text(GTK_ENTRY(widget), ""); - gtk_widget_modify_text(widget, GTK_STATE_NORMAL,NULL); - } - - g_hash_table_destroy(table); - - return FALSE; -} - static void username_changed_cb(GtkEntry *entry, AccountPrefsDialog *dialog) { @@ -317,10 +298,38 @@ } } +#if !GTK_CHECK_VERSION(3,2,0) +static gboolean +username_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) +{ + GHashTable *table; + const char *label; + + if (!dialog->prpl_info || ! PURPLE_PROTOCOL_PLUGIN_HAS_FUNC( + dialog->prpl_info, get_account_text_table)) { + return FALSE; + } + + table = dialog->prpl_info->get_account_text_table(NULL); + label = g_hash_table_lookup(table, "login_label"); + + if(!strcmp(gtk_entry_get_text(GTK_ENTRY(widget)), label)) { + gtk_entry_set_text(GTK_ENTRY(widget), ""); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_color(widget, GTK_STATE_NORMAL, NULL); +#else + gtk_widget_modify_text(widget, GTK_STATE_NORMAL,NULL); +#endif + } + + g_hash_table_destroy(table); + + return FALSE; +} + static gboolean username_nofocus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) { - GdkColor color = {0, 34952, 35466, 34181}; GHashTable *table = NULL; const char *label = NULL; @@ -336,7 +345,11 @@ gtk_entry_set_text(GTK_ENTRY(widget), label); /* Make sure we can hit it again */ g_signal_handlers_unblock_by_func(widget, G_CALLBACK(username_changed_cb), dialog); - gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &color); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_color(widget, GTK_STATE_NORMAL, &dialog->username_entry_hint_color); +#else + gtk_widget_modify_text(widget, GTK_STATE_NORMAL, dialog->username_entry_hint_color); +#endif } g_hash_table_destroy(table); @@ -345,6 +358,84 @@ return FALSE; } +static gboolean +username_themechange_cb(GObject *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) +{ + GHashTable *table; + const char *label, *text; + char *temp_text = NULL; +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context; + GtkBorder border; +#else + GtkStyle *style; + const GtkBorder *border = NULL; +#endif + gint xsize; + + table = dialog->prpl_info->get_account_text_table(NULL); + label = g_hash_table_lookup(table, "login_label"); + text = gtk_entry_get_text(GTK_ENTRY(widget)); + + g_signal_handlers_block_by_func(widget, G_CALLBACK(username_themechange_cb), dialog); + g_signal_handlers_block_by_func(widget, G_CALLBACK(username_changed_cb), dialog); + if (strcmp(text, label)) { + temp_text = g_strdup(text); + gtk_entry_set_text(GTK_ENTRY(widget), label); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_color(GTK_WIDGET(widget), GTK_STATE_NORMAL, NULL); +#else + gtk_widget_modify_text(GTK_WIDGET(widget), GTK_STATE_NORMAL, NULL); +#endif + } + +#if GTK_CHECK_VERSION(3,0,0) + context = gtk_widget_get_style_context(dialog->username_entry); + gtk_style_context_get_color(context, GTK_STATE_FLAG_INSENSITIVE, + &dialog->username_entry_hint_color); +#else + style = gtk_rc_get_style(dialog->username_entry); + dialog->username_entry_hint_color = &(style->fg[GTK_STATE_INSENSITIVE]); +#endif + + pango_layout_get_pixel_size(gtk_entry_get_layout(GTK_ENTRY(widget)), &xsize, NULL); +#if GTK_CHECK_VERSION(3,0,0) + gtk_style_context_get_margin(context, GTK_STATE_FLAG_NORMAL, &border); + xsize += border.left + border.right; + gtk_style_context_get_padding(context, GTK_STATE_FLAG_NORMAL, &border); + xsize += border.left + border.right; +#else + xsize += 2 * style->xthickness; + gtk_style_get(style, GTK_TYPE_ENTRY, "inner-border", &border, NULL); + if (border) + xsize += border->left + border->right; + else + xsize += 4; /* 2 * default inner-border */ +#endif + gtk_widget_set_size_request(GTK_WIDGET(widget), xsize, -1); + if (temp_text) { + gtk_entry_set_text(GTK_ENTRY(widget), temp_text); + g_free(temp_text); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_color(GTK_WIDGET(widget), GTK_STATE_NORMAL, NULL); +#else + gtk_widget_modify_text(GTK_WIDGET(widget), GTK_STATE_NORMAL, NULL); +#endif + } else +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_color(GTK_WIDGET(widget), GTK_STATE_NORMAL, &dialog->username_entry_hint_color); +#else + gtk_widget_modify_text(GTK_WIDGET(widget), GTK_STATE_NORMAL, dialog->username_entry_hint_color); +#endif + + g_signal_handlers_unblock_by_func(widget, G_CALLBACK(username_themechange_cb), dialog); + g_signal_handlers_unblock_by_func(widget, G_CALLBACK(username_changed_cb), dialog); + g_hash_table_destroy(table); + + return FALSE; +} +#endif + static void register_button_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog) { @@ -354,8 +445,10 @@ (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME)); int register_noscreenname = (opt_noscreenname && register_checked); +#if !GTK_CHECK_VERSION(3,2,0) /* get rid of login_label in username field */ username_focus_cb(dialog->username_entry, NULL, dialog); +#endif if (register_noscreenname) { gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), ""); @@ -373,7 +466,9 @@ != '\0'); } +#if !GTK_CHECK_VERSION(3,2,0) username_nofocus_cb(dialog->username_entry, NULL, dialog); +#endif } static void @@ -531,18 +626,24 @@ if (!username && dialog->prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(dialog->prpl_info, get_account_text_table)) { - GdkColor color = {0, 34952, 35466, 34181}; GHashTable *table; const char *label; table = dialog->prpl_info->get_account_text_table(NULL); label = g_hash_table_lookup(table, "login_label"); +#if GTK_CHECK_VERSION(3,2,0) + gtk_entry_set_placeholder_text(GTK_ENTRY(dialog->username_entry), label); +#else gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), label); + username_themechange_cb(G_OBJECT(dialog->username_entry), NULL, dialog); + g_signal_connect(G_OBJECT(dialog->username_entry), "style-set", + G_CALLBACK(username_themechange_cb), dialog); g_signal_connect(G_OBJECT(dialog->username_entry), "focus-in-event", G_CALLBACK(username_focus_cb), dialog); g_signal_connect(G_OBJECT(dialog->username_entry), "focus-out-event", G_CALLBACK(username_nofocus_cb), dialog); - gtk_widget_modify_text(dialog->username_entry, GTK_STATE_NORMAL, &color); +#endif + g_hash_table_destroy(table); } @@ -617,10 +718,6 @@ /* Password */ dialog->password_entry = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(dialog->password_entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(dialog->password_entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(dialog->password_entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ dialog->password_box = add_pref_box(dialog, vbox, _("_Password:"), dialog->password_entry); @@ -935,10 +1032,6 @@ else if (purple_account_option_string_get_masked(option)) { gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ } if (str_value != NULL && str_hints) @@ -1176,10 +1269,6 @@ /* Password */ dialog->proxy_pass_entry = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(dialog->proxy_pass_entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(dialog->proxy_pass_entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(dialog->proxy_pass_entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ add_pref_box(dialog, vbox2, _("Pa_ssword:"), dialog->proxy_pass_entry); if (dialog->account != NULL && @@ -2583,18 +2672,93 @@ } static void -authorize_and_add_cb(struct auth_request *ar) +authorize_and_add_cb(struct auth_request *ar, const char *message) { - ar->auth_cb(ar->data); + ar->auth_cb(message, ar->data); if (ar->add_buddy_after_auth) { purple_blist_request_add_buddy(ar->account, ar->username, NULL, ar->alias); } } static void -deny_no_add_cb(struct auth_request *ar) +authorize_noreason_cb(struct auth_request *ar) +{ + authorize_and_add_cb(ar, NULL); +} + +static void +authorize_reason_cb(struct auth_request *ar) { - ar->deny_cb(ar->data); + const char *protocol_id; + PurplePlugin *plugin; + PurplePluginProtocolInfo *prpl_info = NULL; + + protocol_id = purple_account_get_protocol_id(ar->account); + if ((plugin = purple_find_prpl(protocol_id)) != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); + + if (prpl_info && (prpl_info->options & OPT_PROTO_AUTHORIZATION_GRANTED_MESSAGE)) { + /* Duplicate information because ar is freed by closing minidialog */ + struct auth_request *aa = g_new0(struct auth_request, 1); + aa->auth_cb = ar->auth_cb; + aa->deny_cb = ar->deny_cb; + aa->data = ar->data; + aa->account = ar->account; + aa->username = g_strdup(ar->username); + aa->alias = g_strdup(ar->alias); + aa->add_buddy_after_auth = ar->add_buddy_after_auth; + purple_request_input(ar->account, NULL, _("Authorization acceptance message:"), + NULL, _("No reason given."), TRUE, FALSE, NULL, + _("OK"), G_CALLBACK(authorize_and_add_cb), + _("Cancel"), G_CALLBACK(authorize_noreason_cb), + ar->account, ar->username, NULL, + aa); + /* FIXME: aa is going to leak now. */ + } else { + authorize_noreason_cb(ar); + } +} + +static void +deny_no_add_cb(struct auth_request *ar, const char *message) +{ + ar->deny_cb(message, ar->data); +} + +static void +deny_noreason_cb(struct auth_request *ar) +{ + ar->deny_cb(NULL, ar->data); +} + +static void +deny_reason_cb(struct auth_request *ar) +{ + const char *protocol_id; + PurplePlugin *plugin; + PurplePluginProtocolInfo *prpl_info = NULL; + + protocol_id = purple_account_get_protocol_id(ar->account); + if ((plugin = purple_find_prpl(protocol_id)) != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); + + if (prpl_info && (prpl_info->options & OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE)) { + /* Duplicate information because ar is freed by closing minidialog */ + struct auth_request *aa = g_new0(struct auth_request, 1); + aa->auth_cb = ar->auth_cb; + aa->deny_cb = ar->deny_cb; + aa->data = ar->data; + aa->add_buddy_after_auth = ar->add_buddy_after_auth; + purple_request_input(ar->account, NULL, _("Authorization denied message:"), + NULL, _("No reason given."), TRUE, FALSE, NULL, + _("OK"), G_CALLBACK(deny_no_add_cb), + _("Cancel"), G_CALLBACK(deny_noreason_cb), + ar->account, ar->username, NULL, + aa); + /* FIXME: aa is going to leak now. */ + } else { + deny_noreason_cb(ar); + } } static gboolean @@ -2637,43 +2801,41 @@ GdkPixbuf *prpl_icon; struct auth_request *aa; const char *our_name; - gboolean have_valid_alias = alias && *alias; + gboolean have_valid_alias; + char *escaped_remote_user; + char *escaped_alias; + char *escaped_our_name; + char *escaped_message; gc = purple_account_get_connection(account); - if (message != NULL && *message == '\0') - message = NULL; + if (message != NULL && *message != '\0') + escaped_message = g_markup_escape_text(message, -1); + else + escaped_message = g_strdup(""); our_name = (id != NULL) ? id : (purple_connection_get_display_name(gc) != NULL) ? purple_connection_get_display_name(gc) : purple_account_get_username(account); - - if (pidgin_mini_dialog_links_supported()) { - char *escaped_remote_user = g_markup_escape_text(remote_user, -1); - char *escaped_alias = alias != NULL ? g_markup_escape_text(alias, -1) : g_strdup(""); - char *escaped_our_name = g_markup_escape_text(our_name, -1); - char *escaped_message = message != NULL ? g_markup_escape_text(message, -1) : g_strdup(""); - buffer = g_strdup_printf(_("<a href=\"viewinfo\">%s</a>%s%s%s wants to add you (%s) to his or her buddy list%s%s"), - escaped_remote_user, - (have_valid_alias ? " (" : ""), - escaped_alias, - (have_valid_alias ? ")" : ""), - escaped_our_name, - (have_valid_alias ? ": " : "."), - escaped_message); - g_free(escaped_remote_user); - g_free(escaped_alias); - g_free(escaped_our_name); - g_free(escaped_message); - } else { - buffer = g_strdup_printf(_("%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"), - remote_user, - (have_valid_alias ? " (" : ""), - (have_valid_alias ? alias : ""), - (have_valid_alias ? ")" : ""), - our_name, - (message != NULL ? ": " : "."), - (message != NULL ? message : "")); - } + escaped_our_name = g_markup_escape_text(our_name, -1); + + escaped_remote_user = g_markup_escape_text(remote_user, -1); + + have_valid_alias = alias && *alias; + escaped_alias = have_valid_alias ? g_markup_escape_text(alias, -1) : g_strdup(""); + + buffer = g_strdup_printf(_("<a href=\"viewinfo\">%s</a>%s%s%s wants to add you (%s) to his or her buddy list%s%s"), + escaped_remote_user, + (have_valid_alias ? " (" : ""), + escaped_alias, + (have_valid_alias ? ")" : ""), + escaped_our_name, + (have_valid_alias ? ": " : "."), + escaped_message); + + g_free(escaped_remote_user); + g_free(escaped_alias); + g_free(escaped_our_name); + g_free(escaped_message); prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); @@ -2689,15 +2851,13 @@ alert = pidgin_make_mini_dialog_with_custom_icon( gc, prpl_icon, _("Authorize buddy?"), NULL, aa, - _("Authorize"), authorize_and_add_cb, - _("Deny"), deny_no_add_cb, + _("Authorize"), authorize_reason_cb, + _("Deny"), deny_reason_cb, NULL); dialog = PIDGIN_MINI_DIALOG(alert); - if (pidgin_mini_dialog_links_supported()) { - pidgin_mini_dialog_enable_description_markup(dialog); - pidgin_mini_dialog_set_link_callback(dialog, G_CALLBACK(get_user_info_cb), aa); - } + pidgin_mini_dialog_enable_description_markup(dialog); + pidgin_mini_dialog_set_link_callback(dialog, G_CALLBACK(get_user_info_cb), aa); pidgin_mini_dialog_set_description(dialog, buffer); pidgin_mini_dialog_add_non_closing_button(dialog, _("Send Instant Message"), send_im_cb, aa);
--- a/pidgin/gtkblist.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkblist.c Sat Feb 02 21:20:08 2013 +0100 @@ -1110,10 +1110,6 @@ if (pce->secret) { gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(input)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(input), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ } pidgin_add_widget_to_vbox(data->rq_data.vbox, pce->label, data->rq_data.sg, input, TRUE, NULL); g_signal_connect(G_OBJECT(input), "changed", @@ -5473,6 +5469,7 @@ GtkWidget *hbox, *label; const char *username = purple_account_get_username(account); char *markup; + char *description; hbox = gtk_hbox_new(FALSE, 6); g_object_set_data(G_OBJECT(hbox), OBJECT_DATA_KEY_ACCOUNT, account); @@ -5485,14 +5482,9 @@ g_free(markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); g_object_set(G_OBJECT(label), "ellipsize", PANGO_ELLIPSIZE_END, NULL); -#if GTK_CHECK_VERSION(2,12,0) - { /* avoid unused variable warnings on pre-2.12 Gtk */ - char *description = - purple_account_get_current_error(account)->description; - if (description != NULL && *description != '\0') - gtk_widget_set_tooltip_text(label, description); - } -#endif + description = purple_account_get_current_error(account)->description; + if (description != NULL && *description != '\0') + gtk_widget_set_tooltip_text(label, description); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); return hbox; @@ -5536,12 +5528,10 @@ update_signed_on_elsewhere_tooltip(PurpleAccount *account, const char *description) { -#if GTK_CHECK_VERSION(2,12,0) PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); GtkContainer *c = GTK_CONTAINER(priv->signed_on_elsewhere->contents); GtkWidget *label = find_child_widget_by_account(c, account); gtk_widget_set_tooltip_text(label, description); -#endif } @@ -5667,7 +5657,6 @@ { PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); GtkStyle *style; -#if GTK_CHECK_VERSION(2,12,0) GtkWidget *window; if (priv->changing_style) @@ -5686,25 +5675,6 @@ gtk_widget_destroy(window); gtk_widget_queue_draw(gtkblist->headline); -#else - GtkTooltips *tooltips; - - if (gtkblist->changing_style) - return; - - tooltips = gtk_tooltips_new (); - g_object_ref_sink (tooltips); - - gtk_tooltips_force_window (tooltips); - gtk_widget_ensure_style (tooltips->tip_window); - style = gtk_widget_get_style (tooltips->tip_window); - - priv->changing_style = TRUE; - gtk_widget_set_style (gtkblist->headline, style); - priv->changing_style = FALSE; - - g_object_unref (tooltips); -#endif } #endif @@ -6141,9 +6111,7 @@ close = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); close = pidgin_create_small_button(close); gtk_box_pack_start(GTK_BOX(gtkblist->headline), close, FALSE, FALSE, 0); -#if GTK_CHECK_VERSION(2,12,0) gtk_widget_set_tooltip_text(close, _("Close")); -#endif g_signal_connect(close, "clicked", G_CALLBACK(headline_close_press_cb), gtkblist); g_signal_connect(G_OBJECT(ebox), "enter-notify-event", G_CALLBACK(headline_box_enter_cb), priv); @@ -7811,10 +7779,6 @@ purple_prefs_add_int(PIDGIN_PREFS_ROOT "/blist/y", 0); purple_prefs_add_int(PIDGIN_PREFS_ROOT "/blist/width", 250); /* Golden ratio, baby */ purple_prefs_add_int(PIDGIN_PREFS_ROOT "/blist/height", 405); /* Golden ratio, baby */ -#if !GTK_CHECK_VERSION(2,14,0) - /* This pref is used in pidgintooltip.c. */ - purple_prefs_add_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay", 500); -#endif purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/theme", ""); purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_BLIST_THEME_LOADER, "type", "blist", NULL));
--- a/pidgin/gtkcellrendererexpander.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkcellrendererexpander.c Sat Feb 02 21:20:08 2013 +0100 @@ -29,7 +29,6 @@ * Jonathon Blandford <jrb@redhat.com> for RedHat, Inc. */ -#include <gtk/gtk.h> #include "gtkcellrendererexpander.h" #include "gtk3compat.h"
--- a/pidgin/gtkconv-theme.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkconv-theme.c Sat Feb 02 21:20:08 2013 +0100 @@ -500,7 +500,8 @@ } g_free(priv->variant); - g_array_unref(priv->nick_colors); + if (priv->nick_colors) + g_array_unref(priv->nick_colors); parent_class->finalize(obj); }
--- a/pidgin/gtkconv.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkconv.c Sat Feb 02 21:20:08 2013 +0100 @@ -1005,7 +1005,7 @@ /* Now the Buddy drop-down entry field. */ info->entry = gtk_entry_new(); - pidgin_setup_screenname_autocomplete_with_filter(info->entry, NULL, chat_invite_filter, + pidgin_setup_screenname_autocomplete(info->entry, NULL, chat_invite_filter, purple_conversation_get_account(conv)); gtk_table_attach_defaults(GTK_TABLE(table), info->entry, 1, 2, 0, 1); gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->entry); @@ -3315,15 +3315,10 @@ return FALSE; buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); - - /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle - * removing "isolated" buddy nodes well */ - if (purple_version_check(2, 0, 2) == NULL) { - if ((buddy == NULL) && (gtkconv->webview != NULL)) { - buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); - } - - if ((buddy == NULL) && (gtkconv->webview != NULL)) { + if (!buddy && gtkconv->webview) { + buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); + + if (!buddy) { buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL); purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); @@ -5776,9 +5771,6 @@ gtkconv->send_history = g_list_append(NULL, NULL); /* Setup some initial variables. */ -#if !GTK_CHECK_VERSION(2,12,0) - gtkconv->tooltips = gtk_tooltips_new(); -#endif gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; gtkconv->unseen_count = 0; theme_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"); @@ -5997,10 +5989,6 @@ g_free(gtkconv->u.chat); } -#if !GTK_CHECK_VERSION(2,12,0) - gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); -#endif - gtkconv->send_history = g_list_first(gtkconv->send_history); g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL); g_list_free(gtkconv->send_history); @@ -6726,6 +6714,47 @@ } #endif + + /* on rejoin only request message history from after this message */ + if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV) && + purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + PurpleChat *chat = purple_blist_find_chat( + purple_conversation_get_account(conv), + purple_conversation_get_name(conv)); + if (chat) { + GHashTable *comps = purple_chat_get_components(chat); + time_t now, history_since, prev_history_since = 0; + struct tm *history_since_tm; + const char *history_since_s, *prev_history_since_s; + + history_since = mtime + 1; + + prev_history_since_s = g_hash_table_lookup(comps, + "history_since"); + if (prev_history_since_s != NULL) + prev_history_since = purple_str_to_time( + prev_history_since_s, TRUE, NULL, NULL, + NULL); + + now = time(NULL); + /* in case of incorrectly stored timestamps */ + if (prev_history_since > now) + prev_history_since = now; + /* in case of delayed messages */ + if (history_since < prev_history_since) + history_since = prev_history_since; + + history_since_tm = gmtime(&history_since); + history_since_s = purple_utf8_strftime( + "%Y-%m-%dT%H:%M:%SZ", history_since_tm); + if (g_strcmp0(prev_history_since_s, + history_since_s) != 0) + g_hash_table_replace(comps, + g_strdup("history_since"), + g_strdup(history_since_s)); + } + } + purple_signal_emit(pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), account, name, displaying, conv, flags); @@ -8207,7 +8236,7 @@ purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " "longer in this chat. You will automatically rejoin the chat when " "the account reconnects."), - PURPLE_MESSAGE_SYSTEM, time(NULL)); + PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL)); } list = list->next; } @@ -10226,7 +10255,7 @@ gtk_css_provider_load_from_data(provider, str->str, str->len, &error); gtk_style_context_add_provider(gtk_widget_get_style_context(widget), - provider, + GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); if (error)
--- a/pidgin/gtkconv.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkconv.h Sat Feb 02 21:20:08 2013 +0100 @@ -90,11 +90,7 @@ gboolean make_sound; -#if GTK_CHECK_VERSION(2,12,0) gpointer depr2; -#else - GtkTooltips *tooltips; -#endif GtkWidget *tab_cont; GtkWidget *tabby;
--- a/pidgin/gtkdebug.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkdebug.c Sat Feb 02 21:20:08 2013 +0100 @@ -109,7 +109,8 @@ text = gtk_entry_get_text(GTK_ENTRY(debug_win->expression)); purple_prefs_set_string(PIDGIN_PREFS_ROOT "/debug/regex", text); } - g_regex_unref(debug_win->regex); + if (debug_win->regex != NULL) + g_regex_unref(debug_win->regex); /* If the "Save Log" dialog is open then close it */ purple_request_close_with_handle(debug_win); @@ -699,9 +700,6 @@ gint width, height; void *handle; GtkToolItem *item; -#if !GTK_CHECK_VERSION(2,12,0) - GtkTooltips *tooltips; -#endif win = g_new0(DebugWindow, 1); @@ -728,12 +726,6 @@ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/toolbar")) { /* Setup our top button bar thingie. */ toolbar = gtk_toolbar_new(); -#if !GTK_CHECK_VERSION(2,12,0) - tooltips = gtk_tooltips_new(); -#endif -#if !GTK_CHECK_VERSION(2,14,0) - gtk_toolbar_set_tooltips(GTK_TOOLBAR(toolbar), TRUE); -#endif gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), TRUE); g_signal_connect(G_OBJECT(toolbar), "button-press-event", G_CALLBACK(toolbar_context), win); @@ -1046,7 +1038,7 @@ esc_s = purple_escape_js(arg_s); - js = g_strdup_printf("append(%d, '%s', '%s', '%s');", + js = g_strdup_printf("append(%d, '%s', '%s', %s);", level, mdate, category ? category : "", esc_s); g_free(esc_s);
--- a/pidgin/gtkdialogs.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkdialogs.c Sat Feb 02 21:20:08 2013 +0100 @@ -220,7 +220,7 @@ {N_("Malay"), "ms_MY", "Muhammad Najmi bin Ahmad Zabidi", "najmi.zabidi@gmail.com"}, {N_("Burmese"), "my_MM", "Thura Hlaing", "trhura@gmail.com"}, {N_("Bokmål Norwegian"), "nb", "Hans Fredrik Nordhaug", "hans@nordhaug.priv.no"}, - {N_("Nepali"), "ne", "Shyam Krishna Bal", "shyamkrishna_bal@yahoo.com"}, + {N_("Nepali"), "ne", "Shyam Krishna Bal", NULL}, {N_("Dutch, Flemish"), "nl", "Gideon van Melle", "translations@gvmelle.com"}, {N_("Norwegian Nynorsk"), "nn", "Yngve Spjeld Landro", "l10n@landro.net"}, {N_("Occitan"), "oc", "Yannig Marchegay", "yannig@marchegay.org"},
--- a/pidgin/gtkdnd-hints.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkdnd-hints.c Sat Feb 02 21:20:08 2013 +0100 @@ -26,7 +26,6 @@ #include "gtkdnd-hints.h" -#include <gtk/gtk.h> #include <gdk/gdk.h> #include <gdk-pixbuf/gdk-pixbuf.h>
--- a/pidgin/gtkdocklet.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkdocklet.c Sat Feb 02 21:20:08 2013 +0100 @@ -847,38 +847,20 @@ static gboolean docklet_gtk_embed_timeout_cb(gpointer data) { -#if !GTK_CHECK_VERSION(2,12,0) - if (gtk_status_icon_is_embedded(docklet)) { - /* Older GTK+ (<2.12) don't implement the embedded signal, but the - information is still accessible through the above function. */ - purple_debug_info("docklet", "embedded\n"); + /* The docklet was not embedded within the timeout. + * Remove it as a visibility manager, but leave the plugin + * loaded so that it can embed automatically if/when a notification + * area becomes available. + */ + purple_debug_info("docklet", "failed to embed within timeout\n"); + pidgin_docklet_remove(); + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); - pidgin_docklet_embedded(); - purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", TRUE); - } - else -#endif - { - /* The docklet was not embedded within the timeout. - * Remove it as a visibility manager, but leave the plugin - * loaded so that it can embed automatically if/when a notification - * area becomes available. - */ - purple_debug_info("docklet", "failed to embed within timeout\n"); - pidgin_docklet_remove(); - purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded", FALSE); - } - -#if GTK_CHECK_VERSION(2,12,0) embed_timeout = 0; return FALSE; -#else - return TRUE; -#endif } #endif -#if GTK_CHECK_VERSION(2,12,0) static gboolean docklet_gtk_embedded_cb(GtkWidget *widget, gpointer data) { @@ -901,7 +883,6 @@ return TRUE; } -#endif static void docklet_gtk_status_activated_cb(GtkStatusIcon *status_icon, gpointer user_data) @@ -956,9 +937,7 @@ g_signal_connect(G_OBJECT(docklet), "activate", G_CALLBACK(docklet_gtk_status_activated_cb), NULL); g_signal_connect(G_OBJECT(docklet), "popup-menu", G_CALLBACK(docklet_gtk_status_clicked_cb), NULL); -#if GTK_CHECK_VERSION(2,12,0) g_signal_connect(G_OBJECT(docklet), "notify::embedded", G_CALLBACK(docklet_gtk_embedded_cb), NULL); -#endif gtk_status_icon_set_visible(docklet, TRUE); @@ -978,15 +957,11 @@ if (!recreate) { pidgin_docklet_embedded(); #ifndef _WIN32 -#if GTK_CHECK_VERSION(2,12,0) if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/gtk/embedded")) { embed_timeout = purple_timeout_add_seconds(LONG_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); } else { embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); } -#else - embed_timeout = purple_timeout_add_seconds(SHORT_EMBED_TIMEOUT, docklet_gtk_embed_timeout_cb, NULL); -#endif #endif }
--- a/pidgin/gtkeventloop.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkeventloop.c Sat Feb 02 21:20:08 2013 +0100 @@ -124,11 +124,7 @@ pidgin_input_add, g_source_remove, NULL, /* input_get_error */ -#if GLIB_CHECK_VERSION(2,14,0) g_timeout_add_seconds, -#else - NULL, -#endif NULL, NULL, NULL
--- a/pidgin/gtkimhtml.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkimhtml.c Sat Feb 02 21:20:08 2013 +0100 @@ -1758,7 +1758,7 @@ gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); gtk_text_buffer_create_tag(imhtml->text_buffer, "search", "background", "#22ff00", "weight", "bold", NULL); gtk_text_buffer_create_tag(imhtml->text_buffer, "comment", "weight", PANGO_WEIGHT_NORMAL, -#if FALSE && GTK_CHECK_VERSION(2,10,10) +#if FALSE "invisible", FALSE, #endif NULL); @@ -2523,7 +2523,7 @@ [19:58] <Robot101> marv: images go into the imgstore, a refcounted... well.. hash. :) [19:59] <KingAnt> marv: I think the image tag used by the core is something like <img id="#"/> [19:59] Ro0tSiEgE robert42 RobFlynn Robot101 ross22 roz -[20:00] <KingAnt> marv: Where the ID is the what is returned when you add the image to the imgstore using purple_imgstore_add +[20:00] <KingAnt> marv: Where the ID is the what is returned when you add the image to the imgstore using purple_imgstore_new [20:00] <marv> Robot101: so how does the image get passed to serv_got_im() and serv_send_im()? just as the <img id="#" and then the prpl looks it up from the store? [20:00] <KingAnt> marv: Right [20:00] <marv> alright @@ -3398,7 +3398,7 @@ gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); -#if FALSE && GTK_CHECK_VERSION(2,10,10) +#if FALSE wpos = g_snprintf (ws, len, "%s", tag); gtk_text_buffer_insert_with_tags_by_name(imhtml->text_buffer, iter, ws, wpos, "comment", NULL); #else @@ -3576,7 +3576,7 @@ void gtk_imhtml_show_comments (GtkIMHtml *imhtml, gboolean show) { -#if FALSE && GTK_CHECK_VERSION(2,10,10) +#if FALSE GtkTextTag *tag; tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), "comment"); if (tag) @@ -3963,8 +3963,7 @@ gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(image->image)); - if(!gtk_check_version(2, 4, 0)) - g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); + g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); gtk_widget_show(GTK_WIDGET(image->image)); gtk_widget_show(box); @@ -5268,8 +5267,10 @@ g_free(name); if (tmp) { - g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); + gchar *escaped = purple_markup_escape_text(tmp, -1); + g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", escaped); buf[sizeof(buf)-1] = '\0'; + g_free(escaped); return buf; } else { return "";
--- a/pidgin/gtkimhtmltoolbar.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkimhtmltoolbar.c Sat Feb 02 21:20:08 2013 +0100 @@ -529,7 +529,7 @@ name = strrchr(filename, G_DIR_SEPARATOR) + 1; - id = purple_imgstore_add_with_id(filedata, size, name); + id = purple_imgstore_new_with_id(filedata, size, name); if (id == 0) { buf = g_strdup_printf(_("Failed to store image: %s\n"), filename); @@ -1177,9 +1177,6 @@ } g_free(toolbar->sml); -#if !GTK_CHECK_VERSION(2,12,0) - gtk_object_sink(GTK_OBJECT(toolbar->tooltips)); -#endif menu = g_object_get_data(object, "font_menu"); if (menu) @@ -1377,10 +1374,6 @@ toolbar->smiley_dialog = NULL; toolbar->image_dialog = NULL; -#if !GTK_CHECK_VERSION(2,12,0) - toolbar->tooltips = gtk_tooltips_new(); -#endif - gtk_box_set_spacing(GTK_BOX(toolbar), 3); gtk_imhtmltoolbar_create_old_buttons(toolbar);
--- a/pidgin/gtkimhtmltoolbar.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkimhtmltoolbar.h Sat Feb 02 21:20:08 2013 +0100 @@ -44,11 +44,7 @@ GtkWidget *imhtml; -#if GTK_CHECK_VERSION(2,12,0) gpointer depr1; -#else - GtkTooltips *tooltips; -#endif GtkWidget *bold; GtkWidget *italic;
--- a/pidgin/gtkmain.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkmain.c Sat Feb 02 21:20:08 2013 +0100 @@ -413,8 +413,8 @@ /* FUCKING GET ME A TOWEL! */ #ifdef _WIN32 /* suppress gcc "no previous prototype" warning */ -int pidgin_main(HINSTANCE hint, int argc, char *argv[]); -int pidgin_main(HINSTANCE hint, int argc, char *argv[]) +int __cdecl pidgin_main(HINSTANCE hint, int argc, char *argv[]); +int __cdecl pidgin_main(HINSTANCE hint, int argc, char *argv[]) #else int main(int argc, char *argv[]) #endif @@ -754,16 +754,9 @@ return 0; } - /* TODO: Move blist loading into purple_blist_init() */ - purple_set_blist(purple_blist_new()); - purple_blist_load(); - /* load plugins we had when we quit */ purple_plugins_load_saved(PIDGIN_PREFS_ROOT "/plugins/loaded"); - /* TODO: Move pounces loading into purple_pounces_init() */ - purple_pounces_load(); - ui_main(); #ifdef USE_SM
--- a/pidgin/gtkmedia.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkmedia.c Sat Feb 02 21:20:08 2013 +0100 @@ -666,30 +666,18 @@ } static void -#if GTK_CHECK_VERSION(2,12,0) pidgin_media_input_volume_changed(GtkScaleButton *range, double value, PurpleMedia *media) { double val = (double)value * 100.0; -#else -pidgin_media_input_volume_changed(GtkRange *range, PurpleMedia *media) -{ - double val = (double)gtk_range_get_value(GTK_RANGE(range)); -#endif purple_media_set_input_volume(media, NULL, val); } static void -#if GTK_CHECK_VERSION(2,12,0) pidgin_media_output_volume_changed(GtkScaleButton *range, double value, PurpleMedia *media) { double val = (double)value * 100.0; -#else -pidgin_media_output_volume_changed(GtkRange *range, PurpleMedia *media) -{ - double val = (double)gtk_range_get_value(GTK_RANGE(range)); -#endif purple_media_set_output_volume(media, NULL, NULL, val); } @@ -717,7 +705,6 @@ } else g_return_val_if_reached(NULL); -#if GTK_CHECK_VERSION(2,12,0) /* Setup widget structure */ volume_widget = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); progress_parent = gtk_vbox_new(FALSE, 0); @@ -729,19 +716,6 @@ gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume), value/100.0); gtk_box_pack_end(GTK_BOX(volume_widget), volume, FALSE, FALSE, 0); -#else - /* Setup widget structure */ - volume_widget = gtk_vbox_new(FALSE, 0); - progress_parent = volume_widget; - - /* Volume slider */ - volume = gtk_hscale_new_with_range(0.0, 100.0, 5.0); - gtk_range_set_increments(GTK_RANGE(volume), 5.0, 25.0); - gtk_range_set_value(GTK_RANGE(volume), value); - gtk_scale_set_draw_value(GTK_SCALE(volume), FALSE); - gtk_box_pack_end(GTK_BOX(volume_widget), - volume, TRUE, FALSE, 0); -#endif /* Volume level indicator */ progress = gtk_progress_bar_new();
--- a/pidgin/gtkmenutray.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkmenutray.c Sat Feb 02 21:20:08 2013 +0100 @@ -37,10 +37,6 @@ * Globals *****************************************************************************/ static GObjectClass *parent_class = NULL; -#if !GTK_CHECK_VERSION(2,12,0) -static GtkTooltips *tooltips = NULL; -#endif - /****************************************************************************** * Internal Stuff *****************************************************************************/ @@ -80,20 +76,6 @@ #endif /****************************************************************************** - * Widget Stuff - *****************************************************************************/ -#if !GTK_CHECK_VERSION(2,12,0) -static void -tooltips_unref_cb(gpointer data, GObject *object, gboolean is_last_ref) -{ - if (is_last_ref) { - g_object_unref(tooltips); - tooltips = NULL; - } -} -#endif - -/****************************************************************************** * Object Stuff *****************************************************************************/ static void @@ -270,14 +252,6 @@ void pidgin_menu_tray_set_tooltip(PidginMenuTray *menu_tray, GtkWidget *widget, const char *tooltip) { -#if !GTK_CHECK_VERSION(2,12,0) - gboolean notify_tooltips = FALSE; - if (!tooltips) { - tooltips = gtk_tooltips_new(); - notify_tooltips = TRUE; - } -#endif - /* Should we check whether widget is a child of menu_tray? */ /* @@ -290,13 +264,5 @@ if (!gtk_widget_get_has_window(widget)) widget = gtk_widget_get_parent(widget); -#if GTK_CHECK_VERSION(2,12,0) gtk_widget_set_tooltip_text(widget, tooltip); -#else - gtk_tooltips_set_tip(tooltips, widget, tooltip, NULL); - - if (notify_tooltips) - g_object_add_toggle_ref(G_OBJECT(tooltips), tooltips_unref_cb, NULL); -#endif } -
--- a/pidgin/gtknotify.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtknotify.c Sat Feb 02 21:20:08 2013 +0100 @@ -388,13 +388,8 @@ gboolean pidgin_notify_emails_pending() { -#if GTK_CHECK_VERSION(2,18,0) return mail_dialog != NULL && !gtk_widget_get_visible(mail_dialog->dialog); -#else - return mail_dialog != NULL - && !GTK_WIDGET_VISIBLE(mail_dialog->dialog); -#endif } void pidgin_notify_emails_present(void *data)
--- a/pidgin/gtkpluginpref.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkpluginpref.c Sat Feb 02 21:20:08 2013 +0100 @@ -94,10 +94,6 @@ if (purple_plugin_pref_get_masked(pref)) { gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ } g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(entry_cb),
--- a/pidgin/gtkpounce.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkpounce.c Sat Feb 02 21:20:08 2013 +0100 @@ -601,7 +601,7 @@ dialog->buddy_entry = gtk_entry_new(); - pidgin_setup_screenname_autocomplete_with_filter(dialog->buddy_entry, dialog->account_menu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(FALSE)); + pidgin_setup_screenname_autocomplete(dialog->buddy_entry, dialog->account_menu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(FALSE)); gtk_box_pack_start(GTK_BOX(hbox), dialog->buddy_entry, TRUE, TRUE, 0); gtk_widget_show(dialog->buddy_entry);
--- a/pidgin/gtkprefs.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkprefs.c Sat Feb 02 21:20:08 2013 +0100 @@ -58,7 +58,7 @@ #include "gtkwebview.h" #include "gtkwebviewtoolbar.h" #include "pidginstock.h" -#if USE_VV +#ifdef USE_VV #include "media-gst.h" #if GST_CHECK_VERSION(1,0,0) #include <gst/video/videooverlay.h> @@ -123,7 +123,7 @@ static GtkListStore *prefs_status_icon_themes; static GtkListStore *prefs_smiley_themes; -#if USE_VV +#ifdef USE_VV static const gchar *AUDIO_SRC_PLUGINS[] = { "alsasrc", "ALSA", @@ -733,6 +733,19 @@ prefs_smiley_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); } +/** + * Attempt to load the given directory as a theme. If we are unable to + * open the path as a theme then we recurse into path and attempt to + * load each subdirectory that we encounter. + * + * @param path A directory containing a theme. The theme could be at the + * top level of this directory or in any subdirectory thereof. + * @param type The type of theme to load. The loader for this theme type + * will be used and this loader will determine what constitutes a + * "theme." + * + * @return A new reference to a PurpleTheme. + */ static PurpleTheme * prefs_theme_find_theme(const gchar *path, const gchar *type) { @@ -876,7 +889,11 @@ "purple", info->type, NULL); /* move the entire directory to new location */ - g_rename(purple_theme_get_dir(theme), theme_dest); + if (g_rename(purple_theme_get_dir(theme), theme_dest)) { + purple_debug_error("gtkprefs", "Error renaming %s to %s: " + "%s\n", purple_theme_get_dir(theme), theme_dest, + g_strerror(errno)); + } g_free(theme_dest); g_remove(destdir); @@ -920,14 +937,21 @@ if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR); - g_rename(purple_theme_get_dir(theme), theme_dest); + if (g_rename(purple_theme_get_dir(theme), theme_dest)) { + purple_debug_error("gtkprefs", "Error renaming %s to %s: " + "%s\n", purple_theme_get_dir(theme), theme_dest, + g_strerror(errno)); + } g_free(theme_dest); g_object_unref(theme); prefs_themes_refresh(); } else { - g_remove(temp_path); + if (g_remove(temp_path)) { + purple_debug_error("gtkprefs", "Error removing %s: %s\n", + temp_path, g_strerror(errno)); + } purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL); } } else { @@ -2435,10 +2459,6 @@ gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 1, 2, GTK_FILL , 0, 0, 0); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(proxy_print_option), (void *)PROXYPASS); @@ -3018,7 +3038,7 @@ return ret; } -#if USE_VV +#ifdef USE_VV static GList * get_vv_element_devices(const gchar *element_name) { @@ -3377,10 +3397,9 @@ } static void -volume_changed_cb(GtkScaleButton *button, gpointer data) +volume_changed_cb(GtkScaleButton *button, gdouble value, gpointer data) { - purple_prefs_set_int("/purple/media/audio/volume/input", - gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100); + purple_prefs_set_int("/purple/media/audio/volume/input", value * 100); } static void @@ -3655,7 +3674,7 @@ prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++); prefs_notebook_add_page(_("Status / Idle"), away_page(), notebook_page++); prefs_notebook_add_page(_("Themes"), theme_page(), notebook_page++); -#if USE_VV +#ifdef USE_VV prefs_notebook_add_page(_("Voice/Video"), vv_page(), notebook_page++); #endif } @@ -3789,7 +3808,7 @@ purple_prefs_connect_callback(&prefs, PIDGIN_PREFS_ROOT "/smileys/theme", smiley_theme_pref_cb, NULL); -#if USE_VV +#ifdef USE_VV /* Voice/Video */ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig"); purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/audio");
--- a/pidgin/gtkrequest.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkrequest.c Sat Feb 02 21:20:08 2013 +0100 @@ -48,11 +48,6 @@ #include "gtk3compat.h" -#if !GTK_CHECK_VERSION(2,12,0) -#undef gtk_widget_set_tooltip_text -#define gtk_widget_set_tooltip_text(x,y) -#endif - static GtkWidget * create_account_field(PurpleRequestField *field); typedef struct @@ -466,10 +461,6 @@ if (masked) { gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ } } gtk_widget_show_all(vbox); @@ -844,7 +835,7 @@ } } } - pidgin_setup_screenname_autocomplete_with_filter(entry, optmenu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(!strcmp(type_hint, "screenname-all"))); + pidgin_setup_screenname_autocomplete(entry, optmenu, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(!strcmp(type_hint, "screenname-all"))); } } } @@ -912,10 +903,6 @@ if (purple_request_field_string_is_masked(field)) { gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE); -#if !GTK_CHECK_VERSION(2,16,0) - if (gtk_entry_get_invisible_char(GTK_ENTRY(widget)) == '*') - gtk_entry_set_invisible_char(GTK_ENTRY(widget), PIDGIN_INVISIBLE_CHAR); -#endif /* Less than GTK+ 2.16 */ } gtk_editable_set_editable(GTK_EDITABLE(widget),
--- a/pidgin/gtkstatusbox.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkstatusbox.c Sat Feb 02 21:20:08 2013 +0100 @@ -454,11 +454,9 @@ gtk_widget_set_parent(status_box->icon_box, GTK_WIDGET(status_box)); gtk_widget_show(status_box->icon_box); -#if GTK_CHECK_VERSION(2,12,0) gtk_widget_set_tooltip_text(status_box->icon_box, status_box->account ? _("Click to change your buddyicon for this account.") : _("Click to change your buddyicon for all accounts.")); -#endif if (status_box->account && !purple_account_get_bool(status_box->account, "use-global-buddyicon", TRUE))
--- a/pidgin/gtkutils.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkutils.c Sat Feb 02 21:20:08 2013 +0100 @@ -28,9 +28,7 @@ #include "internal.h" #include "pidgin.h" -#ifndef _WIN32 -# include <X11/Xlib.h> -#else +#ifdef _WIN32 # ifdef small # undef small # endif @@ -1412,7 +1410,7 @@ } shortname = strrchr(data->filename, G_DIR_SEPARATOR); shortname = shortname ? shortname + 1 : data->filename; - id = purple_imgstore_add_with_id(filedata, size, shortname); + id = purple_imgstore_new_with_id(filedata, size, shortname); gtk_webview_insert_image(GTK_WEBVIEW(gtkconv->entry), id); purple_imgstore_unref_by_id(id); @@ -2021,7 +2019,7 @@ } void -pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *accountopt, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data) +pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *accountopt, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data) { PidginCompletionData *data;
--- a/pidgin/gtkutils.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkutils.h Sat Feb 02 21:20:08 2013 +0100 @@ -359,7 +359,7 @@ * should be shown. This can be @c NULL. * @param user_data The data to be passed to the filter_func function. */ -void pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *optmenu, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data); +void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data); /** * The default filter function for username autocomplete.
--- a/pidgin/gtkwebviewtoolbar.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/gtkwebviewtoolbar.c Sat Feb 02 21:20:08 2013 +0100 @@ -579,7 +579,7 @@ name = strrchr(filename, G_DIR_SEPARATOR) + 1; - id = purple_imgstore_add_with_id(filedata, size, name); + id = purple_imgstore_new_with_id(filedata, size, name); if (id == 0) { buf = g_strdup_printf(_("Failed to store image: %s\n"), filename);
--- a/pidgin/minidialog.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/minidialog.c Sat Feb 02 21:20:08 2013 +0100 @@ -145,16 +145,6 @@ g_object_set(G_OBJECT(mini_dialog), "enable-description-markup", TRUE, NULL); } -gboolean -pidgin_mini_dialog_links_supported() -{ -#if GTK_CHECK_VERSION(2,18,0) - return TRUE; -#else - return FALSE; -#endif -} - void pidgin_mini_dialog_set_link_callback(PidginMiniDialog *mini_dialog, GCallback cb, gpointer user_data) { g_signal_connect(PIDGIN_MINI_DIALOG_GET_PRIVATE(mini_dialog)->desc, "activate-link", cb, user_data);
--- a/pidgin/minidialog.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/minidialog.h Sat Feb 02 21:20:08 2013 +0100 @@ -144,11 +144,6 @@ */ void pidgin_mini_dialog_enable_description_markup(PidginMiniDialog *mini_dialog); -/** Mini-dialogs support hyperlinks in their description - * (you should first call pidgin_mini_dialog_enable_description_markup() on a given - * dialog to enable them). */ -gboolean pidgin_mini_dialog_links_supported(void); - /** Sets a callback which gets invoked when a hyperlink in the dialog's description is clicked on. * @param mini_dialog a mini-dialog * @param cb the callback to invoke
--- a/pidgin/pidgin-3.pc.in Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/pidgin-3.pc.in Sat Feb 02 21:20:08 2013 +0100 @@ -11,5 +11,5 @@ Name: Pidgin Description: Pidgin is a GTK2-based instant messenger application. Version: @VERSION@ -Requires: gtk+-2.0 purple-3 +Requires: @GTK_PC_MODULE@ purple-3 Cflags: -I${includedir}
--- a/pidgin/pidgin.h Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/pidgin.h Sat Feb 02 21:20:08 2013 +0100 @@ -60,22 +60,5 @@ #define PIDGIN_HIG_BORDER 12 #define PIDGIN_HIG_BOX_SPACE 6 -#if !GTK_CHECK_VERSION(2,16,0) || !defined(PIDGIN_DISABLE_DEPRECATED) -/* - * Older versions of GNOME defaulted to using an asterisk as the invisible - * character. But this is ugly and we want to use something nicer. - * - * The default invisible character was changed in GNOME revision 21446 - * (GTK+ 2.16) from an asterisk to the first available character out of - * 0x25cf, 0x2022, 0x2731, 0x273a. See GNOME bugs 83935 and 307304 for - * discussion leading up to the change. - * - * Here's the change: - * http://svn.gnome.org/viewvc/gtk%2B?view=revision&revision=21446 - * - */ -#define PIDGIN_INVISIBLE_CHAR (gunichar)0x25cf -#endif /* Less than GTK+ 2.16 */ - #endif /* _PIDGIN_H_ */
--- a/pidgin/pidginstock.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/pidginstock.c Sat Feb 02 21:20:08 2013 +0100 @@ -67,7 +67,7 @@ { PIDGIN_STOCK_IGNORE, NULL, GTK_STOCK_DIALOG_ERROR }, { PIDGIN_STOCK_INVITE, NULL, GTK_STOCK_JUMP_TO }, { PIDGIN_STOCK_MODIFY, NULL, GTK_STOCK_PREFERENCES }, - { PIDGIN_STOCK_ADD, NULL, GTK_STOCK_ADD }, + { PIDGIN_STOCK_ADD, NULL, GTK_STOCK_ADD }, { PIDGIN_STOCK_PAUSE, NULL, GTK_STOCK_MEDIA_PAUSE }, { PIDGIN_STOCK_POUNCE, NULL, GTK_STOCK_REDO }, { PIDGIN_STOCK_OPEN_MAIL, NULL, GTK_STOCK_JUMP_TO }, @@ -80,17 +80,17 @@ static const GtkStockItem stock_items[] = { - { PIDGIN_STOCK_ALIAS, N_("_Alias"), 0, 0, NULL }, - { PIDGIN_STOCK_CHAT, N_("_Join"), 0, 0, NULL }, - { PIDGIN_STOCK_CLOSE_TABS, N_("Close _tabs"), 0, 0, NULL }, - { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("I_M"), 0, 0, NULL }, - { PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), 0, 0, NULL }, - { PIDGIN_STOCK_INVITE, N_("_Invite"), 0, 0, NULL }, - { PIDGIN_STOCK_MODIFY, N_("_Modify..."), 0, 0, NULL }, - { PIDGIN_STOCK_ADD, N_("_Add..."), 0, 0, NULL }, - { PIDGIN_STOCK_OPEN_MAIL, N_("_Open Mail"), 0, 0, NULL }, - { PIDGIN_STOCK_PAUSE, N_("_Pause"), 0, 0, NULL }, - { PIDGIN_STOCK_EDIT, N_("_Edit"), 0, 0, NULL } + { PIDGIN_STOCK_ALIAS, N_("_Alias"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_CHAT, N_("_Join"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_CLOSE_TABS, N_("Close _tabs"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("I_M"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_INVITE, N_("_Invite"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_MODIFY, N_("_Modify..."), 0, 0, PACKAGE }, + { PIDGIN_STOCK_ADD, N_("_Add..."), 0, 0, PACKAGE }, + { PIDGIN_STOCK_OPEN_MAIL, N_("_Open Mail"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_PAUSE, N_("_Pause"), 0, 0, PACKAGE }, + { PIDGIN_STOCK_EDIT, N_("_Edit"), 0, 0, PACKAGE } }; typedef struct {
--- a/pidgin/pidgintooltip.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/pidgintooltip.c Sat Feb 02 21:20:08 2013 +0100 @@ -61,22 +61,15 @@ static void initialize_tooltip_delay() { -#if GTK_CHECK_VERSION(2,14,0) GtkSettings *settings; -#endif if (tooltip_delay != -1) return; -#if GTK_CHECK_VERSION(2,14,0) settings = gtk_settings_get_default(); g_object_get(settings, "gtk-enable-tooltips", &enable_tooltips, NULL); g_object_get(settings, "gtk-tooltip-timeout", &tooltip_delay, NULL); -#else - tooltip_delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); - enable_tooltips = (tooltip_delay != 0); -#endif } static void
--- a/pidgin/pixmaps/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/pixmaps/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -297,6 +297,7 @@ protocols/48/bonjour.png \ protocols/48/facebook.png \ protocols/48/gadu-gadu.png \ + protocols/48/google-talk.png \ protocols/48/novell.png \ protocols/48/icq.png \ protocols/48/irc.png \
--- a/pidgin/plugins/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -45,7 +45,6 @@ sendbutton_la_LDFLAGS = -module -avoid-version spellchk_la_LDFLAGS = -module -avoid-version themeedit_la_LDFLAGS = -module -avoid-version -vvconfig_la_LDFLAGS = -module -avoid-version webkit_la_LDFLAGS = -module -avoid-version xmppconsole_la_LDFLAGS = -module -avoid-version
--- a/pidgin/plugins/cap/cap.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/cap/cap.c Sat Feb 02 21:20:08 2013 +0100 @@ -43,7 +43,7 @@ int threshold = purple_prefs_get_int("/plugins/gtk/cap/threshold"); int min_minute = (current_minute - threshold) % 1440; int max_minute = (current_minute + threshold) % 1440; - char *sql; + char *sql, sta_id = NULL; sqlite3_stmt *stmt = NULL; const char *tail = NULL; int rc; @@ -94,7 +94,9 @@ sqlite3_free(sql); - if(strcmp(purple_status_get_id(get_status_for(buddy)), "offline") == 0) { + sta_id = purple_status_get_id(get_status_for(buddy)); + + if(sta_id && !strcmp(sta_id, "offline")) { /* This is kind of stupid, change it. */ if(prediction == 1.0f) prediction = 0.0f;
--- a/pidgin/plugins/convcolors.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/convcolors.c Sat Feb 02 21:20:08 2013 +0100 @@ -198,12 +198,8 @@ { if (response == GTK_RESPONSE_OK) { -#if GTK_CHECK_VERSION(2,14,0) GtkWidget *colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog)); -#else - GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel; -#endif GdkColor color; char colorstr[8]; char tmp[128]; @@ -237,15 +233,9 @@ g_snprintf(tmp, sizeof(tmp), "%s/color", data); if (gdk_color_parse(purple_prefs_get_string(tmp), &color)) { -#if GTK_CHECK_VERSION(2,14,0) gtk_color_selection_set_current_color(GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog))), &color); -#else - gtk_color_selection_set_current_color( - GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), - &color); -#endif } gtk_window_present(GTK_WINDOW(color_dialog));
--- a/pidgin/plugins/disco/xmppdisco.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/disco/xmppdisco.c Sat Feb 02 21:20:08 2013 +0100 @@ -265,7 +265,7 @@ g_return_val_if_fail(str != NULL, ""); for ( ; disco_type_mappings[i].from; ++i) { - if (!strcasecmp(str, disco_type_mappings[i].from)) + if (!g_ascii_strcasecmp(str, disco_type_mappings[i].from)) return disco_type_mappings[i].to; }
--- a/pidgin/plugins/notify.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/notify.c Sat Feb 02 21:20:08 2013 +0100 @@ -96,16 +96,10 @@ #include "gtkplugin.h" #include "gtkutils.h" -#ifndef _WIN32 -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#endif - #define NOTIFY_PLUGIN_ID "gtk-x11-notify" static PurplePlugin *my_plugin = NULL; -#ifndef _WIN32 +#ifdef HAVE_X11 static GdkAtom _Cardinal = GDK_NONE; static GdkAtom _PurpleUnseenCount = GDK_NONE; #endif @@ -525,7 +519,7 @@ static void handle_count_xprop(PidginWindow *purplewin) { -#ifndef _WIN32 +#ifdef HAVE_X11 guint count; GtkWidget *window; GdkWindow *gdkwin; @@ -542,11 +536,7 @@ } count = count_messages(purplewin); -#if GTK_CHECK_VERSION(2,14,0) gdkwin = gtk_widget_get_window(window); -#else - gdkwin = window->window; -#endif gdk_property_change(gdkwin, _PurpleUnseenCount, _Cardinal, 32, GDK_PROP_MODE_REPLACE, (guchar *) &count, 1); @@ -757,7 +747,7 @@ g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(method_toggle_cb), "method_count"); -#ifndef _WIN32 +#ifdef HAVE_X11 /* Count xprop method button */ toggle = gtk_check_button_new_with_mnemonic(_("Insert count of new message into _X property")); gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
--- a/pidgin/plugins/perl/common/Makefile.mingw Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/perl/common/Makefile.mingw Sat Feb 02 21:20:08 2013 +0100 @@ -102,7 +102,7 @@ $(C_FILES): $(PIDGIN_CONFIG_H) $(TARGET).dll: $(PIDGIN_DLL).a $(PURPLE_PERL_DLL).a $(OBJECTS) - $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) -o $(TARGET).dll + $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(DLL_LD_FLAGS) $(LIBS) -o $(TARGET).dll ## ## CLEAN
--- a/pidgin/plugins/pidginrc.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/pidginrc.c Sat Feb 02 21:20:08 2013 +0100 @@ -244,12 +244,8 @@ if (response == GTK_RESPONSE_OK) { GdkColor color; gchar colorstr[8]; -#if GTK_CHECK_VERSION(2,14,0) GtkWidget *colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog)); -#else - GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel; -#endif gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color); @@ -280,13 +276,9 @@ if (pref != NULL && strcmp(pref, "")) { if (gdk_color_parse(pref, &color)) { -#if GTK_CHECK_VERSION(2,14,0) gtk_color_selection_set_current_color(GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(color_dialog))), &color); -#else - gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), &color); -#endif } }
--- a/pidgin/plugins/relnot.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/relnot.c Sat Feb 02 21:20:08 2013 +0100 @@ -74,7 +74,7 @@ if(!purple_http_response_is_successfull(response)) return; - changelog = purple_http_response_get_data(response); + changelog = purple_http_response_get_data(response, NULL); while(changelog[i] && changelog[i] != '\n') i++; @@ -113,7 +113,7 @@ gchar *url; const char *host = "pidgin.im"; - url = g_strdup_printf("http://%s/version.php?version=%s&build=%s", + url = g_strdup_printf("https://%s/version.php?version=%s&build=%s", host, purple_core_get_version(), #ifdef _WIN32
--- a/pidgin/plugins/spellchk.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/spellchk.c Sat Feb 02 21:20:08 2013 +0100 @@ -319,6 +319,10 @@ * Part 1 of 2: This marks . as being an inside-word character. */ if (c == '.') return TRUE; + if (c == '+') + return TRUE; + if (c == '-') + return TRUE; /* Avoid problems with \r, for example (SF #1289031). */ if (c == '\\')
--- a/pidgin/plugins/themeedit.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/themeedit.c Sat Feb 02 21:20:08 2013 +0100 @@ -67,12 +67,8 @@ GdkColor color; PidginBlistTheme *theme; -#if GTK_CHECK_VERSION(2,14,0) colorsel = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog)); -#else - colorsel = GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel; -#endif gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color); theme = pidgin_blist_get_theme(); @@ -155,16 +151,10 @@ } dialog = gtk_color_selection_dialog_new(_("Select Color")); -#if GTK_CHECK_VERSION(2,14,0) if (color) gtk_color_selection_set_current_color(GTK_COLOR_SELECTION( gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dialog))), color); -#else - if (color) - gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel), - color); -#endif g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(theme_color_selected), prop); @@ -184,9 +174,7 @@ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_size_group_add_widget(sizegroup, label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); -#if GTK_CHECK_VERSION(2, 12, 0) gtk_widget_set_tooltip_text(label, blurb); -#endif color = pidgin_pixbuf_button_from_stock("", GTK_STOCK_SELECT_COLOR, PIDGIN_BUTTON_HORIZONTAL); @@ -210,9 +198,7 @@ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_size_group_add_widget(sizegroup, label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); -#if GTK_CHECK_VERSION(2, 12, 0) gtk_widget_set_tooltip_text(label, blurb); -#endif font = pidgin_pixbuf_button_from_stock("", GTK_STOCK_SELECT_FONT, PIDGIN_BUTTON_HORIZONTAL);
--- a/pidgin/plugins/timestamp_format.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/timestamp_format.c Sat Feb 02 21:20:08 2013 +0100 @@ -160,11 +160,7 @@ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); g_signal_connect_after(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), dialog); -#if GTK_CHECK_VERSION(2,14,0) gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), frame); -#else - gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame); -#endif gtk_window_set_role(GTK_WINDOW(dialog), "plugin_config"); gtk_window_set_title(GTK_WINDOW(dialog), _(purple_plugin_get_name(plugin))); gtk_widget_show_all(dialog); @@ -183,13 +179,8 @@ if (!GTK_IS_IMHTML(view)) return TRUE; -#if GTK_CHECK_VERSION(2,14,0) if (!gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(view)), &cx, &cy, NULL)) return TRUE; -#else - if (!gdk_window_get_pointer(GTK_WIDGET(view)->window, &cx, &cy, NULL)) - return TRUE; -#endif buffer = gtk_text_view_get_buffer(view);
--- a/pidgin/plugins/xmppconsole.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/plugins/xmppconsole.c Sat Feb 02 21:20:08 2013 +0100 @@ -291,11 +291,7 @@ #endif gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); gtk_container_set_border_width(GTK_CONTAINER(dialog), 12); -#if GTK_CHECK_VERSION(2,14,0) vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); -#else - vbox = GTK_DIALOG(dialog)->vbox; -#endif hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -381,11 +377,7 @@ #endif gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); gtk_container_set_border_width(GTK_CONTAINER(dialog), 12); -#if GTK_CHECK_VERSION(2,14,0) vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); -#else - vbox = GTK_DIALOG(dialog)->vbox; -#endif hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -541,11 +533,7 @@ #endif gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); gtk_container_set_border_width(GTK_CONTAINER(dialog), 12); -#if GTK_CHECK_VERSION(2,14,0) vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); -#else - vbox = GTK_DIALOG(dialog)->vbox; -#endif hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
--- a/pidgin/smileyparser.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/smileyparser.c Sat Feb 02 21:20:08 2013 +0100 @@ -151,7 +151,7 @@ } /* now for each theme smiley, observe that this does look nasty */ - if (!current_smiley_theme || !(current_smiley_theme->list)) { + if (!current_smiley_theme) { purple_debug_warning("smiley", "theme does not exist\n"); return temp; }
--- a/pidgin/themes/Contents/Resources/Content.html Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/themes/Contents/Resources/Content.html Sat Feb 02 21:20:08 2013 +0100 @@ -1,6 +1,6 @@ <div class="x-container %messageClasses% %messageDirection%"> <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">(%time%)</abbr> - <div class="x-sender">%sender%:</div> - <div class="x-message">%message%</div> + <span class="x-sender">%sender%:</span> + <span class="x-message">%message%</span> </div> <div id="insert"></div>
--- a/pidgin/themes/Contents/Resources/Incoming/Content.html Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/themes/Contents/Resources/Incoming/Content.html Sat Feb 02 21:20:08 2013 +0100 @@ -1,8 +1,8 @@ <div class="x-container %messageClasses% %messageDirection%"> - <div class="x-header" style="color: %senderColor%;"> + <span class="x-header" style="color: %senderColor%;"> <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">(%time%)</abbr> - <div class="x-sender">%sender%:</div> - </div> - <div class="x-message">%message%</div> + <span class="x-sender">%sender%:</span> + </span> + <span class="x-message">%message%</span> </div> <div id="insert"></div>
--- a/pidgin/themes/Contents/Resources/Status.html Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/themes/Contents/Resources/Status.html Sat Feb 02 21:20:08 2013 +0100 @@ -1,5 +1,7 @@ <div class="x-status_container %messageClasses% %messageDirection% %status%"> - <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">%time%</abbr> - <div class="x-message">%message%</div> + <span class="x-header"> + <abbr class="x-time" title="%time{yyyy-MM-ddTHH:mm:ssZZ}%">%time%</abbr> + </span> + <span class="x-message">%message%</span> </div> <div id="insert"></div>
--- a/pidgin/themes/Contents/Resources/main.css Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/themes/Contents/Resources/main.css Sat Feb 02 21:20:08 2013 +0100 @@ -29,12 +29,6 @@ font-weight: bold; } -.x-time, .x-sender -{ - float: left; - margin-right: 4px; -} - .x-message p { margin: 0;
--- a/pidgin/win32/gtkwin32dep.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/win32/gtkwin32dep.c Sat Feb 02 21:20:08 2013 +0100 @@ -171,10 +171,19 @@ } void winpidgin_notify_uri(const char *uri) { - /* We'll allow whatever URI schemes are supported by the - * default http browser. + /* Allow a few commonly used and "safe" schemes to go to the specific + * class handlers and send everything else to the default http browser. + * This isn't optimal, but should cover the most common cases. I didn't + * see any better secure solutions when I did some research. */ - winpidgin_shell_execute(uri, "open", "http"); + gchar *scheme = g_uri_parse_scheme(uri); + if (scheme && (g_ascii_strcasecmp(scheme, "https") == 0 + || g_ascii_strcasecmp(scheme, "ftp") == 0 + || g_ascii_strcasecmp(scheme, "mailto") == 0)) + winpidgin_shell_execute(uri, "open", scheme); + else + winpidgin_shell_execute(uri, "open", "http"); + g_free(scheme); } #define PIDGIN_WM_FOCUS_REQUEST (WM_APP + 13) @@ -377,7 +386,8 @@ } void winpidgin_init(HINSTANCE hint) { - FARPROC proc; + typedef void (__cdecl* LPFNSETLOGFILE)(const LPCSTR); + LPFNSETLOGFILE MySetLogFile; gchar *exchndl_dll_path; purple_debug_info("winpidgin", "winpidgin_init start\n"); @@ -385,10 +395,10 @@ exe_hInstance = hint; exchndl_dll_path = g_build_filename(wpurple_install_dir(), "exchndl.dll", NULL); - proc = wpurple_find_and_loadproc(exchndl_dll_path, "SetLogFile"); + MySetLogFile = (LPFNSETLOGFILE) wpurple_find_and_loadproc(exchndl_dll_path, "SetLogFile"); g_free(exchndl_dll_path); exchndl_dll_path = NULL; - if (proc) { + if (MySetLogFile) { gchar *debug_dir, *locale_debug_dir; debug_dir = g_build_filename(purple_user_dir(), "pidgin.RPT", NULL); @@ -396,7 +406,7 @@ purple_debug_info("winpidgin", "Setting exchndl.dll LogFile to %s\n", debug_dir); - (proc)(locale_debug_dir); + MySetLogFile(locale_debug_dir); g_free(debug_dir); g_free(locale_debug_dir);
--- a/pidgin/win32/nsis/generate_gtk_zip.sh Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/win32/nsis/generate_gtk_zip.sh Sat Feb 02 21:20:08 2013 +0100 @@ -2,31 +2,57 @@ # Script to generate zip file for GTK+ runtime to be included in Pidgin installer PIDGIN_BASE=$1 +GPG_SIGN=$2 if [ ! -e $PIDGIN_BASE/ChangeLog ]; then echo $(basename $0) must must have the pidgin base dir specified as a parameter. exit 1 fi -STAGE_DIR=$PIDGIN_BASE/pidgin/win32/nsis/gtk_runtime_stage +STAGE_DIR=`readlink -f $PIDGIN_BASE/pidgin/win32/nsis/gtk_runtime_stage` #Subdirectory of $STAGE_DIR INSTALL_DIR=Gtk CONTENTS_FILE=$INSTALL_DIR/CONTENTS +PIDGIN_VERSION=$( < $PIDGIN_BASE/VERSION ) #This needs to be changed every time there is any sort of change. -BUNDLE_VERSION=2.16.6.0 +BUNDLE_VERSION=2.16.6.1 +BUNDLE_SHA1SUM=5e16b7efb11943e8c80bc390f6c38df904fd36ed +ZIP_FILE="$PIDGIN_BASE/pidgin/win32/nsis/gtk-runtime-$BUNDLE_VERSION.zip" -ATK="http://ftp.acc.umu.se/pub/gnome/binaries/win32/atk/1.26/atk_1.26.0-1_win32.zip ATK 1.26.0-1" -CAIRO="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/cairo_1.8.10-1_win32.zip Cairo 1.8.10-1" -EXPAT="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/expat_2.0.1-1_win32.zip Expat 2.0.1-1" -FONTCONFIG="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/fontconfig_2.8.0-2_win32.zip Fontconfig 2.8.0-2" -FREETYPE="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/freetype_2.3.11-2_win32.zip Freetype 2.3.11-2" -GETTEXT="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime-0.17-1.zip Gettext 0.17-1" -GLIB="http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.20/glib_2.20.5-1_win32.zip Glib 2.20.5-1" -GTK="http://ftp.acc.umu.se/pub/gnome/binaries/win32/gtk+/2.16/gtk+_2.16.6-2_win32.zip GTK+ 2.16.6-2" -LIBPNG="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/libpng_1.4.0-1_win32.zip libpng 1.4.0-1" -PANGO="http://ftp.gnome.org/pub/gnome/binaries/win32/pango/1.26/pango_1.26.2-1_win32.zip Pango 1.26.2-1" -ZLIB="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/zlib-1.2.3.zip zlib 1.2.3" +#Download the existing file (so that we distribute the exact same file for all releases with the same bundle version) +FILE="$ZIP_FILE" +if [ ! -e "$FILE" ]; then + wget "https://pidgin.im/win32/download_redir.php?version=$PIDGIN_VERSION>k_version=$BUNDLE_VERSION&dl_pkg=gtk" -O "$FILE" +fi +CHECK_SHA1SUM=`sha1sum $FILE` +CHECK_SHA1SUM=${CHECK_SHA1SUM%%\ *} +if [ "$CHECK_SHA1SUM" != "$BUNDLE_SHA1SUM" ]; then + echo "sha1sum ($CHECK_SHA1SUM) for $FILE doesn't match expected value of $BUNDLE_SHA1SUM" + # Allow "devel" versions to build their own bundles if the download doesn't succeed + if [[ "$PIDGIN_VERSION" == *"devel" ]]; then + echo "Continuing GTK+ Bundle creation for development version of Pidgin" + else + exit 1 + fi +else + exit 0 +fi + + +ATK="http://ftp.gnome.org/pub/gnome/binaries/win32/atk/1.32/atk_1.32.0-2_win32.zip ATK 1.32.0-2 sha1sum:3c31c9d6b19af840e2bd8ccbfef4072a6548dc4e" +#Cairo 1.10.2 has a bug that can be seen when selecting text +#CAIRO="http://ftp.gnome.org/pub/GNOME/binaries/win32/dependencies/cairo_1.10.2-2_win32.zip Cairo 1.10.2-2 sha1sum:d44cd66a9f4d7d29a8f2c28d1c1c5f9b0525ba44" +CAIRO="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/cairo_1.8.10-1_win32.zip Cairo 1.8.10-1 sha1sum:a08476cccd807943958610977a138c4d6097c7b8" +EXPAT="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/expat_2.1.0-1_win32.zip Expat 2.1.0-1 gpg:0x71D4DDE53F188CBE" +FONTCONFIG="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/fontconfig_2.8.0-2_win32.zip Fontconfig 2.8.0-2 sha1sum:37a3117ea6cc50c8a88fba9b6018f35a04fa71ce" +FREETYPE="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/freetype_2.4.10-1_win32.zip Freetype 2.4.10-1 gpg:0x71D4DDE53F188CBE" +GETTEXT="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip Gettext 0.18.1.1-2 sha1sum:a7cc1ce2b99b408d1bbea9a3b4520fcaf26783b3" +GLIB="http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip Glib 2.28.8-1 sha1sum:5d158f4c77ca0b5508e1042955be573dd940b574" +GTK="http://ftp.acc.umu.se/pub/gnome/binaries/win32/gtk+/2.16/gtk+_2.16.6-2_win32.zip GTK+ 2.16.6-2 sha1sum:012853e6de814ebda0cc4459f9eed8ae680e6d17" +LIBPNG="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/libpng_1.4.12-1_win32.zip libpng 1.4.12-1 gpg:0x71D4DDE53F188CBE" +PANGO="http://ftp.gnome.org/pub/gnome/binaries/win32/pango/1.29/pango_1.29.4-1_win32.zip Pango 1.29.4-1 sha1sum:3959319bd04fbce513458857f334ada279b8cdd4" +ZLIB="http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/zlib_1.2.5-2_win32.zip zlib 1.2.5-2 sha1sum:568907188761df2d9309196e447d91bbc5555d2b" ALL="ATK CAIRO EXPAT FONTCONFIG FREETYPE GETTEXT GLIB GTK LIBPNG PANGO ZLIB" @@ -41,11 +67,40 @@ function download_and_extract { URL=${1%%\ *} - NAME=${1#*\ } + VALIDATION=${1##*\ } + NAME=${1%\ *} + NAME=${NAME#*\ } FILE=$(basename $URL) if [ ! -e $FILE ]; then echo Downloading $NAME - wget $URL || return 1 + wget $URL || exit 1 + fi + VALIDATION_TYPE=${VALIDATION%%:*} + VALIDATION_VALUE=${VALIDATION##*:} + if [ $VALIDATION_TYPE == 'sha1sum' ]; then + CHECK_SHA1SUM=`sha1sum $FILE` + CHECK_SHA1SUM=${CHECK_SHA1SUM%%\ *} + if [ "$CHECK_SHA1SUM" != "$VALIDATION_VALUE" ]; then + echo "sha1sum ($CHECK_SHA1SUM) for $FILE doesn't match expected value of $VALIDATION_VALUE" + exit 1 + fi + elif [ $VALIDATION_TYPE == 'gpg' ]; then + if [ ! -e "$FILE.asc" ]; then + echo Downloading GPG key for $NAME + wget "$URL.asc" || exit 1 + fi + #Use our own keyring to avoid adding stuff to the main keyring + #This doesn't use $GPG_SIGN because we don't this validation to be bypassed when people are skipping signing output + GPG_BASE="gpg -q --keyring $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg" + if [[ ! -e $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg \ + || `$GPG_BASE --list-keys "$VALIDATION_VALUE" > /dev/null && echo -n "0"` -ne 0 ]]; then + touch $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg + $GPG_BASE --no-default-keyring --keyserver pgp.mit.edu --recv-key "$VALIDATION_VALUE" || exit 1 + fi + $GPG_BASE --verify "$FILE.asc" || (echo "$FILE failed signature verification"; exit 1) || exit 1 + else + echo "Unrecognized validation type of $VALIDATION_TYPE" + exit 1 fi EXTENSION=${FILE##*.} #This is an OpenSuSE build service RPM @@ -77,7 +132,9 @@ done #Generate zip file to be included in installer -zip -9 -r ../gtk-runtime-$BUNDLE_VERSION.zip Gtk +rm -f $ZIP_FILE +zip -9 -r $ZIP_FILE Gtk +($GPG_SIGN -ab $ZIP_FILE && $GPG_SIGN --verify $ZIP_FILE.asc) || exit 1 exit 0
--- a/pidgin/win32/nsis/pidgin-installer.nsi Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Sat Feb 02 21:20:08 2013 +0100 @@ -34,7 +34,6 @@ !include "MUI.nsh" !include "Sections.nsh" -!include "WinVer.nsh" !include "LogicLib.nsh" !include "Memento.nsh" @@ -71,7 +70,7 @@ !define PERL_REG_KEY "SOFTWARE\Perl" !define PERL_DLL "perl510.dll" -!define DOWNLOADER_URL "http://pidgin.im/win32/download_redir.php?version=${PIDGIN_VERSION}" +!define DOWNLOADER_URL "https://pidgin.im/win32/download_redir.php?version=${PIDGIN_VERSION}" !define MEMENTO_REGISTRY_ROOT HKLM !define MEMENTO_REGISTRY_KEY "${PIDGIN_UNINSTALL_KEY}" @@ -93,6 +92,7 @@ ;Reserve files used in .onInit ;for faster start-up ReserveFile "${NSISDIR}\Plugins\System.dll" +ReserveFile "${NSISDIR}\Plugins\UserInfo.dll" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS !insertmacro MUI_RESERVEFILE_LANGDLL @@ -118,8 +118,8 @@ ;Finish Page config !define MUI_FINISHPAGE_NOAUTOCLOSE - !define MUI_FINISHPAGE_RUN "$INSTDIR\pidgin.exe" - !define MUI_FINISHPAGE_RUN_NOTCHECKED + ;!define MUI_FINISHPAGE_RUN "$INSTDIR\pidgin.exe" + ;!define MUI_FINISHPAGE_RUN_NOTCHECKED !define MUI_FINISHPAGE_LINK $(PIDGINFINISHVISITWEBSITE) !define MUI_FINISHPAGE_LINK_LOCATION "http://pidgin.im" @@ -148,13 +148,6 @@ !include "${PIDGIN_NSIS_INCLUDE_PATH}\langmacros.nsh" ;-------------------------------- -;Reserve Files - ; Only need this if using bzip2 compression - - !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - !insertmacro MUI_RESERVEFILE_LANGDLL - ReserveFile "${NSISDIR}\Plugins\UserInfo.dll" - ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Start Install Sections ;; @@ -268,9 +261,18 @@ NSISdl::download /TIMEOUT=10000 $R2 $R1 Pop $R0 ;StrCmp $R0 "cancel" done - StrCmp $R0 "success" +2 + StrCmp $R0 "success" 0 prompt_retry + + Push "${GTK_SHA1SUM}" + Push "$R1" ; Filename + Call CheckSHA1Sum + Pop $R0 + + StrCmp "$R0" "0" extract + prompt_retry: MessageBox MB_RETRYCANCEL "$(PIDGINGTKDOWNLOADERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done + extract: !endif ;Delete the old Gtk directory @@ -282,7 +284,9 @@ StrCmp $R0 "success" +2 DetailPrint "$R0" ;print error message to log +!ifndef OFFLINE_INSTALLER done: +!endif SectionEnd ; end of GTK+ section ;-------------------------------- @@ -335,7 +339,7 @@ Delete "$INSTDIR\plugins\liboscar.dll" Delete "$INSTDIR\plugins\libjabber.dll" - File /r /x locale ..\..\..\${PIDGIN_INSTALL_DIR}\*.* + File /r /x locale /x Gtk ..\..\..\${PIDGIN_INSTALL_DIR}\*.* ; Check if Perl is installed, if so add it to the AppPaths ReadRegStr $R2 HKLM ${PERL_REG_KEY} "" @@ -351,21 +355,6 @@ perl_done: - ; If this is under NT4, delete the SILC support stuff - ; there is a bug that will prevent any account from connecting - ; See https://lists.silcnet.org/pipermail/silc-devel/2005-January/001588.html - ; Also, remove the GSSAPI SASL plugin and associated files as they aren't - ; compatible with NT4. - ${If} ${IsNT} - ${AndIf} ${IsWinNT4} - ;SILC - Delete "$INSTDIR\plugins\libsilc.dll" - Delete "$INSTDIR\libsilcclient-1-1-3.dll" - Delete "$INSTDIR\libsilc-1-1-2.dll" - ;GSSAPI - Delete "$INSTDIR\sasl2\saslGSSAPI.dll" - ${EndIf} - SetOutPath "$INSTDIR" ; If we don't have install rights we're done @@ -467,9 +456,18 @@ NSISdl::download /TIMEOUT=10000 $R2 $R1 Pop $R0 StrCmp $R0 "cancel" done - StrCmp $R0 "success" +2 + StrCmp $R0 "success" 0 prompt_retry + + Push "${DEBUG_SYMBOLS_SHA1SUM}" + Push "$R1" ; Filename + Call CheckSHA1Sum + Pop $R0 + + StrCmp "$R0" "0" extract + prompt_retry: MessageBox MB_RETRYCANCEL "$(PIDGINDEBUGSYMBOLSERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done + extract: !endif SetOutPath "$INSTDIR" @@ -478,7 +476,9 @@ StrCmp $R0 "success" +2 DetailPrint "$R0" ;print error message to log +!ifndef OFFLINE_INSTALLER done: +!endif SectionEnd ;-------------------------------- @@ -638,11 +638,11 @@ Delete "$INSTDIR\libsasl.dll" Delete "$INSTDIR\libsilc-1-1-2.dll" Delete "$INSTDIR\libsilcclient-1-1-3.dll" + Delete "$INSTDIR\libssp-0.dll" Delete "$INSTDIR\libxml2-2.dll" Delete "$INSTDIR\libymsg.dll" Delete "$INSTDIR\nss3.dll" Delete "$INSTDIR\nssutil3.dll" - Delete "$INSTDIR\nssckbi.dll" Delete "$INSTDIR\pidgin.dll" Delete "$INSTDIR\pidgin.exe" Delete "$INSTDIR\smime3.dll" @@ -1300,3 +1300,40 @@ Pop $R0 Exch $R1 FunctionEnd + +!ifndef OFFLINE_INSTALLER +; Input Stack: Filename, SHA1sum +; Output Return Code: 0=Match; 1=FileSum error; 2=Mismatch +Function CheckSHA1Sum + Push $R0 + Exch + Pop $R0 ;Filename + Push $R2 + Exch 2 + Pop $R2 ;SHA1sum + Push $R1 + + SHA1Plugin::FileSum "$R0" + Pop $R1 + Pop $R0 + + StrCmp "$R1" "0" +4 + DetailPrint "SHA1Sum calculation error: $R0" + IntOp $R1 0 + 1 + Goto done + + ; Compare the SHA1Sums + StrCmp $R2 $R0 +4 + DetailPrint "SHA1Sum mismatch... Expected $R2; got $R0" + IntOp $R1 0 + 2 + Goto done + + IntOp $R1 0 + 0 + + done: + Pop $R2 + Pop $R0 + Exch $R1 ;$R1 has the return code +FunctionEnd +!endif +
--- a/pidgin/win32/winpidgin.c Sat Feb 02 18:29:35 2013 +0100 +++ b/pidgin/win32/winpidgin.c Sat Feb 02 21:20:08 2013 +0100 @@ -38,9 +38,10 @@ #include <sys/stat.h> #include "config.h" -typedef int (CALLBACK* LPFNPIDGINMAIN)(HINSTANCE, int, char**); -typedef void (CALLBACK* LPFNSETDLLDIRECTORY)(LPCWSTR); -typedef BOOL (CALLBACK* LPFNATTACHCONSOLE)(DWORD); +typedef int (__cdecl* LPFNPIDGINMAIN)(HINSTANCE, int, char**); +typedef void (WINAPI* LPFNSETDLLDIRECTORY)(LPCWSTR); +typedef BOOL (WINAPI* LPFNATTACHCONSOLE)(DWORD); +typedef BOOL (WINAPI* LPFNSETPROCESSDEPPOLICY)(DWORD); static BOOL portable_mode = FALSE; @@ -556,7 +557,7 @@ len = WideCharToMultiByte(CP_UTF8, 0, tmp1, wlen, NULL, 0, NULL, NULL); if (len) { - utf8msg = malloc(len * sizeof(char)); + utf8msg = malloc(len); len = WideCharToMultiByte(CP_UTF8, 0, tmp1, wlen, utf8msg, len, NULL, NULL); } @@ -642,16 +643,24 @@ } } + /* Permanently enable DEP if the OS supports it */ + if ((hmod = GetModuleHandleW(L"kernel32.dll"))) { + LPFNSETPROCESSDEPPOLICY MySetProcessDEPPolicy = + (LPFNSETPROCESSDEPPOLICY) + GetProcAddress(hmod, "SetProcessDEPPolicy"); + if (MySetProcessDEPPolicy) + MySetProcessDEPPolicy(1); //PROCESS_DEP_ENABLE + } + if (debug || help || version) { /* If stdout hasn't been redirected to a file, alloc a console * (_istty() doesn't work for stuff using the GUI subsystem) */ if (_fileno(stdout) == -1 || _fileno(stdout) == -2) { LPFNATTACHCONSOLE MyAttachConsole = NULL; - if ((hmod = GetModuleHandleW(L"kernel32.dll"))) { + if (hmod) MyAttachConsole = (LPFNATTACHCONSOLE) GetProcAddress(hmod, "AttachConsole"); - } if ((MyAttachConsole && MyAttachConsole(ATTACH_PARENT_PROCESS)) || AllocConsole()) { freopen("CONOUT$", "w", stdout); @@ -683,31 +692,34 @@ wcscat(pidgin_dir, L"\\exchndl.dll"); if ((hmod = LoadLibraryW(pidgin_dir))) { - FARPROC proc; + typedef void (__cdecl* LPFNSETLOGFILE)(const LPCSTR); + LPFNSETLOGFILE MySetLogFile; /* exchndl.dll is built without UNICODE */ char debug_dir[MAX_PATH]; printf("Loaded exchndl.dll\n"); /* Temporarily override exchndl.dll's logfile * to something sane (Pidgin will override it * again when it initializes) */ - proc = GetProcAddress(hmod, "SetLogFile"); - if (proc) { - if (GetTempPathA(sizeof(debug_dir) * sizeof(char), debug_dir) != 0) { + MySetLogFile = (LPFNSETLOGFILE) GetProcAddress(hmod, "SetLogFile"); + if (MySetLogFile) { + if (GetTempPathA(sizeof(debug_dir), debug_dir) != 0) { strcat(debug_dir, "pidgin.RPT"); printf(" Setting exchndl.dll LogFile to %s\n", debug_dir); - (proc)(debug_dir); + MySetLogFile(debug_dir); } } - proc = GetProcAddress(hmod, "SetDebugInfoDir"); - if (proc) { + /* The function signature for SetDebugInfoDir is the same as SetLogFile, + * so we can reuse the variable */ + MySetLogFile = (LPFNSETLOGFILE) GetProcAddress(hmod, "SetDebugInfoDir"); + if (MySetLogFile) { char *pidgin_dir_ansi = NULL; /* Restore pidgin_dir to point to where the executable is */ pidgin_dir_start[0] = L'\0'; i = WideCharToMultiByte(CP_ACP, 0, pidgin_dir, -1, NULL, 0, NULL, NULL); if (i != 0) { - pidgin_dir_ansi = malloc(i * sizeof(char)); + pidgin_dir_ansi = malloc(i); i = WideCharToMultiByte(CP_ACP, 0, pidgin_dir, -1, pidgin_dir_ansi, i, NULL, NULL); if (i == 0) { @@ -716,13 +728,13 @@ } } if (pidgin_dir_ansi != NULL) { - _snprintf(debug_dir, sizeof(debug_dir) / sizeof(char), + _snprintf(debug_dir, sizeof(debug_dir), "%s\\pidgin-%s-dbgsym", pidgin_dir_ansi, VERSION); - debug_dir[sizeof(debug_dir) / sizeof(char) - 1] = '\0'; + debug_dir[sizeof(debug_dir) - 1] = '\0'; printf(" Setting exchndl.dll DebugInfoDir to %s\n", debug_dir); - (proc)(debug_dir); + MySetLogFile(debug_dir); free(pidgin_dir_ansi); } } @@ -800,7 +812,7 @@ int len = WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, NULL, 0, NULL, NULL); if (len != 0) { - char *arg = malloc(len * sizeof(char)); + char *arg = malloc(len); len = WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, arg, len, NULL, NULL); if (len != 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/ca-certs/Baltimore_CyberTrust_Root.pem Sat Feb 02 21:20:08 2013 +0100 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE-----
--- a/share/ca-certs/Makefile.am Sat Feb 02 18:29:35 2013 +0100 +++ b/share/ca-certs/Makefile.am Sat Feb 02 21:20:08 2013 +0100 @@ -1,6 +1,7 @@ CERTIFICATES = \ AddTrust_External_Root.pem \ America_Online_Root_Certification_Authority_1.pem \ + Baltimore_CyberTrust_Root.pem \ CAcert_Root.pem \ CAcert_Class3.pem \ Deutsche_Telekom_Root_CA_2.pem \ @@ -14,7 +15,6 @@ Thawte_Premium_Server_CA.pem \ Thawte_Primary_Root_CA.pem \ ValiCert_Class_2_VA.pem \ - Verisign_RSA_Secure_Server_CA.pem \ Verisign_Class3_Primary_CA.pem \ VeriSign_Class_3_Public_Primary_Certification_Authority_-_G2.pem \ VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem \ @@ -23,9 +23,7 @@ EXTRA_CERTS = \ AOL_Member_CA.pem \ DigiCertHighAssuranceCA-3.pem \ - Microsoft_Internet_Authority.pem \ Microsoft_Internet_Authority_2010.pem \ - Microsoft_Secure_Server_Authority.pem \ Microsoft_Secure_Server_Authority_2010.pem \ VeriSign_Class3_Extended_Validation_CA.pem \ VeriSign_International_Server_Class_3_CA.pem
--- a/share/ca-certs/Microsoft_Internet_Authority.pem Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFCjCCBHOgAwIBAgIEBycWdTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTA4MDIxOTE4MjcwMloXDTExMDIxOTE4MjQ1M1owJzElMCMG -A1UEAxMcTWljcm9zb2Z0IEludGVybmV0IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAKiloatvDehDG/rQriel2AC9qmSJdvjKb2fmJf30 -K7SaC3zQu8kGQxENUEFsHsH0jmBejJ9vvn9tHZ8hGL+kORvWUVBskdMzP65rC0V0 -VeVgUYzPZ7MvrLfhh9+v3yJ7qRuf1aNgmzJg5t1AA91X+aRrFT4lRzl9BFWhQ1VS -XaD7l6qoiyhD8FbrdLRAe61swsRmzWeXoy6NJpOBsGXaCSG1Jooylro+zkWxt97c -NkNf/wYqoYcIXo02YpFbwreveejW9a0Lh/1z9+e9aiMtC5QnPT57GTqNINt5R0rp -Iz4g3GJhmjXVoVF/tev5DMJuhRgPoz0W0aA3UnSmTWh2RFvgqawLqSRrKUhVjySi -/m5s62uG5xxIftO7/6ljzS061CFoV/RBl/I3WghYp04sr4cSXWa/rL449YhBT8BJ -jltefWCYAOcT1nA4oFXwXbl1qCUIkZ0bqwju2FGW5vl2qh6vmzcQjc3XxD0m2UqC -yJNFa9SUgVXtUCqeOI+KqgLW01tpqZteG10byWKmppTVAvdPwHoGE0bl6wBwXldE -f7Pn4lqu6Yp4bedP3Qv1sfp2H7D98cxSwYRt3UcXN2kjTPv+pby2fEHm9GWf3iE/ -7OtzUI7LYhP7+rGyuCYTtZKH1jDWHrTZBpnAPmrAQQHCI8/4TjF9ZQ1mqRi6x9I9 -9XGfAgMBAAGjggFvMIIBazASBgNVHRMBAf8ECDAGAQH/AgEBMFMGA1UdIARMMEow -SAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly9jeWJlcnRydXN0Lm9t -bmlyb290LmNvbS9yZXBvc2l0b3J5LmNmbTAOBgNVHQ8BAf8EBAMCAYYwgYkGA1Ud -IwSBgTB/oXmkdzB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0 -aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAh -BgNVBAMTGkdURSBDeWJlclRydXN0IEdsb2JhbCBSb290ggIBpTBFBgNVHR8EPjA8 -MDqgOKA2hjRodHRwOi8vd3d3LnB1YmxpYy10cnVzdC5jb20vY2dpLWJpbi9DUkwv -MjAxOC9jZHAuY3JsMB0GA1UdDgQWBBTG27vA2CAZkvFg/IjxWH+8G06PGjANBgkq -hkiG9w0BAQUFAAOBgQBnSDXCyiqGmHTAEJOtZYVm/IbzGtzCY423NF6/yuccYZkm -spJnDoh8nq3nx3P2KBEyPAqoQ1MEFC+ByQjV4AAQ9dMQALUGNRfHhFUhBeeIybYd -bzvKOxSlIYSwO2T56+oXyDlkbQWKmHec5qzCE0lwGHslsRU/CHwhuFu2nH+CxQ== ------END CERTIFICATE-----
--- a/share/ca-certs/Microsoft_Secure_Server_Authority.pem Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIGEzCCA/ugAwIBAgIKYRZtLwAEAAAAIDANBgkqhkiG9w0BAQUFADAnMSUwIwYD -VQQDExxNaWNyb3NvZnQgSW50ZXJuZXQgQXV0aG9yaXR5MB4XDTA4MDQwOTIxMzc1 -NFoXDTExMDIxOTE4MjQ1M1owgYsxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJ -kiaJk/IsZAEZFgltaWNyb3NvZnQxFDASBgoJkiaJk/IsZAEZFgRjb3JwMRcwFQYK -CZImiZPyLGQBGRYHcmVkbW9uZDEqMCgGA1UEAxMhTWljcm9zb2Z0IFNlY3VyZSBT -ZXJ2ZXIgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -kYTz6fKXvrdfIr5o3Ue4CRIzhTE+8JE4hrLTQki3emjYn/CfHRPb7hmMiOZmWBdE -DUEymyXOyZ7Sy2tC6WaBC4onVYotPoSsaOZJv6EJeHPk64RiWTfX+XqufRndYOEC -DUmotYQNPV/8InioIBf9+gOSsAMdmyGZF6C1PkJqvPZTRxNv6hxuMMb6uOQIPoFX -/ceQvAOZcJx2qGsAVKsJHylYkC0GgVyFVhOI0vcZZBcP5T+NtOmyjVBWdxS413HL -D+8w+3wG0bOP8EyOeRnuf0KLXGBangte0ZFIRd28GXpo5UrcA/r5000e2RTHmhC4 -8YPMIoi+q9XZoF5R0Z069QIDAQABo4IB2jCCAdYwEgYDVR0TAQH/BAgwBgEB/wIB -ADAdBgNVHQ4EFgQUFFXEOeA9LtFVLkiWsNh+FCIGk7wwCwYDVR0PBAQDAgGGMBIG -CSsGAQQBgjcVAQQFAgMFAAUwIwYJKwYBBAGCNxUCBBYEFM7FoL4P/nlmdZEP8PeS -WzWYqBWzMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMB8GA1UdIwQYMBaAFMbb -u8DYIBmS8WD8iPFYf7wbTo8aMIGjBgNVHR8EgZswgZgwgZWggZKggY+GNmh0dHA6 -Ly9tc2NybC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL21zd3d3KDQpLmNy -bIY0aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL21zd3d3 -KDQpLmNybIYfaHR0cDovL2NvcnBwa2kvY3JsL21zd3d3KDQpLmNybDB5BggrBgEF -BQcBAQRtMGswPAYIKwYBBQUHMAKGMGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w -a2kvbXNjb3JwL21zd3d3KDQpLmNydDArBggrBgEFBQcwAoYfaHR0cDovL2NvcnBw -a2kvYWlhL21zd3d3KDQpLmNydDANBgkqhkiG9w0BAQUFAAOCAgEAempuzk/VLM4N -H9TAbFtCjKc95iGmyx2bHbEk9m2cbGxXjBre+N4cJoIYYmhLrZ6L712ov1NjM73b -m8fb2Fy8Yw8Cmwc8VtarPZT2yzGr8MhNUDVuZswaKfjCY3H7RYv/XKc7AOMd25WP -/M0WTT4Bna6hl9dUaDGwv5SZFFIJ17FLo4FR2H7IkOOI/WcUPAHeDXUewp4qRPE/ -560xZrLSeNH2lKnOAwwXxwnXSo5WOF5AQXh1nRdbBV9Nu7yI6jH1QV6fKf6oFU2Y -IOjpnJ0FihVB6XoZ0wNOUMzPEEQcTfIoVoc+t0iK02wcmTLgBgbYU703dHvvPTcn -IfdI2mscx8l9MjUOdklIIve0FhCxRPqHpEeKjM95gllbXmWgQxAXiog+A62fEo5d -M7nfeEyiweSlhj1cv+2dyhzyS5saKYkk3ocCnOMCyD0M+4gJx4n4b/zT3rcujyN+ -7m20PbBTjcdTT1+AxOs75rON2hhKUqqrk2MDCpnEJsNK4TuRyDUtm9r+AxaZ4XRK -MT8InY1Xl9hzrIK6MVERYH46kxg6odwpzJ8Urn4dREBiMy6Gzq8mtyXvpYEcmeGL -zz1aT7qNNbQ0qqbPb6RpOMHlUWOIhVWJC71T5WK1pynAc3P9zOm8BkUYvIyJvCbR -bufCGVng4FAtVZ1advxSVRoa4GyuFZ8= ------END CERTIFICATE-----
--- a/share/ca-certs/Verisign_RSA_Secure_Server_CA.pem Sat Feb 02 18:29:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzEL -MAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMu -MS4wLAYDVQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MB4XDTk0MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UE -BhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD -VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGb -MA0GCSqGSIb3DQEBAQUAA4GJADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6O -LDfO6zV4ZFQD5YRAUcm/jwjiioII0haGN1XpsSECrXZogZoFokvJSyVmIlZs -iAeP94FZbYQHZXATcXY+m3dM41CJVphIuR2nKRoTLkoRWZweFdVJVCxzOmmC -sZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZIhvcNAQECBQADfgBl3X7hsuyw -4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3YQO2WxZpO8ZECAyIUwxr -l0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc1/p3yjkWWW8O6tO1 -g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA== ------END CERTIFICATE-----