yahoo: Remove protocol plugin from tree
Yahoo has completely reimplemented their protocol, so this version
is no longer operable as of August 5th, 2016:
https://yahoo.tumblr.com/post/145715934739/q2-2016-progress-report-on-our-product
A new prpl has been written to support the new protocol. It can be
found here: https://github.com/EionRobb/funyahoo-plusplus
This also removes support for Yahoo! Japan. According to
http://messenger.yahoo.co.jp/ the service ended March 26th, 2014.
--- a/ChangeLog Wed Oct 05 21:14:58 2016 +0200
+++ b/ChangeLog Wed Oct 05 15:10:29 2016 -0500
@@ -13,6 +13,14 @@
https://pidgin.im/pipermail/devel/2016-September/024078.htm
* Removed the MySpaceIM protocol plugin. The service has been defunct for a
+ * Remove the Yahoo! protocol plugin. Yahoo has completely + reimplemented their protocol, so this version is no longer operable as + https://yahoo.tumblr.com/post/145715934739/q2-2016-progress-report-on-our-product + A new protocol plugin has been written to support the new protocol. + It can be found here: https://github.com/EionRobb/funyahoo-plusplus + This also removes support for Yahoo! Japan. According to + http://messenger.yahoo.co.jp/ the service ended March 26th, 2014. * Replaced instances of d.pidgin.im with developer.pidgin.im and updated the
--- a/README Wed Oct 05 21:14:58 2016 +0200
+++ b/README Wed Oct 05 15:10:29 2016 -0500
@@ -4,7 +4,7 @@
libpurple is a library intended to be used by programmers seeking
to write an IM client that connects to many IM networks. It supports
-AIM, ICQ, XMPP, MSN and Yahoo!, among others.
+AIM, ICQ, and XMPP, among others. Pidgin is a graphical IM client written in C which uses the GTK+
--- a/configure.ac Wed Oct 05 21:14:58 2016 +0200
+++ b/configure.ac Wed Oct 05 15:10:29 2016 -0500
@@ -1189,7 +1189,7 @@
if test "x$STATIC_PRPLS" = "xall" ; then
- STATIC_PRPLS="bonjour gg irc jabber novell oscar sametime silc simple yahoo zephyr"
+ STATIC_PRPLS="bonjour gg irc jabber novell oscar sametime silc simple zephyr" if test "x$have_meanwhile" != "xyes" ; then
STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
@@ -1209,19 +1209,13 @@
for i in $STATIC_PRPLS ; do
dnl Ugly special case for "libsilcpurple.la":
- dnl ... and Ugly special case for multi-protocol oscar and yahoo
+ dnl ... and Ugly special case for multi-protocol oscar if test \( "x$i" = "xoscar" -o "x$i" = "xaim" -o "x$i" = "xicq" \) -a "x$static_oscar" != "xyes"; then
STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/oscar/liboscar.la"
extern_init="$extern_init extern gboolean purple_init_aim_plugin();"
extern_init="$extern_init extern gboolean purple_init_icq_plugin();"
load_proto="$load_proto purple_init_aim_plugin();"
load_proto="$load_proto purple_init_icq_plugin();"
- elif test "x$i" = "xyahoo"; then
- STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/yahoo/libymsg.la"
- extern_init="$extern_init extern gboolean purple_init_yahoo_plugin();"
- extern_init="$extern_init extern gboolean purple_init_yahoojp_plugin();"
- load_proto="$load_proto purple_init_yahoo_plugin();"
- load_proto="$load_proto purple_init_yahoojp_plugin();"
if test "x$i" = "xsilc"; then
STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib${i}purple.la"
@@ -1246,7 +1240,6 @@
silc10) static_silc=yes ;;
simple) static_simple=yes ;;
- yahoo) static_yahoo=yes ;;
zephyr) static_zephyr=yes ;;
*) echo "Invalid static protocol $i!!" ; exit 1 ;;
@@ -1260,7 +1253,6 @@
AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes")
AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$have_silc" = "xyes")
AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes")
-AM_CONDITIONAL(STATIC_YAHOO, test "x$static_yahoo" = "xyes")
AM_CONDITIONAL(STATIC_ZEPHYR, test "x$static_zephyr" = "xyes")
AC_SUBST(STATIC_LINK_LIBS)
AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init(void) { $load_proto },
@@ -1268,7 +1260,7 @@
AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
if test "x$DYNAMIC_PRPLS" = "xall" ; then
- DYNAMIC_PRPLS="bonjour gg irc jabber novell oscar sametime silc simple yahoo zephyr"
+ DYNAMIC_PRPLS="bonjour gg irc jabber novell oscar sametime silc simple zephyr" if test "x$have_meanwhile" != "xyes"; then
DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
@@ -1298,7 +1290,6 @@
silc) dynamic_silc=yes ;;
silc10) dynamic_silc=yes ;;
simple) dynamic_simple=yes ;;
- yahoo) dynamic_yahoo=yes ;;
zephyr) dynamic_zephyr=yes ;;
*) echo "Invalid dynamic protocol $i!!" ; exit 1 ;;
@@ -1785,7 +1776,7 @@
[enable_nss="$enableval"],
-msg_ssl="None. Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!"
+msg_ssl="None. Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!" dnl # Check for GnuTLS if it's specified.
@@ -2196,19 +2187,19 @@
Neither GnuTLS or NSS SSL development headers found.
Use --disable-nss --disable-gnutls if you do not need SSL support.
-Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!
+Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable! elif test "x$looked_for_gnutls" = "xyes" -a "x$force_deps" = "xyes" ; then
GnuTLS SSL development headers not found.
Use --disable-gnutls if you do not need SSL support.
-Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
+Novell Groupwise and Google Talk will not work without SSL support. elif test "x$looked_for_nss" = "xyes" -a "x$force_deps" = "xyes" ; then
NSS SSL development headers not found.
Use --disable-nss if you do not need SSL support.
-Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
+Novell Groupwise and Google Talk will not work without SSL support. @@ -2660,7 +2651,6 @@
libpurple/protocols/silc/Makefile
libpurple/protocols/silc10/Makefile
libpurple/protocols/simple/Makefile
- libpurple/protocols/yahoo/Makefile
libpurple/protocols/zephyr/Makefile
--- a/doc/finch.1.in Wed Oct 05 21:14:58 2016 +0200
+++ b/doc/finch.1.in Wed Oct 05 15:10:29 2016 -0500
@@ -30,11 +30,10 @@
\fBfinch\fR is a console-based modular messaging client based on libpurple
-which is capable of connecting to AIM, Yahoo!, XMPP, ICQ, IRC, SILC,
+which is capable of connecting to AIM, XMPP, ICQ, IRC, SILC, Novell GroupWise, Lotus Sametime, Zephyr, Gadu-Gadu, and QQ all at once. It has
many common features found in other clients, as well as many unique features.
-Finch is not endorsed by or affiliated with America Online, ICQ, Microsoft, or
+Finch is not endorsed by or affiliated with America Online, ICQ, or Microsoft. The following options are provided by \fBfinch\fR using the standard GNU
--- a/doc/pidgin.1.in Wed Oct 05 21:14:58 2016 +0200
+++ b/doc/pidgin.1.in Wed Oct 05 15:10:29 2016 -0500
@@ -29,11 +29,10 @@
\fBpidgin\fR is a graphical modular messaging client based on libpurple
-which is capable of connecting to AIM, Yahoo!, XMPP, ICQ, IRC, SILC,
+which is capable of connecting to AIM, XMPP, ICQ, IRC, SILC, Novell GroupWise, Lotus Sametime, Zephyr, Gadu-Gadu, and QQ all at once. It has
many common features found in other clients, as well as many unique features.
-Pidgin is not endorsed by or affiliated with America Online, ICQ, Microsoft, or
+Pidgin is not endorsed by or affiliated with America Online, ICQ, or Microsoft. Pidgin can be extended by plugins written in multiple programming languages and
controlled through DBus or \fBpurple-remote\fR.
--- a/libpurple/account.c Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/account.c Wed Oct 05 15:10:29 2016 -0500
@@ -535,35 +535,6 @@
*********************************************************************/
-migrate_yahoo_japan(PurpleAccount *account)
- /* detect a Yahoo! JAPAN account that existed prior to 2.6.0 and convert it
- * to use the new prpl-yahoojp. Also remove the account-specific settings
- if(purple_strequal(purple_account_get_protocol_id(account), "prpl-yahoo")) {
- if(purple_account_get_bool(account, "yahoojp", FALSE)) {
- const char *serverjp = purple_account_get_string(account, "serverjp", NULL);
- const char *xferjp_host = purple_account_get_string(account, "xferjp_host", NULL);
- g_return_if_fail(serverjp != NULL);
- g_return_if_fail(xferjp_host != NULL);
- purple_account_set_string(account, "server", serverjp);
- purple_account_set_string(account, "xfer_host", xferjp_host);
- purple_account_set_protocol_id(account, "prpl-yahoojp");
- /* these should always be nuked */
- purple_account_remove_setting(account, "yahoojp");
- purple_account_remove_setting(account, "serverjp");
- purple_account_remove_setting(account, "xferjp_host");
migrate_icq_server(PurpleAccount *account)
/* Migrate the login server setting for ICQ accounts. See
@@ -668,9 +639,6 @@
/* we do this here because we need access to account settings to determine
- * if we can/should migrate an old Yahoo! JAPAN account */
- migrate_yahoo_japan(account);
- /* we do this here because we need access to account settings to determine
* if we can/should migrate an ICQ account's server setting */
migrate_icq_server(account);
/* we do this here because we need to do it before the user views the
--- a/libpurple/buddyicon.c Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/buddyicon.c Wed Oct 05 15:10:29 2016 -0500
@@ -1095,23 +1095,6 @@
purple_blist_node_set_string(node, "icon_checksum", hash);
purple_blist_node_remove_setting(node, "avatar_hash");
- PurpleAccount *account = purple_buddy_get_account((PurpleBuddy *)node);
- const char *prpl_id = purple_account_get_protocol_id(account);
- if (g_str_equal(prpl_id, "prpl-yahoo") || g_str_equal(prpl_id, "prpl-yahoojp"))
- int checksum = purple_blist_node_get_int(node, "icon_checksum");
- char *checksum_str = g_strdup_printf("%i", checksum);
- purple_blist_node_remove_setting(node, "icon_checksum");
- purple_blist_node_set_string(node, "icon_checksum", checksum_str);
--- a/libpurple/data/gconf/purple.schemas.in Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/data/gconf/purple.schemas.in Wed Oct 05 15:10:29 2016 -0500
@@ -204,39 +204,5 @@
<long>True if the command used to handle this type of URL should be run in a terminal.</long>
- <key>/schemas/desktop/gnome/url-handlers/ymsgr/enabled</key>
- <applyto>/desktop/gnome/url-handlers/ymsgr/enabled</applyto>
- <default>true</default>
- <short>Whether the specified command should handle "ymsgr" URLs</short>
- <long>True if the command specified in the "command" key should handle "ymsgr" URLs.</long>
- <key>/schemas/desktop/gnome/url-handlers/ymsgr/command</key>
- <applyto>/desktop/gnome/url-handlers/ymsgr/command</applyto>
- <default>purple-url-handler "%s"</default>
- <short>The handler for "ymsgr" URLs</short>
- <long>The command used to handle "ymsgr" URLs, if enabled.</long>
- <key>/schemas/desktop/gnome/url-handlers/ymsgr/needs_terminal</key>
- <applyto>/desktop/gnome/url-handlers/ymsgr/needs_terminal</applyto>
- <default>false</default>
- <short>Run the command in a terminal</short>
- <long>True if the command used to handle this type of URL should be run in a terminal.</long>
--- a/libpurple/plugins/psychic.c Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/plugins/psychic.c Wed Oct 05 15:10:29 2016 -0500
@@ -21,7 +21,7 @@
#define PLUGIN_SUMMARY N_("Psychic mode for incoming conversation")
#define PLUGIN_DESC N_("Causes conversation windows to appear as other" \
" users begin to message you. This works for" \
- " AIM, ICQ, XMPP, Sametime, and Yahoo!")
+ " AIM, ICQ, XMPP, and Sametime") #define PLUGIN_AUTHOR "Christopher O'Brien <siege@preoccupied.net>"
--- a/libpurple/protocols/Makefile.am Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/protocols/Makefile.am Wed Oct 05 15:10:29 2016 -0500
@@ -1,5 +1,5 @@
EXTRA_DIST = Makefile.mingw
-DIST_SUBDIRS = bonjour gg irc jabber novell null oscar sametime silc silc10 simple yahoo zephyr
+DIST_SUBDIRS = bonjour gg irc jabber novell null oscar sametime silc silc10 simple zephyr SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS)
--- a/libpurple/protocols/Makefile.mingw Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/protocols/Makefile.mingw Wed Oct 05 15:10:29 2016 -0500
@@ -8,7 +8,7 @@
include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-SUBDIRS = gg irc jabber novell null oscar sametime silc simple yahoo bonjour
+SUBDIRS = gg irc jabber novell null oscar sametime silc simple bonjour .PHONY: all install clean
--- a/libpurple/protocols/yahoo/Makefile.am Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
-libyahoo_la_LDFLAGS = -module -avoid-version
-libyahoojp_la_LDFLAGS = -module -avoid-version
-st = -DPURPLE_STATIC_PRPL
-noinst_LTLIBRARIES = libymsg.la
-libymsg_la_SOURCES = $(YAHOOSOURCES) libyahoo.c libyahoojp.c
-libymsg_la_CFLAGS = $(AM_CFLAGS)
-pkg_LTLIBRARIES = libymsg.la libyahoo.la libyahoojp.la
-libymsg_la_SOURCES = $(YAHOOSOURCES)
-libymsg_la_LIBADD = $(GLIB_LIBS)
-libyahoo_la_SOURCES = libyahoo.c
-libyahoo_la_LIBADD = libymsg.la
-libyahoojp_la_SOURCES = libyahoojp.c
-libyahoojp_la_LIBADD = libymsg.la
- -I$(top_srcdir)/libpurple \
- -I$(top_builddir)/libpurple \
--- a/libpurple/protocols/yahoo/Makefile.mingw Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-# Description: Makefile for win32 (mingw) version of libyahoo
-PIDGIN_TREE_TOP := ../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-YAHOOJP_TARGET = libyahoojp
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_DIR)
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_PLUGINS_DIR)
- -I$(GTK_TOP)/include/glib-2.0 \
- -I$(GTK_TOP)/lib/glib-2.0/include \
- -I$(PURPLE_TOP)/win32 \
-OBJECTS = $(C_SRC:%.c=%.o)
-YAHOO_C_SRC = libyahoo.c
-YAHOO_OBJECTS = $(YAHOO_C_SRC:%.c=%.o)
-YAHOOJP_C_SRC = libyahoojp.c
-YAHOOJP_OBJECTS = $(YAHOOJP_C_SRC:%.c=%.o)
-include $(PIDGIN_COMMON_RULES)
-.PHONY: all install clean
-all: $(TARGET).dll $(YAHOO_TARGET).dll $(YAHOOJP_TARGET).dll
-install: all $(DLL_INSTALL_DIR)
- cp $(YAHOO_TARGET).dll $(YAHOOJP_TARGET).dll $(DLL_INSTALL_DIR)
- cp $(TARGET).dll $(PURPLE_INSTALL_DIR)
-$(OBJECTS): $(PURPLE_CONFIG_H)
-$(TARGET).dll.a $(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
- $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
-$(YAHOO_TARGET).dll: $(TARGET).dll.a $(YAHOO_OBJECTS)
- $(CC) -shared $(YAHOO_OBJECTS) $(LIB_PATHS) $(LIBS) -lymsg $(DLL_LD_FLAGS) -o $(YAHOO_TARGET).dll
-$(YAHOOJP_TARGET).dll: $(TARGET).dll.a $(YAHOOJP_OBJECTS)
- $(CC) -shared $(YAHOOJP_OBJECTS) $(LIB_PATHS) $(LIBS) -lymsg $(DLL_LD_FLAGS) -o $(YAHOOJP_TARGET).dll
- rm -f $(OBJECTS) $(TARGET).dll $(TARGET).dll.a
- rm -f $(YAHOO_OBJECTS) $(YAHOO_TARGET).dll
- rm -f $(YAHOOJP_OBJECTS) $(YAHOOJP_TARGET).dll
-include $(PIDGIN_COMMON_TARGETS)
--- a/libpurple/protocols/yahoo/libyahoo.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
- * 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
- * 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 "yahoo_aliases.h"
-#include "yahoo_doodle.h"
-#include "yahoo_filexfer.h"
-#include "yahoo_picture.h"
-static PurplePlugin *my_protocol = NULL;
-static void yahoo_register_commands(void)
- purple_cmd_register("join", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoo", yahoopurple_cmd_chat_join,
- _("join <room>: Join a chat room on the Yahoo network"), NULL);
- purple_cmd_register("list", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoo", yahoopurple_cmd_chat_list,
- _("list: List rooms on the Yahoo network"), NULL);
- purple_cmd_register("buzz", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoo", yahoopurple_cmd_buzz,
- _("buzz: Buzz a user to get their attention"), NULL);
- purple_cmd_register("doodle", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoo", yahoo_doodle_purple_cmd_start,
- _("doodle: Request user to start a Doodle session"), NULL);
-static PurpleAccount *find_acct(const char *prpl, const char *acct_id)
- PurpleAccount *acct = NULL;
- /* If we have a specific acct, use it */
- acct = purple_accounts_find(acct_id, prpl);
- if (acct && !purple_account_is_connected(acct))
- } else { /* Otherwise find an active account for the protocol */
- GList *l = purple_accounts_get_all();
- if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
- && purple_account_is_connected(l->data)) {
-/* This may not be the best way to do this, but we find the first key w/o a value
- * and assume it is the buddy name */
-static void yahoo_find_uri_novalue_param(gpointer key, gpointer value, gpointer user_data)
- char **retval = user_data;
- if (value == NULL && *retval == NULL) {
-static gboolean yahoo_uri_handler(const char *proto, const char *cmd, GHashTable *params)
- char *acct_id = g_hash_table_lookup(params, "account");
- if (g_ascii_strcasecmp(proto, "ymsgr"))
- acct = find_acct(purple_plugin_get_id(my_protocol), acct_id);
- /* ymsgr:SendIM?screename&m=The+Message */
- if (!g_ascii_strcasecmp(cmd, "SendIM")) {
- g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &sname);
- char *message = g_hash_table_lookup(params, "m");
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, sname, acct);
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname);
- purple_conversation_present(conv);
- /* Spaces are encoded as '+' */
- g_strdelimit(message, "+", ' ');
- purple_conv_send_confirm(conv, message);
- **If pidgindialogs_im() was in the core, we could use it here.
- * It is all purple_request_* based, but I'm not sure it really belongs in the core
- /* ymsgr:Chat?roomname */
- else if (!g_ascii_strcasecmp(cmd, "Chat")) {
- g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &rname);
- /* This is somewhat hacky, but the params aren't useful after this command */
- g_hash_table_insert(params, g_strdup("room"), g_strdup(rname));
- g_hash_table_insert(params, g_strdup("type"), g_strdup("Chat"));
- serv_join_chat(purple_account_get_connection(acct), params);
- ** Same as above (except that this would have to be re-written using purple_request_*)
- pidgin_blist_joinchat_show(); */
- /* ymsgr:AddFriend?name */
- else if (!g_ascii_strcasecmp(cmd, "AddFriend")) {
- g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &name);
- purple_blist_request_add_buddy(acct, name, NULL, NULL);
-yahoo_get_account_text_table(PurpleAccount *account)
- table = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(table, "login_label", (gpointer)_("Yahoo! ID..."));
-static gboolean yahoo_unload_plugin(PurplePlugin *plugin)
-static PurpleWhiteboardPrplOps yahoo_whiteboard_prpl_ops =
- yahoo_doodle_get_dimensions,
- yahoo_doodle_get_brush,
- yahoo_doodle_set_brush,
- yahoo_doodle_send_draw_list,
-static PurplePluginProtocolInfo prpl_info =
- OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
- NULL, /* user_splits */
- NULL, /* protocol_options */
- {"png,gif,jpeg", 96, 96, 96, 96, 0, PURPLE_ICON_SCALE_SEND},
- NULL, /* change_passwd*/
- NULL, /* add_buddies */
- NULL, /* remove_buddies */
- NULL, /* reject chat invite */
- NULL, /* chat whisper */
- NULL, /* register_user */
- NULL, /* get_cb_info */
- NULL, /* get_cb_away */
- yahoo_update_alias, /* alias_buddy */
- yahoo_change_buddys_group,
- NULL, /* convo_closed */
- purple_normalize_nocase, /* normalize */
- NULL, /* void (*remove_group)(PurpleConnection *gc, const char *group);*/
- NULL, /* char *(*get_cb_real_name)(PurpleConnection *gc, int id, const char *who); */
- NULL, /* set_chat_topic */
- NULL, /* find_blist_chat */
- yahoo_roomlist_get_list,
- yahoo_roomlist_expand_category,
- yahoo_can_receive_file, /* can_receive_file */
- yahoo_offline_message, /* offline_message */
- &yahoo_whiteboard_prpl_ops,
- NULL, /* roomlist_room_serialize */
- NULL, /* unregister_user */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
- yahoo_get_account_text_table, /* get_account_text_table */
- NULL, /* initiate_media */
- NULL, /* get_media_caps */
- NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
-static PurplePluginInfo info =
- PURPLE_PLUGIN_PROTOCOL, /**< type */
- NULL, /**< ui_requirement */
- NULL, /**< dependencies */
- PURPLE_PRIORITY_DEFAULT, /**< priority */
- "prpl-yahoo", /**< id */
- DISPLAY_VERSION, /**< version */
- N_("Yahoo! Protocol Plugin"),
- N_("Yahoo! Protocol Plugin"),
- PURPLE_WEBSITE, /**< homepage */
- yahoo_unload_plugin, /**< unload */
- &prpl_info, /**< extra_info */
-init_plugin(PurplePlugin *plugin)
- PurpleAccountOption *option;
- option = purple_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("File transfer server"), "xfer_host", YAHOO_XFER_HOST);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("File transfer port"), "xfer_port", YAHOO_XFER_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Chat room locale"), "room_list_locale", YAHOO_ROOMLIST_LOCALE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Encoding"), "local_charset", "UTF-8");
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Ignore conference and chatroom invitations"), "ignore_invites", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Use account proxy for HTTP and HTTPS connections"), "proxy_ssl", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Chat room list URL"), "room_list", YAHOO_ROOMLIST_URL);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- yahoo_register_commands();
- purple_signal_connect(purple_get_core(), "uri-handler", plugin,
- PURPLE_CALLBACK(yahoo_uri_handler), NULL);
-PURPLE_INIT_PLUGIN(yahoo, init_plugin, info);
--- a/libpurple/protocols/yahoo/libyahoojp.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
- * 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
- * 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 "yahoo_aliases.h"
-#include "yahoo_doodle.h"
-#include "yahoo_filexfer.h"
-#include "yahoo_picture.h"
-static void yahoojp_register_commands(void)
- purple_cmd_register("join", "s", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoojp", yahoopurple_cmd_chat_join,
- _("join <room>: Join a chat room on the Yahoo network"), NULL);
- purple_cmd_register("list", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
- PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoojp", yahoopurple_cmd_chat_list,
- _("list: List rooms on the Yahoo network"), NULL);
- purple_cmd_register("buzz", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoojp", yahoopurple_cmd_buzz,
- _("buzz: Buzz a user to get their attention"), NULL);
- purple_cmd_register("doodle", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-yahoojp", yahoo_doodle_purple_cmd_start,
- _("doodle: Request user to start a Doodle session"), NULL);
-yahoojp_get_account_text_table(PurpleAccount *account)
- table = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(table, "login_label", (gpointer)_("Yahoo JAPAN ID..."));
-static gboolean yahoojp_unload_plugin(PurplePlugin *plugin)
-static PurpleWhiteboardPrplOps yahoo_whiteboard_prpl_ops =
- yahoo_doodle_get_dimensions,
- yahoo_doodle_get_brush,
- yahoo_doodle_set_brush,
- yahoo_doodle_send_draw_list,
-static PurplePluginProtocolInfo prpl_info =
- OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC,
- NULL, /* user_splits */
- NULL, /* protocol_options */
- {"png,gif,jpeg", 96, 96, 96, 96, 0, PURPLE_ICON_SCALE_SEND},
- NULL, /* change_passwd*/
- NULL, /* add_buddies */
- NULL, /* remove_buddies */
- NULL, /* reject chat invite */
- NULL, /* chat whisper */
- NULL, /* register_user */
- NULL, /* get_cb_info */
- NULL, /* get_cb_away */
- yahoo_update_alias, /* alias_buddy */
- yahoo_change_buddys_group,
- NULL, /* convo_closed */
- purple_normalize_nocase, /* normalize */
- NULL, /* void (*remove_group)(PurpleConnection *gc, const char *group);*/
- NULL, /* char *(*get_cb_real_name)(PurpleConnection *gc, int id, const char *who); */
- NULL, /* set_chat_topic */
- NULL, /* find_blist_chat */
- yahoo_roomlist_get_list,
- yahoo_roomlist_expand_category,
- NULL, /* can_receive_file */
- yahoo_offline_message, /* offline_message */
- &yahoo_whiteboard_prpl_ops,
- NULL, /* roomlist_room_serialize */
- NULL, /* unregister_user */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
- yahoojp_get_account_text_table, /* get_account_text_table */
- NULL, /* initiate_media */
- NULL, /* get_media_caps */
- NULL, /* set_public_alias */
- NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
-static PurplePluginInfo info =
- PURPLE_PLUGIN_PROTOCOL, /**< type */
- NULL, /**< ui_requirement */
- NULL, /**< dependencies */
- PURPLE_PRIORITY_DEFAULT, /**< priority */
- "prpl-yahoojp", /**< id */
- "Yahoo JAPAN", /**< name */
- DISPLAY_VERSION, /**< version */
- N_("Yahoo! JAPAN Protocol Plugin"),
- N_("Yahoo! JAPAN Protocol Plugin"),
- PURPLE_WEBSITE, /**< homepage */
- yahoojp_unload_plugin, /**< unload */
- &prpl_info, /**< extra_info */
-init_plugin(PurplePlugin *plugin)
- PurpleAccountOption *option;
- option = purple_account_option_int_new(_("Pager port"), "port", YAHOO_PAGER_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("File transfer server"), "xfer_host", YAHOOJP_XFER_HOST);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_int_new(_("File transfer port"), "xfer_port", YAHOO_XFER_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Chat room locale"), "room_list_locale", YAHOOJP_ROOMLIST_LOCALE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Encoding"), "local_charset", "UTF-8");
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Ignore conference and chatroom invitations"), "ignore_invites", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_bool_new(_("Use account proxy for HTTP and HTTPS connections"), "proxy_ssl", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- option = purple_account_option_string_new(_("Chat room list URL"), "room_list", YAHOO_ROOMLIST_URL);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
- yahoojp_register_commands();
-PURPLE_INIT_PLUGIN(yahoojp, init_plugin, info);
--- a/libpurple/protocols/yahoo/libymsg.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5513 +0,0 @@
- * 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
- * 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
- * Note: When handling the list of struct yahoo_pair's from an incoming
- * packet the value might not be UTF-8. You should either validate that
- * it is UTF-8 using g_utf8_validate() or use yahoo_string_decode().
-#include "yahoo_aliases.h"
-#include "yahoo_doodle.h"
-#include "yahoo_filexfer.h"
-#include "yahoo_friend.h"
-#include "yahoo_packet.h"
-#include "yahoo_picture.h"
-/* #define YAHOO_DEBUG */
-/* #define TRY_WEBMESSENGER_LOGIN 0 */
-#define PING_TIMEOUT 3600
-#define KEEPALIVE_TIMEOUT 60
-#ifdef TRY_WEBMESSENGER_LOGIN
-static void yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message);
-#endif /* TRY_WEBMESSENGER_LOGIN */
-static gboolean yahoo_is_japan(PurpleAccount *account)
- return purple_strequal(purple_account_get_protocol_id(account), "prpl-yahoojp");
-static void yahoo_update_status(PurpleConnection *gc, const char *name, YahooFriend *f)
- if (!gc || !name || !f || !purple_find_buddy(purple_connection_get_account(gc), name))
- case YAHOO_STATUS_OFFLINE:
- status = YAHOO_STATUS_TYPE_OFFLINE;
- case YAHOO_STATUS_AVAILABLE:
- status = YAHOO_STATUS_TYPE_AVAILABLE;
- status = YAHOO_STATUS_TYPE_BRB;
- case YAHOO_STATUS_BUSY:
- status = YAHOO_STATUS_TYPE_BUSY;
- case YAHOO_STATUS_NOTATHOME:
- status = YAHOO_STATUS_TYPE_NOTATHOME;
- case YAHOO_STATUS_NOTATDESK:
- status = YAHOO_STATUS_TYPE_NOTATDESK;
- case YAHOO_STATUS_NOTINOFFICE:
- status = YAHOO_STATUS_TYPE_NOTINOFFICE;
- case YAHOO_STATUS_ONPHONE:
- status = YAHOO_STATUS_TYPE_ONPHONE;
- case YAHOO_STATUS_ONVACATION:
- status = YAHOO_STATUS_TYPE_ONVACATION;
- case YAHOO_STATUS_OUTTOLUNCH:
- status = YAHOO_STATUS_TYPE_OUTTOLUNCH;
- case YAHOO_STATUS_STEPPEDOUT:
- status = YAHOO_STATUS_TYPE_STEPPEDOUT;
- case YAHOO_STATUS_INVISIBLE: /* this should never happen? */
- status = YAHOO_STATUS_TYPE_INVISIBLE;
- case YAHOO_STATUS_CUSTOM:
- case YAHOO_STATUS_IDLE:
- status = YAHOO_STATUS_TYPE_AVAILABLE;
- status = YAHOO_STATUS_TYPE_AWAY;
- purple_debug_warning("yahoo", "Warning, unknown status %d\n", f->status);
- if (f->status == YAHOO_STATUS_CUSTOM)
- purple_prpl_got_user_status(purple_connection_get_account(gc), name, status, "message",
- yahoo_friend_get_status_message(f), NULL);
- purple_prpl_got_user_status(purple_connection_get_account(gc), name, status, NULL);
- purple_prpl_got_user_idle(purple_connection_get_account(gc), name, TRUE, f->idle);
- purple_prpl_got_user_idle(purple_connection_get_account(gc), name, FALSE, 0);
- purple_prpl_got_user_status(purple_connection_get_account(gc), name, YAHOO_STATUS_TYPE_MOBILE, NULL);
- purple_prpl_got_user_status_deactive(purple_connection_get_account(gc), name, YAHOO_STATUS_TYPE_MOBILE);
-static void yahoo_process_status(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account = purple_connection_get_account(gc);
- gboolean unicode = FALSE;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
- if (!purple_account_get_remember_password(account))
- purple_account_set_password(account, NULL);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
- _("You have signed on from another location"));
- struct yahoo_pair *pair = l->data;
- case 0: /* we won't actually do anything with this */
- case 1: /* we won't actually do anything with this */
- case 8: /* how many online buddies we have */
- case 7: /* the current buddy */
- /* update the previous buddy before changing the variables */
- yahoo_friend_set_status_message(f, yahoo_string_decode(gc, message, unicode));
- yahoo_update_status(gc, name, f);
- if (pair->value && g_utf8_validate(pair->value, -1, NULL)) {
- /* Look ahead to see if we have the federation info about the buddy */
- for (tmplist = l->next; tmplist; tmplist = tmplist->next) {
- struct yahoo_pair *p = tmplist->data;
- fed = strtol(p->value, NULL, 10);
- case YAHOO_FEDERATION_MSN:
- name = fedname = g_strconcat("msn/", name, NULL);
- case YAHOO_FEDERATION_OCS:
- name = fedname = g_strconcat("ocs/", name, NULL);
- case YAHOO_FEDERATION_IBM:
- name = fedname = g_strconcat("ibm/", name, NULL);
- case YAHOO_FEDERATION_NONE:
- f = yahoo_friend_find_or_new(gc, name);
- f->status = strtol(pair->value, NULL, 10);
- if ((f->status >= YAHOO_STATUS_BRB) && (f->status <= YAHOO_STATUS_STEPPEDOUT))
- if (f->status == YAHOO_STATUS_IDLE) {
- /* Idle may have already been set in a more precise way in case 137 */
- if(pkt->service == YAHOO_SERVICE_STATUS_15)
- if (f->status != YAHOO_STATUS_CUSTOM)
- yahoo_friend_set_status_message(f, NULL);
- case 19: /* custom message */
- case 11: /* this is the buddy's session id */
- f->session_id = strtol(pair->value, NULL, 10);
- case 17: /* in chat? */
- case 47: /* is custom status away or not? 2=idle*/
- /* I have no idea what it means when this is
- * set when someone's available, but it doesn't
- if (f->status == YAHOO_STATUS_AVAILABLE)
- f->away = strtol(pair->value, NULL, 10);
- /* Idle may have already been set in a more precise way in case 137 */
- if(pkt->service == YAHOO_SERVICE_STATUS_15)
- case 138: /* when value is 1, either we're not idle, or we are but won't say how long */
- if( (strtol(pair->value, NULL, 10) == 1) && (f->idle) )
- case 137: /* usually idle time in seconds, sometimes login time */
- if (f->status != YAHOO_STATUS_AVAILABLE)
- f->idle = time(NULL) - strtol(pair->value, NULL, 10);
- case 13: /* bitmask, bit 0 = pager, bit 1 = chat, bit 2 = game */
- if (strtol(pair->value, NULL, 10) == 0) {
- f->status = YAHOO_STATUS_OFFLINE;
- purple_prpl_got_user_status(account, name, "offline", NULL);
- purple_prpl_got_user_status_deactive(account, name, YAHOO_STATUS_TYPE_MOBILE);
- f->sms = strtol(pair->value, NULL, 10);
- yahoo_update_status(gc, name, f);
- case 197: /* Avatars */
- decoded = purple_base64_decode(pair->value, &len);
- if (decoded && len > 0) {
- tmp = purple_str_binary_to_ascii(decoded, len);
- purple_debug_info("yahoo", "Got key 197, value = %s\n", tmp);
- case 192: /* Pictures, aka Buddy Icons, checksum */
- /* FIXME: Please, if you know this protocol,
- * FIXME: fix up the strtol() stuff if possible. */
- int cksum = strtol(pair->value, NULL, 10);
- const char *locksum = NULL;
- b = purple_find_buddy(gc->account, name);
- if (!cksum || (cksum == -1)) {
- yahoo_friend_set_buddy_icon_need_request(f, TRUE);
- purple_buddy_icons_set_for_user(gc->account, name, NULL, 0, NULL);
- yahoo_friend_set_buddy_icon_need_request(f, FALSE);
- locksum = purple_buddy_icons_get_checksum_for_user(b);
- if (!locksum || (cksum != strtol(locksum, NULL, 10)))
- yahoo_send_picture_request(gc, name);
- case 16: /* Custom error message */
- char *tmp = yahoo_string_decode(gc, pair->value, TRUE);
- purple_notify_error(gc, NULL, tmp, NULL);
- case 97: /* Unicode status message */
- unicode = !strcmp(pair->value, "1");
- case 244: /* client version number. Yahoo Client Detection */
- if(f && strtol(pair->value, NULL, 10))
- f->version_id = strtol(pair->value, NULL, 10);
- case 241: /* Federated network buddy belongs to */
- break; /* We process this when get '7' */
- purple_debug_warning("yahoo",
- "Unknown status key %d\n", pair->key);
- if (pkt->service == YAHOO_SERVICE_LOGOFF)
- f->status = YAHOO_STATUS_OFFLINE;
- yahoo_friend_set_status_message(f, yahoo_string_decode(gc, message, unicode));
- if (name) /* update the last buddy */
- yahoo_update_status(gc, name, f);
-static void yahoo_do_group_check(PurpleAccount *account, GHashTable *ht, const char *name, const char *group)
- gboolean onlist = FALSE;
- if (g_hash_table_lookup_extended(ht, name, (gpointer *)&oname, (gpointer *)&list))
- g_hash_table_steal(ht, oname);
- list = purple_find_buddies(account, name);
- for (i = list; i; i = i->next) {
- g = purple_buddy_get_group(b);
- if (!purple_utf8_strcasecmp(group, purple_group_get_name(g))) {
- purple_debug_misc("yahoo",
- "Oh good, %s is in the right group (%s).\n", name, group);
- list = g_slist_delete_link(list, i);
- purple_debug_misc("yahoo",
- "Uhoh, %s isn't on the list (or not in this group), adding him to group %s.\n", name, group);
- if (!(g = purple_find_group(group))) {
- g = purple_group_new(group);
- purple_blist_add_group(g, NULL);
- b = purple_buddy_new(account, name, NULL);
- purple_blist_add_buddy(b, NULL, g, NULL);
- oname = g_strdup(name);
- g_hash_table_insert(ht, oname, list);
-static void yahoo_do_group_cleanup(gpointer key, gpointer value, gpointer user_data)
- GSList *list = value, *i;
- for (i = list; i; i = i->next) {
- g = purple_buddy_get_group(b);
- purple_debug_misc("yahoo", "Deleting Buddy %s from group %s.\n", name,
- purple_group_get_name(g));
- purple_blist_remove_buddy(b);
-static char *_getcookie(char *rawcookie)
- if (strlen(rawcookie) < 2)
- tmpcookie = g_strdup(rawcookie+2);
- cookieend = strchr(tmpcookie, ';');
- cookie = g_strdup(tmpcookie);
-static void yahoo_process_cookie(YahooData *yd, char *c)
- yd->cookie_y = _getcookie(c);
- } else if (c[0] == 'T') {
- yd->cookie_t = _getcookie(c);
- purple_debug_info("yahoo", "Unrecognized cookie '%c'\n", c[0]);
- yd->cookies = g_slist_prepend(yd->cookies, g_strdup(c));
-static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- YahooFriend *f = NULL; /* It's your friends. They're going to want you to share your StarBursts. */
- /* But what if you had no friends? */
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free);
- struct yahoo_pair *pair = l->data;
- /* This is always 318 before a group, 319 before the first s/n in a group, 320 before any ignored s/n.
- * It is not sent for s/n's in a group after the first.
- * All ignored s/n's are listed last, so when we see a 320 we clear the group and begin marking the
- * s/n's as ignored. It is always followed by an identical 300 key.
- if (pair->value && !strcmp(pair->value, "320")) {
- /* No longer in any group; this indicates the start of the ignore list. */
- g_free(yd->current_list15_grp);
- yd->current_list15_grp = NULL;
- case 301: /* This is 319 before all s/n's in a group after the first. It is followed by an identical 300. */
- case YAHOO_FEDERATION_MSN:
- norm_bud = g_strconcat("msn/", temp, NULL);
- case YAHOO_FEDERATION_OCS:
- norm_bud = g_strconcat("ocs/", temp, NULL);
- case YAHOO_FEDERATION_IBM:
- norm_bud = g_strconcat("ibm/", temp, NULL);
- case YAHOO_FEDERATION_PBX:
- norm_bud = g_strconcat("pbx/", temp, NULL);
- case YAHOO_FEDERATION_NONE:
- norm_bud = g_strdup(temp);
- if (yd->current_list15_grp) {
- /* This buddy is in a group */
- f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!purple_find_buddy(account, norm_bud)) {
- if (!(g = purple_find_group(yd->current_list15_grp))) {
- g = purple_group_new(yd->current_list15_grp);
- purple_blist_add_group(g, NULL);
- b = purple_buddy_new(account, norm_bud, NULL);
- purple_blist_add_buddy(b, NULL, g, NULL);
- yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp);
- purple_debug_info("yahoo", "Setting federation to %d\n", f->fed);
- f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
- /* set p2p status not connected and no p2p packet sent */
- if(fed == YAHOO_FEDERATION_NONE) {
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
- f->p2p_packet_sent = 0;
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT);
- /* This buddy is on the ignore list (and therefore in no group) */
- purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n",account->username, norm_bud);
- purple_privacy_deny_add(account, norm_bud, 1);
- fed = YAHOO_FEDERATION_NONE;
- case 300: /* This is 318 before a group, 319 before any s/n in a group, and 320 before any ignored s/n. */
- case 65: /* This is the group */
- g_free(yd->current_list15_grp);
- yd->current_list15_grp = yahoo_string_decode(gc, pair->value, FALSE);
- case 7: /* buddy's s/n */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- temp = g_strdup(purple_normalize(account, pair->value));
- purple_debug_warning("yahoo", "yahoo_process_list_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 241: /* user on federated network */
- fed = strtol(pair->value, NULL, 10);
- case 59: /* somebody told cookies come here too, but im not sure */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- yahoo_process_cookie(yd, pair->value);
- purple_debug_warning("yahoo", "yahoo_process_list_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 317: /* Stealth Setting */
- stealth = strtol(pair->value, NULL, 10);
- /* case 242: */ /* this seems related to 241 */
- g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL);
- /* The reporter of ticket #9745 determined that we weren't retrieving the
- * aliases during buddy list retrieval, so we never updated aliases that
- * changed while we were signed off. */
- yahoo_fetch_aliases(gc);
- /* Now that we have processed the buddy list, we can say yahoo has connected */
- purple_connection_set_display_name(gc, purple_normalize(account, purple_account_get_username(account)));
- purple_debug_info("yahoo","Authentication: Connection established\n");
- purple_connection_set_state(gc, PURPLE_CONNECTED);
- if (yd->picture_upload_todo) {
- yahoo_buddy_icon_upload(gc, yd->picture_upload_todo);
- yd->picture_upload_todo = NULL;
- yahoo_set_status(account, purple_account_get_active_status(account));
- g_hash_table_destroy(ht);
-static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
- gboolean got_serv_list = FALSE;
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- char **tmp, **bud, *norm_bud;
- yd->session_id = pkt->id;
- struct yahoo_pair *pair = l->data;
- if (!yd->tmp_serv_blist)
- yd->tmp_serv_blist = g_string_new(pair->value);
- g_string_append(yd->tmp_serv_blist, pair->value);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- if (!yd->tmp_serv_ilist)
- yd->tmp_serv_ilist = g_string_new(pair->value);
- g_string_append(yd->tmp_serv_ilist, pair->value);
- purple_debug_warning("yahoo", "yahoo_process_list "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- yd->profiles = g_strsplit(pair->value, ",", -1);
- purple_debug_warning("yahoo", "yahoo_process_list "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 59: /* cookies, yum */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- yahoo_process_cookie(yd, pair->value);
- purple_debug_warning("yahoo", "yahoo_process_list "
- "got non-UTF-8 string for key %d\n", pair->key);
- case YAHOO_SERVICE_PRESENCE_PERM:
- if (g_utf8_validate(pair->value, -1, NULL)) {
- if (!yd->tmp_serv_plist)
- yd->tmp_serv_plist = g_string_new(pair->value);
- g_string_append(yd->tmp_serv_plist, pair->value);
- purple_debug_warning("yahoo", "yahoo_process_list "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (yd->tmp_serv_blist) {
- ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free);
- lines = g_strsplit(yd->tmp_serv_blist->str, "\n", -1);
- for (tmp = lines; *tmp; tmp++) {
- split = g_strsplit(*tmp, ":", 2);
- if (!split[0] || !split[1]) {
- grp = yahoo_string_decode(gc, split[0], FALSE);
- buddies = g_strsplit(split[1], ",", -1);
- for (bud = buddies; bud && *bud; bud++) {
- if (!g_utf8_validate(*bud, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_list "
- "got non-UTF-8 string for bud\n");
- norm_bud = g_strdup(purple_normalize(account, *bud));
- f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!purple_find_buddy(account, norm_bud)) {
- if (!(g = purple_find_group(grp))) {
- g = purple_group_new(grp);
- purple_blist_add_group(g, NULL);
- b = purple_buddy_new(account, norm_bud, NULL);
- purple_blist_add_buddy(b, NULL, g, NULL);
- yahoo_do_group_check(account, ht, norm_bud, grp);
- /* set p2p status not connected and no p2p packet sent */
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
- f->p2p_packet_sent = 0;
- g_string_free(yd->tmp_serv_blist, TRUE);
- yd->tmp_serv_blist = NULL;
- g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL);
- g_hash_table_destroy(ht);
- if (yd->tmp_serv_ilist) {
- buddies = g_strsplit(yd->tmp_serv_ilist->str, ",", -1);
- for (bud = buddies; bud && *bud; bud++) {
- /* The server is already ignoring the user */
- purple_privacy_deny_add(account, *bud, 1);
- g_string_free(yd->tmp_serv_ilist, TRUE);
- yd->tmp_serv_ilist = NULL;
- ((account->perm_deny != PURPLE_PRIVACY_ALLOW_BUDDYLIST) &&
- (account->perm_deny != PURPLE_PRIVACY_DENY_ALL) &&
- (account->perm_deny != PURPLE_PRIVACY_ALLOW_USERS)))
- account->perm_deny = PURPLE_PRIVACY_DENY_USERS;
- purple_debug_info("yahoo", "%s privacy defaulting to PURPLE_PRIVACY_DENY_USERS.\n",
- if (yd->tmp_serv_plist) {
- buddies = g_strsplit(yd->tmp_serv_plist->str, ",", -1);
- for (bud = buddies; bud && *bud; bud++) {
- f = yahoo_friend_find(gc, *bud);
- purple_debug_info("yahoo", "%s setting presence for %s to PERM_OFFLINE\n",
- account->username, *bud);
- f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
- g_string_free(yd->tmp_serv_plist, TRUE);
- yd->tmp_serv_plist = NULL;
- /* Now that we've got the list, request aliases */
- yahoo_fetch_aliases(gc);
-/* pkt_type is YAHOO_PKT_TYPE_SERVER if pkt arrives from yahoo server, YAHOO_PKT_TYPE_P2P if pkt arrives through p2p */
-static void yahoo_process_notify(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type)
- PurpleAccount *account;
- YahooData *yd = gc->proto_data;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- account = purple_connection_get_account(gc);
- struct yahoo_pair *pair = l->data;
- if (pair->key == 4 || pair->key == 1) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_notify "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_notify "
- "got non-UTF-8 string for key %d\n", pair->key);
- val_11 = strtol(pair->value, NULL, 10);
- fed = strtol(pair->value, NULL, 10);
- /* disconnect the peer if connected through p2p and sends wrong value for session id */
- if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) {
- purple_debug_warning("yahoo","p2p: %s sent us notify with wrong session id. Disconnecting p2p connection to peer\n", from);
- /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
- g_hash_table_remove(yd->peers, from);
- if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))
- && (purple_privacy_check(account, from)))
- case YAHOO_FEDERATION_MSN:
- fed_from = g_strconcat("msn/", from, NULL);
- case YAHOO_FEDERATION_OCS:
- fed_from = g_strconcat("ocs/", from, NULL);
- case YAHOO_FEDERATION_IBM:
- fed_from = g_strconcat("ibm/", from, NULL);
- case YAHOO_FEDERATION_PBX:
- fed_from = g_strconcat("pbx/", from, NULL);
- case YAHOO_FEDERATION_NONE:
- if (stat && *stat == '1')
- serv_got_typing(gc, fed_from, 0, PURPLE_TYPING);
- serv_got_typing_stopped(gc, fed_from);
- } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) {
- PurpleBuddy *bud = purple_find_buddy(account, from);
- purple_debug_warning("yahoo",
- "%s is playing a game, and doesn't want you to know.\n", from);
- f = yahoo_friend_find(gc, from);
- return; /* if they're not on the list, don't bother */
- yahoo_friend_set_game(f, NULL);
- if (stat && *stat == '1') {
- yahoo_friend_set_game(f, game);
- yahoo_update_status(gc, from, f);
- } else if (!g_ascii_strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) {
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, account);
- char *buf = g_strdup_printf(_("%s has sent you a webcam invite, which is not yet supported."), from);
- purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL));
-static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account;
- struct _yahoo_im *sms = NULL;
- char *server_msg = NULL;
- account = purple_connection_get_account(gc);
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- sms = g_new0(struct _yahoo_im, 1);
- sms->from = g_strdup_printf("+%s", pair->value);
- sms->time = time(NULL);
- purple_debug_warning("yahoo", "yahoo_process_sms_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- sms->msg = pair->value;
- g_hash_table_insert(yd->sms_carrier, g_strdup(sms->from), g_strdup(pair->value));
- if (g_utf8_validate(pair->value, -1, NULL)) {
- server_msg = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_sms_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- purple_debug_info("yahoo", "Received a malformed SMS packet!\n");
- if ((int)pkt->status < 0)
- pkt->status = YAHOO_STATUS_DISCONNECTED;
- if (pkt->status == YAHOO_STATUS_DISCONNECTED) {
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms->from, account);
- c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sms->from);
- purple_conversation_write(c, NULL, server_msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_notify_error(gc, NULL, _("Your SMS was not delivered"), NULL);
- if (!sms->from || !sms->msg) {
- m = yahoo_string_decode(gc, sms->msg, sms->utf8);
- serv_got_im(gc, sms->from, m, 0, sms->time);
-/* pkt_type is YAHOO_PKT_TYPE_SERVER if pkt arrives from yahoo server, YAHOO_PKT_TYPE_P2P if pkt arrives through p2p */
-static void yahoo_process_message(PurpleConnection *gc, struct yahoo_packet *pkt, yahoo_pkt_type pkt_type)
- PurpleAccount *account;
- YahooData *yd = gc->proto_data;
- struct _yahoo_im *im = NULL;
- account = purple_connection_get_account(gc);
- if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) {
- /* messages are received with status YAHOO_STATUS_OFFLINE in case of p2p */
- struct yahoo_pair *pair = l->data;
- if (pair->key == 4 || pair->key == 1) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- im = g_new0(struct _yahoo_im, 1);
- list = g_slist_append(list, im);
- im->from = pair->value;
- im->fed = YAHOO_FEDERATION_NONE;
- im->fed_from = g_strdup(im->from);
- purple_debug_warning("yahoo", "yahoo_process_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (im && pair->key == 5)
- im->active_id = pair->value;
- im->utf8 = strtol(pair->value, NULL, 10);
- im->time = strtol(pair->value, NULL, 10);
- im->buddy_icon = strtol(pair->value, NULL, 10);
- if (im && pair->key == 241) {
- im->fed = strtol(pair->value, NULL, 10);
- case YAHOO_FEDERATION_MSN:
- im->fed_from = g_strconcat("msn/",im->from, NULL);
- case YAHOO_FEDERATION_OCS:
- im->fed_from = g_strconcat("ocs/",im->from, NULL);
- case YAHOO_FEDERATION_IBM:
- im->fed_from = g_strconcat("ibm/",im->from, NULL);
- case YAHOO_FEDERATION_PBX:
- im->fed_from = g_strconcat("pbx/",im->from, NULL);
- case YAHOO_FEDERATION_NONE:
- im->fed_from = g_strdup(im->from);
- purple_debug_info("yahoo", "Message from federated (%d) buddy %s.\n", im->fed, im->fed_from);
- if (im && (pair->key == 11)) {
- /* disconnect the peer if connected through p2p and sends wrong value for session id */
- if( (im->fed == YAHOO_FEDERATION_NONE) && (pkt_type == YAHOO_PKT_TYPE_P2P)
- && (yd->session_id != strtol(pair->value, NULL, 10)) )
- purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->fed_from);
- /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
- g_hash_table_remove(yd->peers, im->fed_from);
- return; /* Not sure whether we should process remaining IMs in this packet */
- if (im && pair->key == 63 && g_utf8_validate(pair->value, -1, NULL))
- /* Check for the Doodle IMV, no IMvironment for federated buddies */
- if (im->from != NULL && im->fed == YAHOO_FEDERATION_NONE)
- g_hash_table_replace(yd->imvironments, g_strdup(im->from), g_strdup(pair->value));
- if (strstr(pair->value, "doodle;") != NULL)
- if (!purple_privacy_check(account, im->from)) {
- purple_debug_info("yahoo", "Doodle request from %s dropped.\n",
- /* I'm not sure the following ever happens -DAA */
- wb = purple_whiteboard_get_session(account, im->from);
- /* If a Doodle session doesn't exist between this user */
- wb = purple_whiteboard_create(account, im->from,
- DOODLE_STATE_REQUESTED);
- ds->imv_key = g_strdup(pair->value);
- yahoo_doodle_command_send_request(gc, im->from, pair->value);
- yahoo_doodle_command_send_ready(gc, im->from, pair->value);
- } else if (pkt->status == 2) {
- purple_notify_error(gc, NULL,
- _("Your Yahoo! message did not get sent."), NULL);
- for (l = list; l; l = l->next) {
- if (!im->fed_from || !im->msg) {
- if (!purple_privacy_check(account, im->fed_from)) {
- purple_debug_info("yahoo", "Message from %s dropped.\n", im->fed_from);
- * TODO: Is there anything else we should check when determining whether
- * we should send an acknowledgement?
- /* Send acknowledgement. If we don't do this then the official
- * Yahoo Messenger client for Windows will send us the same
- * message 7 seconds later as an offline message. This is true
- * for at least version 9.0.0.2162 on Windows XP. */
- struct yahoo_packet *pkt2;
- pkt2 = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_ACK,
- YAHOO_STATUS_AVAILABLE, pkt->id);
- yahoo_packet_hash(pkt2, "ssisii",
- 1, im->active_id, /* May not always be the connection's display name */
- yahoo_packet_send_and_free(pkt2, yd);
- m = yahoo_string_decode(gc, im->msg, im->utf8);
- /* This may actually not be necessary, but it appears
- * that at least at one point some clients were sending
- * "\r\n" as line delimiters, so we want to avoid double
- m2 = purple_strreplace(m, "\r\n", "\n");
- purple_util_chrreplace(m, '\r', '\n');
- if (!strcmp(m, "<ding>")) {
- username = g_markup_escape_text(im->fed_from, -1);
- purple_prpl_got_attention(gc, username, YAHOO_BUZZ);
- m2 = yahoo_codes_to_html(m);
- serv_got_im(gc, im->fed_from, m2, 0, im->time);
- /* Official clients don't share buddy images with federated buddies */
- if (im->fed == YAHOO_FEDERATION_NONE) {
- if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) {
- if (yahoo_friend_get_buddy_icon_need_request(f)) {
- yahoo_send_picture_request(gc, im->from);
- yahoo_friend_set_buddy_icon_need_request(f, FALSE);
-static void yahoo_process_sysmessage(PurpleConnection *gc, struct yahoo_packet *pkt)
- char *prim, *me = NULL, *msg = NULL;
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_sysmessage "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_sysmessage "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (!msg || !g_utf8_validate(msg, -1, NULL))
- prim = g_strdup_printf(_("Yahoo! system message for %s:"),
- me?me:purple_connection_get_display_name(gc));
- purple_notify_info(NULL, NULL, prim, msg);
-struct yahoo_add_request {
-yahoo_buddy_add_authorize_cb(gpointer data)
- struct yahoo_add_request *add_req = data;
- struct yahoo_packet *pkt;
- YahooData *yd = add_req->gc->proto_data;
- const char *who = add_req->who;
- pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssiii",
- yahoo_packet_hash(pkt, "ssii",
- yahoo_packet_send_and_free(pkt, yd);
-yahoo_buddy_add_deny_cb(struct yahoo_add_request *add_req, const char *msg)
- YahooData *yd = add_req->gc->proto_data;
- struct yahoo_packet *pkt;
- char *encoded_msg = NULL;
- const char *who = add_req->who;
- encoded_msg = yahoo_string_encode(add_req->gc, msg, NULL);
- pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- who += 4; /* Skip fed identifier (msn|ocs|ibm)/' */
- yahoo_packet_hash(pkt, "ssiiiis",
- 14, encoded_msg ? encoded_msg : "");
- yahoo_packet_hash(pkt, "ssiiis",
- 14, encoded_msg ? encoded_msg : "");
- yahoo_packet_send_and_free(pkt, yd);
-yahoo_buddy_add_deny_noreason_cb(struct yahoo_add_request *add_req, const char*msg)
- yahoo_buddy_add_deny_cb(add_req, NULL);
-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,
-static void yahoo_buddy_denied_our_add(PurpleConnection *gc, const char *who, const char *reason)
- YahooData *yd = gc->proto_data;
- char *msg2 = yahoo_string_decode(gc, reason, FALSE);
- notify_msg = g_strdup_printf(_("%s has (retroactively) denied your request to add them to your list for the following reason: %s."), who, msg2);
- notify_msg = g_strdup_printf(_("%s has (retroactively) denied your request to add them to your list."), who);
- purple_notify_info(gc, NULL, _("Add buddy rejected"), notify_msg);
- g_hash_table_remove(yd->friends, who);
- purple_prpl_got_user_status(purple_connection_get_account(gc), who, "offline", NULL); /* FIXME: make this set not on list status instead */
- /* TODO: Shouldn't we remove the buddy from our local list? */
-static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *pkt) {
- PurpleAccount *account;
- const char *msg = NULL;
- account = purple_connection_get_account(gc);
- /* Buddy authorized/declined our addition */
- if (pkt->status == 1) {
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- response = strtol(pair->value, NULL, 10);
- fed = strtol(pair->value, NULL, 10);
- case YAHOO_FEDERATION_MSN:
- who = g_strconcat("msn/", temp, NULL);
- case YAHOO_FEDERATION_OCS:
- who = g_strconcat("ocs/", temp, NULL);
- case YAHOO_FEDERATION_IBM:
- who = g_strconcat("ibm/", temp, NULL);
- case YAHOO_FEDERATION_NONE:
- if (response == 1) /* Authorized */
- purple_debug_info("yahoo", "Received authorization from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
- else if (response == 2) { /* Declined */
- purple_debug_info("yahoo", "Received authorization decline from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
- yahoo_buddy_denied_our_add(gc, who, msg);
- purple_debug_error("yahoo", "Received unknown authorization response of %d from buddy '%s'.\n", response, who ? who : "(Unknown Buddy)");
- /* Buddy requested authorization to add us. */
- else if (pkt->status == 3) {
- struct yahoo_add_request *add_req;
- const char *firstname = NULL, *lastname = NULL;
- add_req = g_new0(struct yahoo_add_request, 1);
- add_req->fed = YAHOO_FEDERATION_NONE;
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- add_req->id = g_strdup(pair->value);
- purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- firstname = pair->value;
- purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- add_req->fed = strtol(pair->value, NULL, 10);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- lastname = pair->value;
- purple_debug_warning("yahoo", "yahoo_buddy_auth_req_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- switch (add_req->fed) {
- case YAHOO_FEDERATION_MSN:
- add_req->who = g_strconcat("msn/", temp, NULL);
- case YAHOO_FEDERATION_OCS:
- add_req->who = g_strconcat("ocs/", temp, NULL);
- case YAHOO_FEDERATION_IBM:
- add_req->who = g_strconcat("ibm/", temp, NULL);
- case YAHOO_FEDERATION_NONE:
- add_req->who = g_strdup(temp);
- if (add_req->id && add_req->who) {
- char *alias = NULL, *dec_msg = NULL;
- if (!purple_privacy_check(account, add_req->who))
- purple_debug_misc("yahoo", "Auth. request from %s dropped and automatically denied due to privacy settings!\n",
- yahoo_buddy_add_deny_cb(add_req, NULL);
- dec_msg = yahoo_string_decode(gc, msg, FALSE);
- if (firstname && lastname)
- alias = g_strdup_printf("%s %s", firstname, lastname);
- alias = g_strdup(firstname);
- alias = g_strdup(lastname);
- /* DONE! this is almost exactly the same as what MSN does,
- * this should probably be moved to the core.
- purple_account_request_authorization(account, add_req->who, add_req->id,
- purple_find_buddy(account, add_req->who) != NULL,
- yahoo_buddy_add_authorize_cb,
- yahoo_buddy_add_deny_reason_cb,
- purple_debug_error("yahoo", "Received authorization of unknown status (%d).\n", pkt->status);
-/* I don't think this happens anymore in Version 15 */
-static void yahoo_buddy_added_us(PurpleConnection *gc, struct yahoo_packet *pkt) {
- PurpleAccount *account;
- struct yahoo_add_request *add_req;
- account = purple_connection_get_account(gc);
- add_req = g_new0(struct yahoo_add_request, 1);
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- add_req->id = g_strdup(pair->value);
- purple_debug_warning("yahoo", "yahoo_buddy_added_us "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- add_req->who = g_strdup(pair->value);
- purple_debug_warning("yahoo", "yahoo_buddy_added_us "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 15: /* time, for when they add us and we're offline */
- if (add_req->id && add_req->who) {
- if (!purple_privacy_check(account, add_req->who)) {
- purple_debug_misc("yahoo", "Auth. request from %s dropped and automatically denied due to privacy settings!\n",
- yahoo_buddy_add_deny_cb(add_req, NULL);
- dec_msg = yahoo_string_decode(gc, msg, FALSE);
- /* DONE! this is almost exactly the same as what MSN does,
- * this should probably be moved to the core.
- purple_account_request_authorization(account, add_req->who, add_req->id,
- purple_find_buddy(account,add_req->who) != NULL,
- yahoo_buddy_add_authorize_cb,
- yahoo_buddy_add_deny_reason_cb, add_req);
-/* I have no idea if this every gets called in version 15 */
-static void yahoo_buddy_denied_our_add_old(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_buddy_denied_our_add_old "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_buddy_denied_our_add_old "
- "got non-UTF-8 string for key %d\n", pair->key);
- yahoo_buddy_denied_our_add(gc, who, msg);
-static void yahoo_process_contact(PurpleConnection *gc, struct yahoo_packet *pkt)
- yahoo_process_status(gc, pkt);
- yahoo_buddy_added_us(gc, pkt);
- yahoo_buddy_denied_our_add_old(gc, pkt);
-#define OUT_CHARSET "utf-8"
-static char *yahoo_decode(const char *text)
- char *converted = NULL;
- n = new = g_malloc(strlen (text) + 1);
- end = text + strlen(text);
- for (p = text; p < end; p++, n++) {
- if (p[1] >= '0' && p[1] <= '7') {
- for (i = 0, k = 0; k < 3; k += 1) {
- if (c < '0' || c > '7') break;
- } else { /* bug 959248 */
- /* If we see a \ not followed by an octal number,
- * it means that it is actually a \\ with one \
- * already eaten by some unknown function.
- * This is arguably broken.
- * I think wing is wrong here, there is no function
- * called that I see that could have done it. I guess
- * it is just really sending single \'s. That's yahoo
- if (strstr(text, "\033$B"))
- converted = g_convert(new, n - new, OUT_CHARSET, "iso-2022-jp", NULL, NULL, NULL);
- converted = g_convert(new, n - new, OUT_CHARSET, "iso-8859-1", NULL, NULL, NULL);
-static void yahoo_process_mail(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- const char *who = NULL;
- const char *email = NULL;
- const char *subj = NULL;
- const char *yahoo_mail_url = (yd->jp? YAHOOJP_MAIL_URL: YAHOO_MAIL_URL);
- if (!purple_account_get_check_mail(account))
- struct yahoo_pair *pair = l->data;
- count = strtol(pair->value, NULL, 10);
- else if (pair->key == 43) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_mail "
- "got non-UTF-8 string for key %d\n", pair->key);
- } else if (pair->key == 42) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_mail "
- "got non-UTF-8 string for key %d\n", pair->key);
- } else if (pair->key == 18) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_mail "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (who && subj && email && *email) {
- char *dec_who = yahoo_decode(who);
- char *dec_subj = yahoo_decode(subj);
- char *from = g_strdup_printf("%s (%s)", dec_who, email);
- purple_notify_email(gc, dec_subj, from, purple_account_get_username(account),
- yahoo_mail_url, NULL, NULL);
- } else if (count > 0) {
- const char *tos[2] = { purple_account_get_username(account) };
- const char *urls[2] = { yahoo_mail_url };
- purple_notify_emails(gc, count, FALSE, NULL, NULL, tos, urls,
-/* We use this structure once while we authenticate */
-/* This is the y64 alphabet... it's like base64, but has a . and a _ */
-static const char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
-/* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function
- * in util.c, but it is different from the one yahoo uses */
-static void to_y64(char *out, const unsigned char *in, gsize inlen)
- /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
- for (; inlen >= 3; inlen -= 3)
- *out++ = base64digits[in[0] >> 2];
- *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
- *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
- *out++ = base64digits[in[2] & 0x3f];
- unsigned char fragment;
- *out++ = base64digits[in[0] >> 2];
- fragment = (in[0] << 4) & 0x30;
- fragment |= in[1] >> 4;
- *out++ = base64digits[fragment];
- *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c];
-static void yahoo_auth16_stage3(PurpleConnection *gc, const char *crypt)
- YahooData *yd = gc->proto_data;
- PurpleAccount *account = purple_connection_get_account(gc);
- const char *name = purple_normalize(account, purple_account_get_username(account));
- PurpleCipher *md5_cipher;
- PurpleCipherContext *md5_ctx;
- gchar base64_string[25];
- struct yahoo_packet *pkt;
- purple_debug_info("yahoo","Authentication: In yahoo_auth16_stage3\n");
- g_return_if_fail(crypt != NULL);
- md5_cipher = purple_ciphers_find_cipher("md5");
- md5_ctx = purple_cipher_context_new(md5_cipher, NULL);
- purple_cipher_context_append(md5_ctx, (guchar *)crypt, strlen(crypt));
- purple_cipher_context_digest(md5_ctx, sizeof(md5_digest), md5_digest, NULL);
- to_y64(base64_string, md5_digest, 16);
- purple_debug_info("yahoo", "yahoo status: %d\n", yd->current_status);
- pkt = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->current_status, yd->session_id);
- if(yd->cookie_b) { /* send B cookie if we have it */
- yahoo_packet_hash(pkt, "ssssssssss",
- 244, yd->jp ? YAHOOJP_CLIENT_VERSION_ID : YAHOO_CLIENT_VERSION_ID,
- 98, purple_account_get_string(account, "room_list_locale", yd->jp ? "jp" : "us"),
- 135, yd->jp ? YAHOOJP_CLIENT_VERSION : YAHOO_CLIENT_VERSION);
- } else { /* don't try to send an empty B cookie - the server will be mad */
- yahoo_packet_hash(pkt, "sssssssss",
- 244, yd->jp ? YAHOOJP_CLIENT_VERSION_ID : YAHOO_CLIENT_VERSION_ID,
- 98, purple_account_get_string(account, "room_list_locale", yd->jp ? "jp" : "us"),
- 135, yd->jp ? YAHOOJP_CLIENT_VERSION : YAHOO_CLIENT_VERSION);
- if (yd->picture_checksum)
- yahoo_packet_hash_int(pkt, 192, yd->picture_checksum);
- yahoo_packet_send_and_free(pkt, yd);
- purple_cipher_context_destroy(md5_ctx);
-static gchar *yahoo_auth16_get_cookie_b(gchar *headers)
- gchar **splits = g_strsplit(headers, "\r\n", -1);
- gchar *tmp = NULL, *tmp2 = NULL, *sem = NULL;
- int elements = g_strv_length(splits), i;
- for(i = 0; i < elements; i++) {
- if(g_ascii_strncasecmp(splits[i], "Set-Cookie: B=", 14) == 0) {
- sem = strchr(tmp, ';');
- tmp2 = g_strndup(tmp, sem - tmp);
- purple_debug_info("yahoo", "Got needed part of B cookie: %s\n",
- tmp2 ? tmp2 : "(null)");
-static void yahoo_auth16_stage2(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
- struct yahoo_auth_data *auth_data = user_data;
- PurpleConnection *gc = auth_data->gc;
- YahooData *yd = purple_connection_get_protocol_data(gc);
- purple_debug_info("yahoo","Authentication: In yahoo_auth16_stage2\n");
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL) {
- purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
- g_free(auth_data->seed);
- else if (len > 0 && ret_data && *ret_data) {
- gchar **splits = g_strsplit(ret_data, "\r\n\r\n", -1), **split_data = NULL;
- if(g_strv_length(splits) > 1) {
- yd->cookie_b = yahoo_auth16_get_cookie_b(splits[0]);
- split_data = g_strsplit(splits[1], "\r\n", -1);
- totalelements = g_strv_length(split_data);
- if (totalelements >= 4) {
- for(i = 0; i < totalelements; i++) {
- /* I'm not exactly a fan of the magic numbers, but it's obvious,
- * so no sense in wasting a bajillion vars or calls to strlen */
- if(g_ascii_isdigit(split_data[i][0])) {
- /* if the current line and the next line both start with numbers,
- * the current line is the length of the body, so skip. If not,
- * then the current line is the response code from the login process. */
- if(!g_ascii_isdigit(split_data[i + 1][0])) {
- response_no = strtol(split_data[i], NULL, 10);
- purple_debug_info("yahoo", "Got auth16 stage 2 response code: %d\n",
- } else if(strncmp(split_data[i], "crumb=", 6) == 0) {
- crumb = g_strdup(&split_data[i][6]);
- if(purple_debug_is_unsafe())
- purple_debug_info("yahoo", "Got crumb: %s\n", crumb);
- } else if(strncmp(split_data[i], "Y=", 2) == 0) {
- yd->cookie_y = g_strdup(&split_data[i][2]);
- if(purple_debug_is_unsafe())
- purple_debug_info("yahoo", "Got Y cookie: %s\n", yd->cookie_y);
- } else if(strncmp(split_data[i], "T=", 2) == 0) {
- yd->cookie_t = g_strdup(&split_data[i][2]);
- if(purple_debug_is_unsafe())
- purple_debug_info("yahoo", "Got T cookie: %s\n", yd->cookie_t);
- g_strfreev(split_data);
- /* Some error in the login process */
- PurpleConnectionError error;
- char *error_reason = NULL;
- /* Some error in the received stream */
- error_reason = g_strdup(_("Received invalid data"));
- error = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- error_reason = g_strdup(_("Unknown error"));
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- /* if we have everything we need, why not try to login irrespective of response */
- if((crumb != NULL) && (yd->cookie_y != NULL) && (yd->cookie_t != NULL)) {
- try_login_on_error = TRUE;
- error_reason = g_strdup(_("Unknown error"));
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- purple_debug_error("yahoo", "Authentication error: %s. "
- "Code %d\n", error_reason, response_no);
- purple_connection_error_reason(gc, error, error_reason);
- g_free(auth_data->seed);
- crypt = g_strconcat(crumb, auth_data->seed, NULL);
- yahoo_auth16_stage3(gc, crypt);
- g_free(auth_data->seed);
-static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
- struct yahoo_auth_data *auth_data = user_data;
- PurpleConnection *gc = auth_data->gc;
- YahooData *yd = purple_connection_get_protocol_data(gc);
- purple_debug_info("yahoo","Authentication: In yahoo_auth16_stage1_cb\n");
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL) {
- purple_debug_error("yahoo", "Login Failed, unable to retrieve login url: %s\n", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
- g_free(auth_data->seed);
- else if (len > 0 && ret_data && *ret_data) {
- PurpleAccount *account = purple_connection_get_account(gc);
- gchar **split_data = g_strsplit(ret_data, "\r\n", -1);
- totalelements = g_strv_length(split_data);
- if(totalelements == 1) { /* Received an error code */
- response_no = strtol(split_data[0], NULL, 10);
- } else if(totalelements == 2 || totalelements == 3 ) { /* received valid data */
- response_no = strtol(split_data[0], NULL, 10);
- token = g_strdup(split_data[1] + strlen("ymsgr="));
- } else { /* It looks like a transparent proxy has returned a document we don't want */
- g_strfreev(split_data);
- /* Some error in the login process */
- PurpleConnectionError error;
- /* Some error in the received stream */
- error_reason = g_strdup(_("Received invalid data"));
- error = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- /* Password incorrect */
- /* Set password to NULL. Avoids account locking. Brings dialog to enter password if clicked on Re-enable account */
- if (!purple_account_get_remember_password(account))
- purple_account_set_password(account, NULL);
- error_reason = g_strdup(_("Incorrect password"));
- error = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- /* security lock from too many failed login attempts */
- error_reason = g_strdup(_("Account locked: Too many failed login "
- "attempts. Logging into the Yahoo! website may fix this."));
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- /* the username does not exist */
- error_reason = g_strdup(_("Username does not exist"));
- error = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
- /* indicates a lock of some description */
- error_reason = g_strdup(_("Account locked: Unknown reason. Logging "
- "into the Yahoo! website may fix this."));
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- /* indicates a lock due to logging in too frequently */
- error_reason = g_strdup(_("Account locked: You have been logging in too "
- "frequently. Wait a few minutes before trying to connect "
- "again. Logging into the Yahoo! website may help."));
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- /* username or password missing */
- error_reason = g_strdup(_("Username or password missing"));
- error = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- error_reason = g_strdup_printf(_("Unknown error (%d)"), response_no);
- error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- purple_debug_error("yahoo", "Authentication error: %s. Code %d\n",
- error_reason, response_no);
- purple_connection_error_reason(gc, error, error_reason);
- g_free(auth_data->seed);
- /* OK to login, correct information provided */
- PurpleUtilFetchUrlData *url_data = NULL;
- gboolean yahoojp = yahoo_is_japan(account);
- gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
- url = g_strdup_printf(yahoojp ? YAHOOJP_LOGIN_URL : YAHOO_LOGIN_URL, token);
- url_data = purple_util_fetch_url_request_len_with_account(
- proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT,
- TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-static void yahoo_auth16_stage1(PurpleConnection *gc, const char *seed)
- YahooData *yd = purple_connection_get_protocol_data(gc);
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleUtilFetchUrlData *url_data = NULL;
- struct yahoo_auth_data *auth_data = NULL;
- char *encoded_username;
- char *encoded_password;
- gboolean yahoojp = yahoo_is_japan(account);
- gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
- purple_debug_info("yahoo", "Authentication: In yahoo_auth16_stage1\n");
- if(!purple_ssl_is_supported()) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable"));
- auth_data = g_new0(struct yahoo_auth_data, 1);
- auth_data->seed = g_strdup(seed);
- encoded_username = g_strdup(purple_url_encode(purple_account_get_username(purple_connection_get_account(gc))));
- encoded_password = g_strdup(purple_url_encode(purple_connection_get_password(gc)));
- url = g_strdup_printf(yahoojp ? YAHOOJP_TOKEN_URL : YAHOO_TOKEN_URL,
- encoded_username, encoded_password, purple_url_encode(seed));
- g_free(encoded_password);
- g_free(encoded_username);
- url_data = purple_util_fetch_url_request_len_with_account(
- proxy_ssl ? account : NULL, url, TRUE,
- YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
- yahoo_auth16_stage1_cb, auth_data);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-static void yahoo_process_auth(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_pair *pair = l->data;
- /* (pair->key == 1) -> sn */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_auth "
- "got non-UTF-8 string for key %d\n", pair->key);
- } else if (pair->key == 13) {
- /* used to be for really old auth routine, dont support now */
- case 2: /* Yahoo ver 16 authentication */
- yahoo_auth16_stage1(gc, seed);
- GHashTable *ui_info = purple_core_get_ui_info();
- buf = g_strdup_printf(_("The Yahoo server has requested the use of an unrecognized "
- "authentication method. You will probably not be able "
- "to successfully sign on to Yahoo. Check %s for updates."),
- ((ui_info && g_hash_table_lookup(ui_info, "website")) ? (char *)g_hash_table_lookup(ui_info, "website") : PURPLE_WEBSITE));
- purple_notify_error(gc, "", _("Failed Yahoo! Authentication"),
- yahoo_auth16_stage1(gc, seed); /* Can't hurt to try it anyway. */
-static void ignore_buddy(PurpleBuddy *buddy) {
- PurpleAccount *account;
- group = purple_buddy_get_group(buddy);
- name = g_strdup(purple_buddy_get_name(buddy));
- account = purple_buddy_get_account(buddy);
- purple_debug_info("yahoo", "blist: Removing '%s' from buddy list.\n", name);
- purple_account_remove_buddy(account, buddy, group);
- purple_blist_remove_buddy(buddy);
- serv_add_deny(purple_account_get_connection(account), name);
-static void keep_buddy(PurpleBuddy *b)
- purple_privacy_deny_remove(purple_buddy_get_account(b),
- purple_buddy_get_name(b), 1);
-static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt) {
- gboolean ignore = TRUE;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_ignore "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* 1 == ignore, 2 == unignore */
- ignore = (strtol(pair->value, NULL, 10) == 1);
- status = strtol(pair->value, NULL, 10);
- * 2 - already in ignore list, could not add
- * 3 - not in ignore list, could not delete
- * 12 - is a buddy, could not add (and possibly also a not-in-ignore list condition?)
- purple_debug_info("yahoo", "Server reported \"is a buddy\" for %s while %s",
- who, (ignore ? "ignoring" : "unignoring"));
- b = purple_find_buddy(gc->account, who);
- g_snprintf(buf, sizeof(buf), _("You have tried to ignore %s, but the "
- "user is on your buddy list. Clicking \"Yes\" "
- "will remove and ignore the buddy."), who);
- purple_request_yes_no(gc, NULL, _("Ignore buddy?"), buf, 0,
- gc->account, who, NULL,
- G_CALLBACK(ignore_buddy),
- G_CALLBACK(keep_buddy));
- purple_debug_info("yahoo", "Server reported that %s is already in the ignore list.\n",
- purple_debug_info("yahoo", "Server reported that %s is not in the ignore list; could not delete\n",
-static void yahoo_process_authresp(PurpleConnection *gc, struct yahoo_packet *pkt)
-#ifdef TRY_WEBMESSENGER_LOGIN
- YahooData *yd = gc->proto_data;
-#endif /* TRY_WEBMESSENGER_LOGIN */
- PurpleAccount *account = gc->account;
- PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- struct yahoo_pair *pair = l->data;
- err = strtol(pair->value, NULL, 10);
- else if (pair->key == 20) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_authresp "
- "got non-UTF-8 string for key %d\n", pair->key);
- msg = g_strdup(_("Unknown error"));
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("Username does not exist"));
- reason = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
-#ifdef TRY_WEBMESSENGER_LOGIN
- PurpleUtilFetchUrlData *url_data;
- purple_input_remove(gc->inpa);
- url_data = purple_util_fetch_url(WEBMESSENGER_URL, TRUE,
- "Purple/" VERSION, FALSE, yahoo_login_page_cb, gc);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-#endif /* TRY_WEBMESSENGER_LOGIN */
- if (!purple_account_get_remember_password(account))
- purple_account_set_password(account, NULL);
- msg = g_strdup(_("Invalid username or password"));
- reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- msg = g_strdup(_("Your account has been locked due to too many failed login attempts."
- " Please try logging into the Yahoo! website."));
- reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- /* See #9660. As much as we know, reconnecting shouldn't hurt */
- purple_debug_info("yahoo", "Got error 52, Set to autoreconnect\n");
- msg = g_strdup(_("Unknown error 52. Reconnecting should fix this."));
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("Error 1013: The username you have entered is invalid."
- " The most common cause of this error is entering your email"
- " address instead of your Yahoo! ID."));
- reason = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
- msg = g_strdup_printf(_("Unknown error number %d. Logging into the Yahoo! website may fix this."), err);
- fullmsg = g_strdup_printf("%s\n%s", msg, url);
- fullmsg = g_strdup(msg);
- purple_connection_error_reason(gc, reason, fullmsg);
-static void yahoo_process_addbuddy(PurpleConnection *gc, struct yahoo_packet *pkt)
- YahooData *yd = gc->proto_data;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- struct yahoo_pair *pair = l->data;
- err = strtol(pair->value, NULL, 10);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_addbuddy "
- "got non-UTF-8 string for key %d\n", pair->key);
- fed = strtol(pair->value, NULL, 10);
- case YAHOO_FEDERATION_MSN:
- who = g_strconcat("msn/", temp, NULL);
- case YAHOO_FEDERATION_OCS:
- who = g_strconcat("ocs/", temp, NULL);
- case YAHOO_FEDERATION_IBM:
- who = g_strconcat("ibm/", temp, NULL);
- case YAHOO_FEDERATION_NONE:
- if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */
- f = yahoo_friend_find_or_new(gc, who);
- yahoo_update_status(gc, who, f);
- if( !g_hash_table_lookup(yd->peers, who) ) {
- /* we are not connected as client, so set friend to not connected */
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT);
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
- f->p2p_packet_sent = 0;
- else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT);
- decoded_group = yahoo_string_decode(gc, group, FALSE);
- buf = g_strdup_printf(_("Unable to add buddy %s to group %s to the server list on account %s."),
- who, decoded_group, purple_connection_get_display_name(gc));
- if (!purple_conv_present_error(who, purple_connection_get_account(gc), buf))
- purple_notify_error(gc, NULL, _("Unable to add buddy to server list"), buf);
-/* write pkt to the source */
-static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt)
- /*build the raw packet and send it to the host*/
- pkt_len = yahoo_packet_build(pkt, 0, 0, 0, &raw_packet);
- written = write(source, raw_packet, pkt_len);
- if (written < 0 || (gsize)written != pkt_len)
- purple_debug_warning("yahoo","p2p: couldn't write to the source\n");
-static void yahoo_p2p_keepalive_cb(gpointer key, gpointer value, gpointer user_data)
- struct yahoo_p2p_data *p2p_data = value;
- PurpleConnection *gc = user_data;
- struct yahoo_packet *pkt_to_send;
- PurpleAccount *account;
- YahooData *yd = gc->proto_data;
- account = purple_connection_get_account(gc);
- pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt_to_send, "ssisi",
- 4, purple_normalize(account, purple_account_get_username(account)),
- 5, p2p_data->host_username,
- 241, 0, /* Protocol identifier */
- yahoo_p2p_write_pkt(p2p_data->source, pkt_to_send);
- yahoo_packet_free(pkt_to_send);
-static gboolean yahoo_p2p_keepalive(gpointer data)
- PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
- g_hash_table_foreach(yd->peers, yahoo_p2p_keepalive_cb, gc);
-/* destroy p2p_data associated with a peer and close p2p connection.
- * g_hash_table_remove() calls this function to destroy p2p_data associated with the peer,
- * call g_hash_table_remove() instead of this fucntion if peer has an entry in the table */
-static void yahoo_p2p_disconnect_destroy_data(gpointer data)
- struct yahoo_p2p_data *p2p_data;
- /* If friend, set him not connected */
- f = yahoo_friend_find(p2p_data->gc, p2p_data->host_username);
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
- if(p2p_data->source >= 0)
- close(p2p_data->source);
- if (p2p_data->input_event > 0)
- purple_input_remove(p2p_data->input_event);
- g_free(p2p_data->host_ip);
- g_free(p2p_data->host_username);
-/* exchange of initial p2pfilexfer packets, service type YAHOO_SERVICE_P2PFILEXFER */
-static void yahoo_p2p_process_p2pfilexfer(gpointer data, gint source, struct yahoo_packet *pkt)
- struct yahoo_p2p_data *p2p_data;
- struct yahoo_packet *pkt_to_send;
- PurpleAccount *account;
- int val_13_to_send = 0;
- yd = p2p_data->gc->proto_data;
- /* lets see whats in the packet */
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- if(strncmp(who, p2p_data->host_username, strlen(p2p_data->host_username)) != 0) {
- /* from whom are we receiving the packets ?? */
- purple_debug_warning("yahoo","p2p: received data from wrong user\n");
- purple_debug_warning("yahoo", "yahoo_p2p_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- p2p_data->val_13 = strtol(pair->value, NULL, 10); /* Value should be 5-7 */
- /* case 5, 49 look laters, no use right now */
- account = purple_connection_get_account(p2p_data->gc);
- /* key_13: sort of a counter.
- * WHEN WE ARE CLIENT: yahoo server sends val_13 = 0, we send to peer val_13 = 1, receive back val_13 = 5,
- * we send val_13=6, receive val_13=7, we send val_13=7, HALT. Keep sending val_13 = 7 as keep alive.
- * WHEN WE ARE SERVER: we send val_13 = 0 to yahoo server, peer sends us val_13 = 1, we send val_13 = 5,
- * receive val_13 = 6, send val_13 = 7, receive val_13 = 7. HALT. Keep sending val_13 = 7 as keep alive. */
- switch(p2p_data->val_13) {
- case 1 : val_13_to_send = 5; break;
- case 5 : val_13_to_send = 6; break;
- case 6 : val_13_to_send = 7; break;
- case 7 : if( g_hash_table_lookup(yd->peers, p2p_data->host_username) )
- val_13_to_send = 7; break;
- default: purple_debug_warning("yahoo","p2p:Unknown value for key 13\n");
- /* Build the yahoo packet */
- pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt_to_send, "ssisi",
- 4, purple_normalize(account, purple_account_get_username(account)),
- 5, p2p_data->host_username,
- 241, 0, /* Protocol identifier */
- /* build the raw packet and send it to the host */
- yahoo_p2p_write_pkt(source, pkt_to_send);
- yahoo_packet_free(pkt_to_send);
- if( val_13_to_send == 7 )
- if( !g_hash_table_lookup(yd->peers, p2p_data->host_username) ) {
- g_hash_table_insert(yd->peers, g_strdup(p2p_data->host_username), p2p_data);
- /* If the peer is a friend, set him connected */
- f = yahoo_friend_find(p2p_data->gc, p2p_data->host_username);
- if(p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) {
- p2p_data->session_id = f->session_id;
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_SERVER);
- yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT);
-/* callback function associated with receiving of data, not considering receipt of multiple YMSG packets in a single TCP packet */
-static void yahoo_p2p_read_pkt_cb(gpointer data, gint source, PurpleInputCondition cond)
- guchar buf[1024]; /* is it safe to assume a fixed array length of 1024 ?? */
- struct yahoo_packet *pkt;
- struct yahoo_p2p_data *p2p_data;
- yd = p2p_data->gc->proto_data;
- len = read(source, buf, sizeof(buf));
- if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
- return ; /* No Worries*/
- purple_debug_warning("yahoo","p2p: Error in connection, or host disconnected\n");
- /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
- if( g_hash_table_lookup(yd->peers, p2p_data->host_username) )
- g_hash_table_remove(yd->peers,p2p_data->host_username);
- yahoo_p2p_disconnect_destroy_data(data);
- /* TODO: It looks like there's a bug here (and above) where an incorrect
- * assumtion is being made that the buffer will be added to when this
- * is next called, but that's not really the case! */
- if(len < YAHOO_PACKET_HDRLEN)
- if(strncmp((char *)buf, "YMSG", 4) != 0) {
- /* Not a YMSG packet */
- purple_debug_warning("yahoo", "p2p: Got something other than YMSG packet\n");
- start = (guchar *) g_strstr_len((char *) buf + 1, len - 1 ,"YMSG");
- /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
- if (g_hash_table_lookup(yd->peers, p2p_data->host_username))
- g_hash_table_remove(yd->peers, p2p_data->host_username);
- yahoo_p2p_disconnect_destroy_data(data);
- purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n");
- g_memmove(buf, start, len);
- pktlen = yahoo_get16(buf + pos); pos += 2;
- if (len < (YAHOO_PACKET_HDRLEN + pktlen)) {
- purple_debug_error("yahoo", "p2p: packet length(%d) > buffer length(%d)\n",
- /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
- if (g_hash_table_lookup(yd->peers, p2p_data->host_username))
- g_hash_table_remove(yd->peers, p2p_data->host_username);
- yahoo_p2p_disconnect_destroy_data(data);
- purple_debug_misc("yahoo", "p2p: %d bytes to read\n", pktlen);
- pkt = yahoo_packet_new(0, 0, 0);
- pkt->service = yahoo_get16(buf + pos); pos += 2;
- pkt->status = yahoo_get32(buf + pos); pos += 4;
- pkt->id = yahoo_get32(buf + pos); pos += 4;
- purple_debug_misc("yahoo", "p2p: Yahoo Service: 0x%02x Status: %d\n",pkt->service, pkt->status);
- yahoo_packet_read(pkt, buf + pos, pktlen);
- /* packet processing */
- case YAHOO_SERVICE_P2PFILEXFER:
- yahoo_p2p_process_p2pfilexfer(data, source, pkt);
- case YAHOO_SERVICE_MESSAGE:
- yahoo_process_message(p2p_data->gc, pkt, YAHOO_PKT_TYPE_P2P);
- case YAHOO_SERVICE_NOTIFY:
- yahoo_process_notify(p2p_data->gc, pkt, YAHOO_PKT_TYPE_P2P);
- purple_debug_warning("yahoo","p2p: p2p service %d Unhandled\n",pkt->service);
- yahoo_packet_free(pkt);
-static void yahoo_p2p_server_send_connected_cb(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_p2p_data *p2p_data;
- yd = p2p_data->gc->proto_data;
- acceptfd = accept(source, NULL, 0);
- if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
- else if(acceptfd == -1) {
- purple_debug_warning("yahoo","yahoo_p2p_server_send_connected_cb: accept: %s\n", g_strerror(errno));
- yahoo_p2p_disconnect_destroy_data(data);
- if (yd->yahoo_p2p_server_timeout_handle) {
- purple_timeout_remove(yd->yahoo_p2p_server_timeout_handle);
- yd->yahoo_p2p_server_timeout_handle = 0;
- /* remove watcher and close p2p server */
- if (yd->yahoo_p2p_server_watcher) {
- purple_input_remove(yd->yahoo_p2p_server_watcher);
- yd->yahoo_p2p_server_watcher = 0;
- if (yd->yahoo_local_p2p_server_fd >= 0) {
- close(yd->yahoo_local_p2p_server_fd);
- yd->yahoo_local_p2p_server_fd = -1;
- /* Add an Input Read event to the file descriptor */
- p2p_data->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data);
- p2p_data->source = acceptfd;
-static gboolean yahoo_cancel_p2p_server_listen_cb(gpointer data)
- struct yahoo_p2p_data *p2p_data;
- yd = p2p_data->gc->proto_data;
- purple_debug_warning("yahoo","yahoo p2p server timeout, peer failed to connect\n");
- yahoo_p2p_disconnect_destroy_data(data);
- purple_input_remove(yd->yahoo_p2p_server_watcher);
- yd->yahoo_p2p_server_watcher = 0;
- close(yd->yahoo_local_p2p_server_fd);
- yd->yahoo_local_p2p_server_fd = -1;
- yd->yahoo_p2p_server_timeout_handle = 0;
-static void yahoo_p2p_server_listen_cb(int listenfd, gpointer data)
- struct yahoo_p2p_data *p2p_data;
- yd = p2p_data->gc->proto_data;
- yd->listen_data = NULL;
- purple_debug_warning("yahoo","p2p: error starting p2p server\n");
- yahoo_p2p_disconnect_destroy_data(data);
- /* Add an Input Read event to the file descriptor */
- yd->yahoo_local_p2p_server_fd = listenfd;
- yd->yahoo_p2p_server_watcher = purple_input_add(listenfd, PURPLE_INPUT_READ, yahoo_p2p_server_send_connected_cb,data);
- yd->yahoo_p2p_server_timeout_handle = purple_timeout_add_seconds(YAHOO_P2P_SERVER_TIMEOUT, yahoo_cancel_p2p_server_listen_cb, data);
-/* send p2p pkt containing our encoded ip, asking peer to connect to us */
-void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
- gchar *base64_ip = NULL;
- struct yahoo_packet *pkt;
- PurpleAccount *account;
- YahooData *yd = gc->proto_data;
- struct yahoo_p2p_data *p2p_data;
- const char *norm_username;
- f = yahoo_friend_find(gc, who);
- account = purple_connection_get_account(gc);
- /* Do not send invitation if already listening for other connection */
- if(yd->yahoo_local_p2p_server_fd >= 0)
- /* One shouldn't try to connect to self */
- if( strcmp(purple_normalize(account, purple_account_get_username(account)), who) == 0)
- /* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */
- if( !( f && (yahoo_friend_get_p2p_status(f) == YAHOO_P2PSTATUS_NOT_CONNECTED) && (f->p2p_packet_sent == 0)) )
- /* Dont send p2p packet to buddies of other protocols */
- /* Finally, don't try to connect to buddies not online or on sms */
- if( (f->status == YAHOO_STATUS_OFFLINE) || f->sms )
- public_ip = purple_network_get_public_ip();
- if( (sscanf(public_ip, "%u.%u.%u.%u", &temp[0], &temp[1], &temp[2], &temp[3])) !=4 )
- ip = (temp[3] << 24) | (temp[2] <<16) | (temp[1] << 8) | temp[0];
- sprintf(temp_str, "%d", ip);
- base64_ip = purple_base64_encode( (guchar *)temp_str, strlen(temp_str) );
- norm_username = purple_normalize(account, purple_account_get_username(account));
- pkt = yahoo_packet_new(YAHOO_SERVICE_PEERTOPEER, YAHOO_STATUS_AVAILABLE, 0);
- yahoo_packet_hash(pkt, "sssissis",
- 12, base64_ip, /* base64 encode ip */
- 61, 0, /* To-do : figure out what is 61 for?? */
- yahoo_packet_send_and_free(pkt, yd);
- f->p2p_packet_sent = 1; /* set p2p_packet_sent to sent */
- p2p_data = g_new0(struct yahoo_p2p_data, 1);
- p2p_data->host_ip = NULL;
- p2p_data->host_username = g_strdup(who);
- p2p_data->val_13 = val_13;
- p2p_data->connection_type = YAHOO_P2P_WE_ARE_SERVER;
- /* FIXME: If the port is already used, purple_network_listener returns NULL and old listener won't be canceled
- * in yahoo_close function. */
- purple_debug_warning("yahoo","p2p: Failed to create p2p server - server already exists\n");
- yd->listen_data = purple_network_listen(YAHOO_PAGER_PORT_P2P, SOCK_STREAM, yahoo_p2p_server_listen_cb, p2p_data);
- if (yd->listen_data == NULL)
- purple_debug_warning("yahoo","p2p: Failed to created p2p server\n");
-/* function called when connection to p2p host is setup */
-static void yahoo_p2p_init_cb(gpointer data, gint source, const gchar *error_message)
- struct yahoo_p2p_data *p2p_data;
- struct yahoo_packet *pkt_to_send;
- PurpleAccount *account;
- yd = p2p_data->gc->proto_data;
- if(error_message != NULL) {
- purple_debug_warning("yahoo","p2p: %s\n",error_message);
- yahoo_send_p2p_pkt(p2p_data->gc, p2p_data->host_username, 2);/* send p2p init packet with val_13=2 */
- yahoo_p2p_disconnect_destroy_data(p2p_data);
- /* Add an Input Read event to the file descriptor */
- p2p_data->input_event = purple_input_add(source, PURPLE_INPUT_READ, yahoo_p2p_read_pkt_cb, data);
- p2p_data->source = source;
- account = purple_connection_get_account(p2p_data->gc);
- /* Build the yahoo packet */
- pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt_to_send, "ssisi",
- 4, purple_normalize(account, purple_account_get_username(account)),
- 5, p2p_data->host_username,
- 241, 0, /* Protocol identifier */
- 13, 1); /* we receive key13= 0 or 2, we send key13=1 */
- yahoo_p2p_write_pkt(source, pkt_to_send); /* build raw packet and send */
- yahoo_packet_free(pkt_to_send);
-static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account;
- /* if status is not YAHOO_STATUS_BRB or YAHOO_STATUS_P2P, the packet bounced back,
- * so it contains our own ip */
- if(pkt->status != YAHOO_STATUS_BRB && pkt->status != YAHOO_STATUS_P2P)
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2p "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* who again, the master identity this time? */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- /* so, this is an ip address. in base64. decoded it's in ascii.
- after strtol, it's in reversed byte order. Who thought this up?*/
- purple_debug_warning("yahoo", "yahoo_process_p2p "
- "got non-UTF-8 string for key %d\n", pair->key);
- val_13 = strtol(pair->value, NULL, 10);
- val_11 = strtol(pair->value, NULL, 10); /* session id of peer */
- if( (f = yahoo_friend_find(gc, who)) )
- f->session_id = val_11;
- yahoo: Key: 61 Value: 0
- yahoo: Key: 13 Value: 0 packet count ??
- yahoo: Key: 49 Value: PEERTOPEER
- yahoo: Key: 140 Value: 1
- struct yahoo_p2p_data *p2p_data;
- decoded = purple_base64_decode(base64, &len);
- purple_debug_info("yahoo","p2p: Unable to decode base64 IP (%s) \n", base64);
- tmp = purple_str_binary_to_ascii(decoded, len);
- purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp);
- ip = strtol((gchar *)decoded, NULL, 10);
- host_ip = g_strdup_printf("%u.%u.%u.%u", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff,
- f = yahoo_friend_find(gc, who);
- yahoo_friend_set_ip(f, host_ip);
- purple_debug_info("yahoo", "IP : %s\n", host_ip);
- account = purple_connection_get_account(gc);
- val_11 = f->session_id;
- p2p_data = g_new0(struct yahoo_p2p_data, 1);
- p2p_data->host_username = g_strdup(who);
- p2p_data->val_13 = val_13;
- p2p_data->session_id = val_11;
- p2p_data->host_ip = host_ip;
- p2p_data->connection_type = YAHOO_P2P_WE_ARE_CLIENT;
- if((purple_proxy_connect(gc, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) {
- purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip);
- g_free(p2p_data->host_ip);
- g_free(p2p_data->host_username);
-static void yahoo_process_audible(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account;
- char *who = NULL, *msg = NULL, *id = NULL;
- account = purple_connection_get_account(gc);
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_audible "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* the audible, in foo.locale.bar.baz format
- eg: base.tw.smiley.smiley43 */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_audible "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* the text of the audible */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_audible "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* SHA-1 hash of audible SWF file (eg: 4e8691499d9c0fb8374478ff9720f4a9ea4a4915) */
- if (!g_utf8_validate(msg, -1, NULL)) {
- purple_debug_misc("yahoo", "Warning, nonutf8 audible, ignoring!\n");
- if (!purple_privacy_check(account, who)) {
- purple_debug_misc("yahoo", "Audible message from %s for %s dropped!\n",
- purple_account_get_username(account), who);
- /* "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);
- serv_got_im(gc, who, buf, 0, time(NULL));
- serv_got_im(gc, who, msg, 0, time(NULL));
-static void yahoo_packet_process(PurpleConnection *gc, struct yahoo_packet *pkt)
- switch (pkt->service) {
- case YAHOO_SERVICE_LOGON:
- case YAHOO_SERVICE_LOGOFF:
- case YAHOO_SERVICE_ISAWAY:
- case YAHOO_SERVICE_ISBACK:
- case YAHOO_SERVICE_GAMELOGON:
- case YAHOO_SERVICE_GAMELOGOFF:
- case YAHOO_SERVICE_CHATLOGON:
- case YAHOO_SERVICE_CHATLOGOFF:
- case YAHOO_SERVICE_Y6_STATUS_UPDATE:
- case YAHOO_SERVICE_STATUS_15:
- yahoo_process_status(gc, pkt);
- case YAHOO_SERVICE_NOTIFY:
- yahoo_process_notify(gc, pkt, YAHOO_PKT_TYPE_SERVER);
- case YAHOO_SERVICE_MESSAGE:
- case YAHOO_SERVICE_GAMEMSG:
- case YAHOO_SERVICE_CHATMSG:
- yahoo_process_message(gc, pkt, YAHOO_PKT_TYPE_SERVER);
- case YAHOO_SERVICE_SYSMESSAGE:
- yahoo_process_sysmessage(gc, pkt);
- case YAHOO_SERVICE_NEWMAIL:
- yahoo_process_mail(gc, pkt);
- case YAHOO_SERVICE_NEWCONTACT:
- yahoo_process_contact(gc, pkt);
- case YAHOO_SERVICE_AUTHRESP:
- yahoo_process_authresp(gc, pkt);
- case YAHOO_SERVICE_LIST:
- yahoo_process_list(gc, pkt);
- case YAHOO_SERVICE_LIST_15:
- yahoo_process_list_15(gc, pkt);
- case YAHOO_SERVICE_AUTH:
- yahoo_process_auth(gc, pkt);
- case YAHOO_SERVICE_AUTH_REQ_15:
- yahoo_buddy_auth_req_15(gc, pkt);
- case YAHOO_SERVICE_ADDBUDDY:
- yahoo_process_addbuddy(gc, pkt);
- case YAHOO_SERVICE_IGNORECONTACT:
- yahoo_process_ignore(gc, pkt);
- case YAHOO_SERVICE_CONFINVITE:
- case YAHOO_SERVICE_CONFADDINVITE:
- yahoo_process_conference_invite(gc, pkt);
- case YAHOO_SERVICE_CONFDECLINE:
- yahoo_process_conference_decline(gc, pkt);
- case YAHOO_SERVICE_CONFLOGON:
- yahoo_process_conference_logon(gc, pkt);
- case YAHOO_SERVICE_CONFLOGOFF:
- yahoo_process_conference_logoff(gc, pkt);
- case YAHOO_SERVICE_CONFMSG:
- yahoo_process_conference_message(gc, pkt);
- case YAHOO_SERVICE_CHATONLINE:
- yahoo_process_chat_online(gc, pkt);
- case YAHOO_SERVICE_CHATLOGOUT:
- yahoo_process_chat_logout(gc, pkt);
- case YAHOO_SERVICE_CHATGOTO:
- yahoo_process_chat_goto(gc, pkt);
- case YAHOO_SERVICE_CHATJOIN:
- yahoo_process_chat_join(gc, pkt);
- case YAHOO_SERVICE_CHATLEAVE: /* XXX is this right? */
- case YAHOO_SERVICE_CHATEXIT:
- yahoo_process_chat_exit(gc, pkt);
- case YAHOO_SERVICE_CHATINVITE: /* XXX never seen this one, might not do it right */
- case YAHOO_SERVICE_CHATADDINVITE:
- yahoo_process_chat_addinvite(gc, pkt);
- case YAHOO_SERVICE_COMMENT:
- yahoo_process_chat_message(gc, pkt);
- case YAHOO_SERVICE_PRESENCE_PERM:
- case YAHOO_SERVICE_PRESENCE_SESSION:
- yahoo_process_presence(gc, pkt);
- case YAHOO_SERVICE_P2PFILEXFER:
- /* This case had no break and continued; thus keeping it this way.*/
- yahoo_process_p2p(gc, pkt); /* P2PFILEXFER handled the same way as process_p2p */
- yahoo_process_p2pfilexfer(gc, pkt); /* redundant ??, need to have a break now */
- case YAHOO_SERVICE_FILETRANSFER:
- yahoo_process_filetransfer(gc, pkt);
- case YAHOO_SERVICE_PEERTOPEER:
- yahoo_process_p2p(gc, pkt);
- case YAHOO_SERVICE_PICTURE:
- yahoo_process_picture(gc, pkt);
- case YAHOO_SERVICE_PICTURE_CHECKSUM:
- yahoo_process_picture_checksum(gc, pkt);
- case YAHOO_SERVICE_PICTURE_UPLOAD:
- yahoo_process_picture_upload(gc, pkt);
- case YAHOO_SERVICE_PICTURE_UPDATE:
- case YAHOO_SERVICE_AVATAR_UPDATE:
- yahoo_process_avatar_update(gc, pkt);
- case YAHOO_SERVICE_AUDIBLE:
- yahoo_process_audible(gc, pkt);
- case YAHOO_SERVICE_CONTACT_DETAILS:
- yahoo_process_contact_details(gc, pkt);
- case YAHOO_SERVICE_FILETRANS_15:
- yahoo_process_filetrans_15(gc, pkt);
- case YAHOO_SERVICE_FILETRANS_INFO_15:
- yahoo_process_filetrans_info_15(gc, pkt);
- case YAHOO_SERVICE_FILETRANS_ACC_15:
- yahoo_process_filetrans_acc_15(gc, pkt);
- case YAHOO_SERVICE_SMS_MSG:
- yahoo_process_sms_message(gc, pkt);
- purple_debug_error("yahoo", "Unhandled service 0x%02x\n", pkt->service);
-static void yahoo_pending(gpointer data, gint source, PurpleInputCondition cond)
- PurpleConnection *gc = data;
- YahooData *yd = gc->proto_data;
- len = read(yd->fd, buf, sizeof(buf));
- tmp = g_strdup_printf(_("Lost connection with server: %s"),
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Server closed the connection"));
- gc->last_received = time(NULL);
- yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen);
- memcpy(yd->rxqueue + yd->rxlen, buf, len);
- struct yahoo_packet *pkt;
- if (yd->rxlen < YAHOO_PACKET_HDRLEN)
- if (strncmp((char *)yd->rxqueue, "YMSG", MIN(4, yd->rxlen)) != 0) {
- /* HEY! This isn't even a YMSG packet. What
- * are you trying to pull? */
- purple_debug_warning("yahoo", "Error in YMSG stream, got something not a YMSG packet!\n");
- start = memchr(yd->rxqueue + 1, 'Y', yd->rxlen - 1);
- g_memmove(yd->rxqueue, start, yd->rxlen - (start - yd->rxqueue));
- yd->rxlen -= start - yd->rxqueue;
- pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2;
- purple_debug_misc("yahoo", "%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen);
- if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen))
- yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen);
- pkt = yahoo_packet_new(0, 0, 0);
- pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2;
- pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4;
- purple_debug_misc("yahoo", "Yahoo Service: 0x%02x Status: %d\n",
- pkt->service, pkt->status);
- pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4;
- yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen);
- yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen;
- guchar *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen);
- yahoo_packet_process(gc, pkt);
- yahoo_packet_free(pkt);
-static void yahoo_got_connected(gpointer data, gint source, const gchar *error_message)
- PurpleConnection *gc = data;
- struct yahoo_packet *pkt;
- tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, yd->current_status, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))));
- yahoo_packet_send_and_free(pkt, yd);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
-#ifdef TRY_WEBMESSENGER_LOGIN
-static void yahoo_got_web_connected(gpointer data, gint source, const gchar *error_message)
- PurpleConnection *gc = data;
- struct yahoo_packet *pkt;
- tmp = g_strdup_printf(_("Unable to connect: %s"), error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- pkt = yahoo_packet_new(YAHOO_SERVICE_WEBLOGIN, YAHOO_STATUS_WEBLOGIN, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 0,
- purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
- 1, purple_normalize(gc->account, purple_account_get_username(purple_connection_get_account(gc))),
- yahoo_packet_send_and_free(pkt, yd);
- gc->inpa = purple_input_add(yd->fd, PURPLE_INPUT_READ, yahoo_pending, gc);
-static void yahoo_web_pending(gpointer data, gint source, PurpleInputCondition cond)
- PurpleConnection *gc = data;
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- char bufread[2048], *i = bufread, *buf = bufread;
- len = read(source, bufread, sizeof(bufread) - 1);
- tmp = g_strdup_printf(_("Lost connection with server: %s"),
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Server closed the connection"));
- if (yd->rxlen > 0 || !g_strstr_len(buf, len, "\r\n\r\n")) {
- yd->rxqueue = g_realloc(yd->rxqueue, yd->rxlen + len + 1);
- memcpy(yd->rxqueue + yd->rxlen, buf, len);
- i = buf = (char *)yd->rxqueue;
- if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) &&
- strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Received unexpected HTTP response from server"));
- purple_debug_misc("yahoo", "Unexpected HTTP response: %s\n", buf);
- s = g_string_sized_new(len);
- while ((i = strstr(i, "Set-Cookie: "))) {
- i += strlen("Set-Cookie: ");
- for (;*i != ';' && *i != '\0'; i++)
- g_string_append_c(s, *i);
- g_string_append(s, "; ");
- /* Should these cookies be included too when trying for xfer?
- * It seems to work without these
- yd->auth = g_string_free(s, FALSE);
- purple_input_remove(gc->inpa);
- /* Now we have our cookies to login with. I'll go get the milk. */
- if (purple_proxy_connect(gc, account, "wcs2.msg.dcn.yahoo.com",
- purple_account_get_int(account, "port", YAHOO_PAGER_PORT),
- yahoo_got_web_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
-static void yahoo_got_cookies_send_cb(gpointer data, gint source, PurpleInputCondition cond)
- int written, remaining;
- remaining = strlen(yd->auth) - yd->auth_written;
- written = write(source, yd->auth + yd->auth_written, remaining);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- purple_input_remove(gc->inpa);
- tmp = g_strdup_printf(_("Lost connection with %s: %s"),
- "login.yahoo.com:80", g_strerror(errno));
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- if (written < remaining) {
- yd->auth_written += written;
- purple_input_remove(gc->inpa);
- gc->inpa = purple_input_add(source, PURPLE_INPUT_READ, yahoo_web_pending, gc);
-static void yahoo_got_cookies(gpointer data, gint source, const gchar *error_message)
- PurpleConnection *gc = data;
- tmp = g_strdup_printf(_("Unable to establish a connection with %s: %s"),
- "login.yahoo.com:80", error_message);
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- gc->inpa = purple_input_add(source, PURPLE_INPUT_WRITE,
- yahoo_got_cookies_send_cb, gc);
- yahoo_got_cookies_send_cb(gc, source, PURPLE_INPUT_WRITE);
-static void yahoo_login_page_hash_iter(const char *key, const char *val, GString *url)
- if (!strcmp(key, "passwd") || !strcmp(key, "login"))
- g_string_append_c(url, '&');
- g_string_append(url, key);
- g_string_append_c(url, '=');
- if (!strcmp(key, ".save") || !strcmp(key, ".js"))
- g_string_append_c(url, '1');
- else if (!strcmp(key, ".challenge"))
- g_string_append(url, val);
- g_string_append(url, purple_url_encode(val));
-static GHashTable *yahoo_login_page_hash(const char *buf, size_t len)
- GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- char name[64], value[64];
- int input_len = strlen("<input ");
- int name_len = strlen("name=\"");
- int value_len = strlen("value=\"");
- while ((len > ((c - buf) + input_len))
- && (c = strstr(c, "<input "))) {
- if (!(c = g_strstr_len(c, len - (c - buf), "name=\"")))
- count = sizeof(name)-1;
- for (d = name; (len > ((c - buf) + 1)) && *c!='"'
- && count; c++, d++, count--)
- count = sizeof(value)-1;
- if (!(d = g_strstr_len(c, len - (c - buf), "value=\"")))
- if (strchr(c, '>') < d)
- for (c = d, d = value; (len > ((c - buf) + 1))
- && *c!='"' && count; c++, d++, count--)
- g_hash_table_insert(hash, g_strdup(name), g_strdup(value));
-yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *url_text, size_t len, const gchar *error_message)
- PurpleConnection *gc = (PurpleConnection *)user_data;
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- const char *sn = purple_account_get_username(account);
- const char *pass = purple_connection_get_password(gc);
- GHashTable *hash = yahoo_login_page_hash(url_text, len);
- GString *url = g_string_new("GET http://login.yahoo.com/config/login?login=");
- char md5[33], *hashp = md5, *chal;
- PurpleCipherContext *context;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL)
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- url = g_string_append(url, sn);
- url = g_string_append(url, "&passwd=");
- cipher = purple_ciphers_find_cipher("md5");
- context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, (const guchar *)pass, strlen(pass));
- purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
- for (i = 0; i < 16; ++i) {
- g_snprintf(hashp, 3, "%02x", digest[i]);
- chal = g_strconcat(md5, g_hash_table_lookup(hash, ".challenge"), NULL);
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, (const guchar *)chal, strlen(chal));
- purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
- for (i = 0; i < 16; ++i) {
- g_snprintf(hashp, 3, "%02x", digest[i]);
- * I dunno why this is here and commented out.. but in case it's needed
- purple_cipher_context_reset(context, NULL);
- purple_cipher_context_append(context, md5, strlen(md5));
- purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
- for (i = 0; i < 16; ++i) {
- g_snprintf(hashp, 3, "%02x", digest[i]);
- url = g_string_append(url, md5);
- g_hash_table_foreach(hash, (GHFunc)yahoo_login_page_hash_iter, url);
- url = g_string_append(url, "&.hash=1&.md5=1 HTTP/1.1\r\n"
- "Host: login.yahoo.com\r\n\r\n");
- g_hash_table_destroy(hash);
- yd->auth = g_string_free(url, FALSE);
- if (purple_proxy_connect(gc, account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
- purple_cipher_context_destroy(context);
-#endif /* TRY_WEBMESSENGER_LOGIN */
-static void yahoo_picture_check(PurpleAccount *account)
- PurpleConnection *gc = purple_account_get_connection(account);
- PurpleStoredImage *img = purple_buddy_icons_find_account_icon(account);
- yahoo_set_buddy_icon(gc, img);
- purple_imgstore_unref(img);
-static int get_yahoo_status_from_purple_status(PurpleStatus *status)
- PurplePresence *presence;
- presence = purple_status_get_presence(status);
- status_id = purple_status_get_id(status);
- msg = purple_status_get_attr_string(status, "message");
- if ((msg != NULL) && (*msg != '\0')) {
- return YAHOO_STATUS_CUSTOM;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_AVAILABLE)) {
- return YAHOO_STATUS_AVAILABLE;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_BRB)) {
- return YAHOO_STATUS_BRB;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_BUSY)) {
- return YAHOO_STATUS_BUSY;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_NOTATHOME)) {
- return YAHOO_STATUS_NOTATHOME;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_NOTATDESK)) {
- return YAHOO_STATUS_NOTATDESK;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_NOTINOFFICE)) {
- return YAHOO_STATUS_NOTINOFFICE;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_ONPHONE)) {
- return YAHOO_STATUS_ONPHONE;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_ONVACATION)) {
- return YAHOO_STATUS_ONVACATION;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_OUTTOLUNCH)) {
- return YAHOO_STATUS_OUTTOLUNCH;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_STEPPEDOUT)) {
- return YAHOO_STATUS_STEPPEDOUT;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_INVISIBLE)) {
- return YAHOO_STATUS_INVISIBLE;
- } else if (!strcmp(status_id, YAHOO_STATUS_TYPE_AWAY)) {
- return YAHOO_STATUS_CUSTOM;
- } else if (purple_presence_is_idle(presence)) {
- return YAHOO_STATUS_IDLE;
- purple_debug_error("yahoo", "Unexpected PurpleStatus!\n");
- return YAHOO_STATUS_AVAILABLE;
-static void yahoo_got_pager_server(PurpleUtilFetchUrlData *url_data,
- gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message)
- YahooData *yd = user_data;
- PurpleConnection *gc = yd->gc;
- PurpleAccount *a = purple_connection_get_account(gc);
- gchar **strings = NULL, *cs_server = NULL;
- int port = purple_account_get_int(a, "port", YAHOO_PAGER_PORT);
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if(error_message != NULL || len == 0) {
- purple_debug_error("yahoo", "Unable to retrieve server info. %"
- G_GSIZE_FORMAT " bytes retrieved with error message: %s\n", len,
- error_message ? error_message : "(null)");
- if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect: The server returned an empty response."));
- if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
- yahoo_got_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
- strings = g_strsplit(url_text, "\r\n", -1);
- if((stringslen = g_strv_length(strings)) > 1) {
- for(i = 0; i < stringslen; i++) {
- if(g_ascii_strncasecmp(strings[i], "COLO_CAPACITY=", 14) == 0) {
- purple_debug_info("yahoo", "Got COLO Capacity: %s\n", &(strings[i][14]));
- } else if(g_ascii_strncasecmp(strings[i], "CS_IP_ADDRESS=", 14) == 0) {
- cs_server = g_strdup(&strings[i][14]);
- purple_debug_info("yahoo", "Got CS IP address: %s\n", cs_server);
- if(cs_server) { /* got an address; get on with connecting */
- if(purple_proxy_connect(gc, a, cs_server, port, yahoo_got_connected, gc) == NULL)
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
- purple_debug_error("yahoo", "No CS address retrieved! Server "
- "response:\n%s\n", url_text ? url_text : "(null)");
- if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect: The server's response did not contain "
- "the necessary information"));
- if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port,
- yahoo_got_connected, gc) == NULL) {
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
-void yahoo_login(PurpleAccount *account) {
- PurpleConnection *gc = purple_account_get_connection(account);
- YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
- PurpleStatus *status = purple_account_get_active_status(account);
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
- PurpleUtilFetchUrlData *url_data;
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
- purple_connection_update_progress(gc, _("Connecting"), 1, 2);
- purple_connection_set_display_name(gc, purple_account_get_username(account));
- yd->jp = yahoo_is_japan(account);
- yd->yahoo_local_p2p_server_fd = -1;
- /* TODO: Is there a good grow size for the buffer? */
- yd->txbuf = purple_circ_buffer_new(0);
- yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free);
- yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
- yd->peers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- yahoo_p2p_disconnect_destroy_data);
- yd->sms_carrier = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- yd->yahoo_p2p_timer = purple_timeout_add_seconds(YAHOO_P2P_KEEPALIVE_SECS,
- yahoo_p2p_keepalive, gc);
- yd->last_keepalive = yd->last_ping = time(NULL);
- yd->current_status = get_yahoo_status_from_purple_status(status);
- yahoo_picture_check(account);
- /* Get the pager server. Actually start connecting in the callback since we
- * must have the contents of the HTTP response to proceed. */
- url_data = purple_util_fetch_url_request_len_with_account(
- proxy_ssl ? purple_connection_get_account(gc) : NULL,
- yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
- use_whole_url ? TRUE : FALSE,
- YAHOO_CLIENT_USERAGENT, FALSE, NULL, FALSE, -1,
- yahoo_got_pager_server, yd);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-void yahoo_close(PurpleConnection *gc) {
- YahooData *yd = (YahooData *)gc->proto_data;
- purple_input_remove(gc->inpa);
- while (yd->url_datas) {
- purple_util_fetch_url_cancel(yd->url_datas->data);
- yd->url_datas = g_slist_delete_link(yd->url_datas, yd->url_datas);
- for (l = yd->confs; l; l = l->next) {
- PurpleConversation *conv = l->data;
- yahoo_conf_leave(yd, purple_conversation_get_name(conv),
- purple_connection_get_display_name(gc),
- purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)));
- g_slist_free(yd->confs);
- for (l = yd->cookies; l; l = l->next) {
- g_slist_free(yd->cookies);
- yd->chat_online = FALSE;
- yahoo_c_leave(gc, 1); /* 1 = YAHOO_CHAT_ID */
- purple_timeout_remove(yd->yahoo_p2p_timer);
- if(yd->yahoo_p2p_server_timeout_handle != 0) {
- purple_timeout_remove(yd->yahoo_p2p_server_timeout_handle);
- yd->yahoo_p2p_server_timeout_handle = 0;
- /* close p2p server if it is waiting for a peer to connect */
- if (yd->yahoo_p2p_server_watcher) {
- purple_input_remove(yd->yahoo_p2p_server_watcher);
- yd->yahoo_p2p_server_watcher = 0;
- if (yd->yahoo_local_p2p_server_fd >= 0) {
- close(yd->yahoo_local_p2p_server_fd);
- yd->yahoo_local_p2p_server_fd = -1;
- g_hash_table_destroy(yd->sms_carrier);
- g_hash_table_destroy(yd->peers);
- g_hash_table_destroy(yd->friends);
- g_hash_table_destroy(yd->imvironments);
- g_hash_table_destroy(yd->xfer_peer_idstring_map);
- purple_input_remove(yd->txhandler);
- purple_circ_buffer_destroy(yd->txbuf);
- g_free(yd->picture_url);
- if (yd->buddy_icon_connect_data)
- purple_proxy_connect_cancel(yd->buddy_icon_connect_data);
- if (yd->picture_upload_todo)
- yahoo_buddy_icon_upload_data_free(yd->picture_upload_todo);
- ycht_connection_close(yd->ycht);
- if (yd->listen_data != NULL)
- purple_network_listen_cancel(yd->listen_data);
- g_free(yd->pending_chat_room);
- g_free(yd->pending_chat_id);
- g_free(yd->pending_chat_topic);
- g_free(yd->pending_chat_goto);
- g_strfreev(yd->profiles);
- yahoo_personal_details_reset(&yd->ypd, TRUE);
- g_free(yd->current_list15_grp);
-const char *yahoo_list_icon(PurpleAccount *a, PurpleBuddy *b)
-const char *yahoo_list_emblem(PurpleBuddy *b)
- PurpleAccount *account;
- PurplePresence *presence;
- if (!b || !(account = purple_buddy_get_account(b)) ||
- !(gc = purple_account_get_connection(account)) ||
- f = yahoo_friend_find(gc, purple_buddy_get_name(b));
- return "not-authorized";
- presence = purple_buddy_get_presence(b);
- if (purple_presence_is_online(presence)) {
- if (yahoo_friend_get_game(f))
-static const char *yahoo_get_status_string(enum yahoo_status a)
- return _("Be Right Back");
- case YAHOO_STATUS_BUSY:
- case YAHOO_STATUS_NOTATHOME:
- return _("Not at Home");
- case YAHOO_STATUS_NOTATDESK:
- return _("Not at Desk");
- case YAHOO_STATUS_NOTINOFFICE:
- return _("Not in Office");
- case YAHOO_STATUS_ONPHONE:
- return _("On the Phone");
- case YAHOO_STATUS_ONVACATION:
- return _("On Vacation");
- case YAHOO_STATUS_OUTTOLUNCH:
- return _("Out to Lunch");
- case YAHOO_STATUS_STEPPEDOUT:
- return _("Stepped Out");
- case YAHOO_STATUS_INVISIBLE:
- case YAHOO_STATUS_IDLE:
- case YAHOO_STATUS_OFFLINE:
-static void yahoo_initiate_conference(PurpleBlistNode *node, gpointer data) {
- GHashTable *components;
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_replace(components, g_strdup("room"),
- g_strdup_printf("%s-%d", purple_connection_get_display_name(gc), id));
- g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference..."));
- g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
- yahoo_c_join(gc, components);
- g_hash_table_destroy(components);
- yahoo_c_invite(gc, id, "Join my conference...", purple_buddy_get_name(buddy));
-static void yahoo_presence_settings(PurpleBlistNode *node, gpointer data) {
- int presence_val = GPOINTER_TO_INT(data);
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yahoo_friend_update_presence(gc, purple_buddy_get_name(buddy), presence_val);
-static void yahoo_game(PurpleBlistNode *node, gpointer data) {
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- f = yahoo_friend_find(gc, purple_buddy_get_name(buddy));
- game = yahoo_friend_get_game(f);
- t = game2 = g_strdup(strstr(game, "ante?room="));
- while (*t && *t != '\t')
- g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game2);
- purple_notify_uri(gc, url);
-char *yahoo_status_text(PurpleBuddy *b)
- PurpleAccount *account;
- account = purple_buddy_get_account(b);
- gc = purple_account_get_connection(account);
- if (!gc || !purple_connection_get_protocol_data(gc))
- f = yahoo_friend_find(gc, purple_buddy_get_name(b));
- return g_strdup(_("Not on server list"));
- case YAHOO_STATUS_AVAILABLE:
- case YAHOO_STATUS_IDLE:
- return g_strdup(yahoo_get_status_string(f->status));
- case YAHOO_STATUS_CUSTOM:
- if (!(msg = yahoo_friend_get_status_message(f)))
- msg2 = g_markup_escape_text(msg, strlen(msg));
- purple_util_chrreplace(msg2, '\n', ' ');
- return g_strdup(yahoo_get_status_string(f->status));
-void yahoo_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
- const char *presence = NULL;
- PurpleAccount *account;
- account = purple_buddy_get_account(b);
- f = yahoo_friend_find(purple_account_get_connection(account), purple_buddy_get_name(b));
- status = g_strdup_printf("\n%s", _("Not on server list"));
- case YAHOO_STATUS_CUSTOM:
- if (!yahoo_friend_get_status_message(f))
- status = g_strdup(yahoo_friend_get_status_message(f));
- case YAHOO_STATUS_OFFLINE:
- status = g_strdup(yahoo_get_status_string(f->status));
- case YAHOO_PRESENCE_ONLINE:
- presence = _("Appear Online");
- case YAHOO_PRESENCE_PERM_OFFLINE:
- presence = _("Appear Permanently Offline");
- case YAHOO_PRESENCE_DEFAULT:
- purple_debug_error("yahoo", "Unknown presence in yahoo_tooltip_text\n");
- purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status);
- purple_notify_user_info_add_pair_plaintext(user_info, _("Presence"), presence);
- YahooPersonalDetails *ypd = &f->ypd;
- {"hp", N_("Home Phone Number"), ypd->phone.home},
- {"wp", N_("Work Phone Number"), ypd->phone.work},
- {"mo", N_("Mobile Phone Number"), ypd->phone.mobile},
- for (i = 0; yfields[i].id; i++) {
- if (!yfields[i].value || !*yfields[i].value)
- purple_notify_user_info_add_pair(user_info, _(yfields[i].text), yfields[i].value);
-static void yahoo_addbuddyfrommenu_cb(PurpleBlistNode *node, gpointer data)
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yahoo_add_buddy(gc, buddy, NULL);
-static void yahoo_chat_goto_menu(PurpleBlistNode *node, gpointer data)
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yahoo_chat_goto(gc, purple_buddy_get_name(buddy));
-static GList *build_presence_submenu(YahooFriend *f, PurpleConnection *gc) {
- YahooData *yd = (YahooData *) gc->proto_data;
- if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
- if (f->presence != YAHOO_PRESENCE_ONLINE) {
- act = purple_menu_action_new(_("Appear Online"),
- PURPLE_CALLBACK(yahoo_presence_settings),
- GINT_TO_POINTER(YAHOO_PRESENCE_ONLINE),
- m = g_list_append(m, act);
- } else if (f->presence != YAHOO_PRESENCE_DEFAULT) {
- act = purple_menu_action_new(_("Appear Offline"),
- PURPLE_CALLBACK(yahoo_presence_settings),
- GINT_TO_POINTER(YAHOO_PRESENCE_DEFAULT),
- m = g_list_append(m, act);
- if (f->presence == YAHOO_PRESENCE_PERM_OFFLINE) {
- act = purple_menu_action_new(_("Don't Appear Permanently Offline"),
- PURPLE_CALLBACK(yahoo_presence_settings),
- GINT_TO_POINTER(YAHOO_PRESENCE_DEFAULT),
- m = g_list_append(m, act);
- act = purple_menu_action_new(_("Appear Permanently Offline"),
- PURPLE_CALLBACK(yahoo_presence_settings),
- GINT_TO_POINTER(YAHOO_PRESENCE_PERM_OFFLINE),
- m = g_list_append(m, act);
-static void yahoo_doodle_blist_node(PurpleBlistNode *node, gpointer data)
- PurpleBuddy *b = (PurpleBuddy *)node;
- PurpleAccount *account = purple_buddy_get_account(b);
- PurpleConnection *gc = purple_account_get_connection(account);
- yahoo_doodle_initiate(gc, purple_buddy_get_name(b));
-yahoo_userinfo_blist_node(PurpleBlistNode *node, gpointer data)
- PurpleBuddy *b = (PurpleBuddy *)node;
- PurpleAccount *account = purple_buddy_get_account(b);
- PurpleConnection *gc = purple_account_get_connection(account);
- yahoo_set_userinfo_for_buddy(gc, b);
-static GList *yahoo_buddy_menu(PurpleBuddy *buddy)
- PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- YahooData *yd = gc->proto_data;
- static char buf2[1024];
- f = yahoo_friend_find(gc, purple_buddy_get_name(buddy));
- act = purple_menu_action_new(_("Add Buddy"),
- PURPLE_CALLBACK(yahoo_addbuddyfrommenu_cb),
- m = g_list_append(m, act);
- if (f && f->status != YAHOO_STATUS_OFFLINE && f->fed == YAHOO_FEDERATION_NONE) {
- act = purple_menu_action_new(_("Join in Chat"),
- PURPLE_CALLBACK(yahoo_chat_goto_menu),
- m = g_list_append(m, act);
- act = purple_menu_action_new(_("Initiate Conference"),
- PURPLE_CALLBACK(yahoo_initiate_conference),
- m = g_list_append(m, act);
- if (yahoo_friend_get_game(f)) {
- const char *game = yahoo_friend_get_game(f);
- if ((room = strstr(game, "&follow="))) {/* skip ahead to the url */
- while (*room && *room != '\t') /* skip to the tab */
- t = room++; /* room as now at the name */
- t++; /* replace the \n with a space */
- g_snprintf(buf2, sizeof buf2, "%s", room);
- act = purple_menu_action_new(buf2,
- PURPLE_CALLBACK(yahoo_game),
- m = g_list_append(m, act);
- act = purple_menu_action_new(_("Presence Settings"), NULL, NULL,
- build_presence_submenu(f, gc));
- m = g_list_append(m, act);
- if (f->fed == YAHOO_FEDERATION_NONE) {
- act = purple_menu_action_new(_("Start Doodling"),
- PURPLE_CALLBACK(yahoo_doodle_blist_node),
- m = g_list_append(m, act);
- act = purple_menu_action_new(_("Set User Info..."),
- PURPLE_CALLBACK(yahoo_userinfo_blist_node),
- m = g_list_append(m, act);
-GList *yahoo_blist_node_menu(PurpleBlistNode *node)
- if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
- return yahoo_buddy_menu((PurpleBuddy *) node);
-static void yahoo_act_id(PurpleConnection *gc, PurpleRequestFields *fields)
- YahooData *yd = gc->proto_data;
- const char *name = yd->profiles[purple_request_fields_get_choice(fields, "id")];
- struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 3, name);
- yahoo_packet_send_and_free(pkt, yd);
- purple_connection_set_display_name(gc, name);
-yahoo_get_inbox_token_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *token, size_t len, const gchar *error_message)
- PurpleConnection *gc = user_data;
- gboolean set_cookie = FALSE;
- YahooData *yd = gc->proto_data;
- g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL)
- purple_debug_error("yahoo", "Requesting mail login token failed: %s\n", error_message);
- else if (len > 0 && token && *token) {
- /* Should we not be hardcoding the rd url? */
- "http://login.yahoo.com/config/reset_cookies_token?"
- "&.done=http://us.rd.yahoo.com/messenger/client/%%3fhttp://mail.yahoo.com/",
- purple_debug_error("yahoo", "No mail login token; forwarding to login screen.\n");
- url = g_strdup(yd->jp ? YAHOOJP_MAIL_URL : YAHOO_MAIL_URL);
- /* Open the mailbox with the parsed url data */
- purple_notify_uri(gc, url);
-static void yahoo_show_inbox(PurplePluginAction *action)
- /* Setup a cookie that can be used by the browser */
- /* XXX I have no idea how this will work with Yahoo! Japan. */
- PurpleConnection *gc = action->context;
- YahooData *yd = gc->proto_data;
- PurpleUtilFetchUrlData *url_data;
- const char* base_url = "http://login.yahoo.com";
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- gchar *request = g_strdup_printf(
- "POST %s/config/cookie_token HTTP/1.0\r\n"
- "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Host: login.yahoo.com\r\n"
- "Content-Length: 0\r\n\r\n",
- use_whole_url ? base_url : "",
- yd->cookie_t, yd->cookie_y);
- url_data = purple_util_fetch_url_request_len_with_account(
- purple_connection_get_account(gc), base_url, use_whole_url,
- YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
- yahoo_get_inbox_token_cb, gc);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- const char *yahoo_mail_url = (yd->jp ? YAHOOJP_MAIL_URL : YAHOO_MAIL_URL);
- purple_debug_error("yahoo",
- "Unable to request mail login token; forwarding to login screen.");
- purple_notify_uri(gc, yahoo_mail_url);
-yahoo_set_userinfo_fn(PurplePluginAction *action)
- yahoo_set_userinfo(action->context);
-static void yahoo_show_act_id(PurplePluginAction *action)
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
- PurpleConnection *gc = (PurpleConnection *) action->context;
- YahooData *yd = purple_connection_get_protocol_data(gc);
- const char *name = purple_connection_get_display_name(gc);
- fields = purple_request_fields_new();
- group = purple_request_field_group_new(NULL);
- purple_request_fields_add_group(fields, group);
- field = purple_request_field_choice_new("id", _("Activate which ID?"), 0);
- purple_request_field_group_add_field(group, field);
- for (iter = 0; yd->profiles[iter]; iter++) {
- purple_request_field_choice_add(field, yd->profiles[iter]);
- if (purple_strequal(yd->profiles[iter], name))
- purple_request_field_choice_set_default_value(field, iter);
- purple_request_fields(gc, NULL, _("Select the ID you want to activate"), NULL,
- _("OK"), G_CALLBACK(yahoo_act_id),
- purple_connection_get_account(gc), NULL, NULL,
-static void yahoo_show_chat_goto(PurplePluginAction *action)
- PurpleConnection *gc = (PurpleConnection *) action->context;
- purple_request_input(gc, NULL, _("Join whom in chat?"), NULL,
- "", FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(yahoo_chat_goto),
- purple_connection_get_account(gc), NULL, NULL,
-GList *yahoo_actions(PurplePlugin *plugin, gpointer context) {
- PurplePluginAction *act;
- act = purple_plugin_action_new(_("Set User Info..."),
- yahoo_set_userinfo_fn);
- m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Activate ID..."),
- m = g_list_append(m, act);
- act = purple_plugin_action_new(_("Join User in Chat..."),
- m = g_list_append(m, act);
- m = g_list_append(m, NULL);
- act = purple_plugin_action_new(_("Open Inbox"),
- m = g_list_append(m, act);
-struct yahoo_sms_carrier_cb_data {
-static void yahoo_get_sms_carrier_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *webdata, size_t len, const gchar *error_message)
- struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data;
- PurpleConnection *gc = sms_cb_data->gc;
- YahooData *yd = gc->proto_data;
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL) {
- purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- g_free(sms_cb_data->who);
- g_free(sms_cb_data->what);
- else if (len > 0 && webdata && *webdata) {
- xmlnode *validate_data_root = xmlnode_from_str(webdata, -1);
- xmlnode *validate_data_child = xmlnode_get_child(validate_data_root, "mobile_no");
- const char *mobile_no = xmlnode_get_attrib(validate_data_child, "msisdn");
- validate_data_root = xmlnode_copy(validate_data_child);
- validate_data_child = xmlnode_get_child(validate_data_root, "status");
- status = xmlnode_get_data(validate_data_child);
- validate_data_child = xmlnode_get_child(validate_data_root, "carrier");
- carrier = xmlnode_get_data(validate_data_child);
- purple_debug_info("yahoo", "SMS validate data: %s\n", webdata);
- if (status && g_str_equal(status, "Valid")) {
- g_hash_table_insert(yd->sms_carrier,
- g_strdup_printf("+%s", mobile_no), g_strdup(carrier));
- yahoo_send_im(sms_cb_data->gc, sms_cb_data->who,
- sms_cb_data->what, PURPLE_MESSAGE_SEND);
- g_hash_table_insert(yd->sms_carrier,
- g_strdup_printf("+%s", mobile_no), g_strdup("Unknown"));
- purple_conversation_write(conv, NULL,
- _("Can't send SMS. Unknown mobile carrier."),
- PURPLE_MESSAGE_SYSTEM, time(NULL));
- xmlnode_free(validate_data_child);
- xmlnode_free(validate_data_root);
- g_free(sms_cb_data->who);
- g_free(sms_cb_data->what);
-static void yahoo_get_sms_carrier(PurpleConnection *gc, gpointer data)
- YahooData *yd = gc->proto_data;
- PurpleUtilFetchUrlData *url_data;
- struct yahoo_sms_carrier_cb_data *sms_cb_data;
- char *validate_request_str = NULL;
- gboolean use_whole_url = FALSE;
- xmlnode *validate_request_root = NULL;
- xmlnode *validate_request_child = NULL;
- if(!(sms_cb_data = data))
- validate_request_root = xmlnode_new("validate");
- xmlnode_set_attrib(validate_request_root, "intl", "us");
- xmlnode_set_attrib(validate_request_root, "version", YAHOO_CLIENT_VERSION);
- xmlnode_set_attrib(validate_request_root, "qos", "0");
- validate_request_child = xmlnode_new_child(validate_request_root, "mobile_no");
- xmlnode_set_attrib(validate_request_child, "msisdn", sms_cb_data->who + 1);
- validate_request_str = xmlnode_to_str(validate_request_root, NULL);
- xmlnode_free(validate_request_child);
- xmlnode_free(validate_request_root);
- request = g_strdup_printf(
- "POST /mobileno?intl=us&version=%s HTTP/1.1\r\n"
- "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s; path=/; domain=.yahoo.com;\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Host: validate.msg.yahoo.com\r\n"
- "Content-Length: %" G_GSIZE_FORMAT "\r\n"
- "Cache-Control: no-cache\r\n\r\n%s",
- YAHOO_CLIENT_VERSION, yd->cookie_t, yd->cookie_y, strlen(validate_request_str), validate_request_str);
- /* use whole URL if using HTTP Proxy */
- if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP))
- url_data = purple_util_fetch_url_request_len_with_account(
- purple_connection_get_account(gc), YAHOO_SMS_CARRIER_URL, use_whole_url,
- YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
- yahoo_get_sms_carrier_cb, data);
- g_free(validate_request_str);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
- purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- g_free(sms_cb_data->who);
- g_free(sms_cb_data->what);
-int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt = NULL;
- char *msg = yahoo_html_to_codes(what);
- struct yahoo_p2p_data *p2p_data;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- msg2 = yahoo_string_encode(gc, msg, &utf8);
- lenc = g_utf8_strlen(msg2, -1);
- if(lenb > YAHOO_MAX_MESSAGE_LENGTH_BYTES || lenc > YAHOO_MAX_MESSAGE_LENGTH_CHARS) {
- purple_debug_info("yahoo", "Message too big. Length is %" G_GSIZE_FORMAT
- " bytes, %ld characters. Max is %d bytes, %d chars."
- " Message is '%s'.\n", lenb, lenc, YAHOO_MAX_MESSAGE_LENGTH_BYTES,
- YAHOO_MAX_MESSAGE_LENGTH_CHARS, msg2);
- fed = yahoo_get_federation_from_name(who);
- /* we have an sms to be sent */
- const char *alias = NULL;
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, account);
- carrier = g_hash_table_lookup(yd->sms_carrier, who);
- struct yahoo_sms_carrier_cb_data *sms_cb_data;
- sms_cb_data = g_malloc(sizeof(struct yahoo_sms_carrier_cb_data));
- sms_cb_data->who = g_strdup(who);
- sms_cb_data->what = g_strdup(what);
- purple_conversation_write(conv, NULL, _("Getting mobile carrier to send the SMS."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- yahoo_get_sms_carrier(gc, sms_cb_data);
- else if( strcmp(carrier,"Unknown") == 0 ) {
- purple_conversation_write(conv, NULL, _("Can't send SMS. Unknown mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- alias = purple_account_get_alias(account);
- pkt = yahoo_packet_new(YAHOO_SERVICE_SMS_MSG, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssss",
- 1, purple_connection_get_display_name(gc),
- yahoo_packet_send_and_free(pkt, yd);
- pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id);
- case YAHOO_FEDERATION_MSN:
- case YAHOO_FEDERATION_OCS:
- case YAHOO_FEDERATION_IBM:
- case YAHOO_FEDERATION_PBX:
- case YAHOO_FEDERATION_NONE:
- yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, fed_who);
- yahoo_packet_hash_int(pkt, 241, fed);
- yahoo_packet_hash_str(pkt, 97, "1");
- yahoo_packet_hash_str(pkt, 14, msg2);
- * If this message is to a user who is also Doodling with the local user,
- * format the chat packet with the correct IMV information (thanks Yahoo!)
- * Otherwise attempt to use the same IMVironment as the remote user,
- * just so that we don't inadvertantly reset their IMVironment back
- * If they have not set an IMVironment, then use the default.
- wb = purple_whiteboard_get_session(gc->account, who);
- yahoo_packet_hash_str(pkt, 63, DOODLE_IMV_KEY);
- imv = g_hash_table_lookup(yd->imvironments, who);
- yahoo_packet_hash_str(pkt, 63, imv);
- yahoo_packet_hash_str(pkt, 63, ";0");
- yahoo_packet_hash_str(pkt, 64, "0"); /* no idea */
- yahoo_packet_hash_str(pkt, 1002, "1"); /* no idea, Yahoo 6 or later only it seems */
- yahoo_packet_hash_str(pkt, 206, "0"); /* 0 = no picture, 2 = picture, maybe 1 = avatar? */
- yahoo_packet_hash_str(pkt, 206, "2");
- /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */
- if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) {
- /* if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p */
- if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !fed) {
- yahoo_packet_hash_int(pkt, 11, p2p_data->session_id);
- yahoo_p2p_write_pkt(p2p_data->source, pkt);
- yahoo_packet_send(pkt, yd);
- yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */
- yahoo_packet_free(pkt);
-unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
- YahooData *yd = gc->proto_data;
- struct yahoo_p2p_data *p2p_data;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- struct yahoo_packet *pkt = NULL;
- fed = yahoo_get_federation_from_name(who);
- /* Don't do anything if sms is being typed */
- if( strncmp(who, "+", 1) == 0 )
- pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, yd->session_id);
- /* check to see if p2p link exists, send through it */
- if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !fed) {
- yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc),
- 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
- 5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */
- yahoo_p2p_write_pkt(p2p_data->source, pkt);
- yahoo_packet_free(pkt);
- else { /* send through yahoo server */
- const char *fed_who = who;
- case YAHOO_FEDERATION_MSN:
- case YAHOO_FEDERATION_OCS:
- case YAHOO_FEDERATION_IBM:
- case YAHOO_FEDERATION_PBX:
- case YAHOO_FEDERATION_NONE:
- yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc),
- 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
- 5, fed_who, 1002, "1");
- yahoo_packet_hash_int(pkt, 241, fed);
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_session_presence_remove(gpointer key, gpointer value, gpointer data)
- YahooFriend *f = value;
- if (f && f->presence == YAHOO_PRESENCE_ONLINE)
- f->presence = YAHOO_PRESENCE_DEFAULT;
-void yahoo_set_status(PurpleAccount *account, PurpleStatus *status)
- PurplePresence *presence;
- struct yahoo_packet *pkt;
- const char *msg = NULL;
- if (!purple_status_is_active(status))
- gc = purple_account_get_connection(account);
- presence = purple_status_get_presence(status);
- yd = (YahooData *)gc->proto_data;
- old_status = yd->current_status;
- yd->current_status = get_yahoo_status_from_purple_status(status);
- if (yd->current_status == YAHOO_STATUS_CUSTOM)
- msg = purple_status_get_attr_string(status, "message");
- if (purple_status_is_available(status)) {
- tmp = yahoo_string_encode(gc, msg, &utf8);
- conv_msg = purple_markup_strip_html(tmp);
- if ((msg == NULL) || (*msg == '\0'))
- tmp = yahoo_string_encode(gc, msg, &utf8);
- conv_msg = purple_markup_strip_html(tmp);
- if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 13, "2");
- yahoo_packet_send_and_free(pkt, yd);
- pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_int(pkt, 10, yd->current_status);
- if (yd->current_status == YAHOO_STATUS_CUSTOM) {
- yahoo_packet_hash_str(pkt, 97, utf8 ? "1" : 0);
- yahoo_packet_hash_str(pkt, 19, conv_msg);
- yahoo_packet_hash_str(pkt, 19, "");
- if (purple_presence_is_idle(presence))
- yahoo_packet_hash_str(pkt, 47, "2");
- if (!purple_status_is_available(status))
- yahoo_packet_hash_str(pkt, 47, "1");
- yahoo_packet_hash_str(pkt, 47, "0");
- yahoo_packet_send_and_free(pkt, yd);
- if (old_status == YAHOO_STATUS_INVISIBLE) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 13, "1");
- yahoo_packet_send_and_free(pkt, yd);
- /* Any per-session presence settings are removed */
- g_hash_table_foreach(yd->friends, yahoo_session_presence_remove, NULL);
-void yahoo_set_idle(PurpleConnection *gc, int idle)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt = NULL;
- char *msg = NULL, *msg2 = NULL;
- PurpleStatus *status = NULL;
- gboolean invisible = FALSE;
- if (idle && yd->current_status != YAHOO_STATUS_CUSTOM)
- yd->current_status = YAHOO_STATUS_IDLE;
- else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) {
- status = purple_presence_get_active_status(purple_account_get_presence(purple_connection_get_account(gc)));
- yd->current_status = get_yahoo_status_from_purple_status(status);
- invisible = (yd->current_status == YAHOO_STATUS_INVISIBLE);
- pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- if (!idle && invisible)
- yahoo_packet_hash_int(pkt, 10, YAHOO_STATUS_AVAILABLE);
- yahoo_packet_hash_int(pkt, 10, yd->current_status);
- if (yd->current_status == YAHOO_STATUS_CUSTOM) {
- status = purple_presence_get_active_status(purple_account_get_presence(purple_connection_get_account(gc)));
- tmp = purple_status_get_attr_string(status, "message");
- msg = yahoo_string_encode(gc, tmp, &utf8);
- msg2 = purple_markup_strip_html(msg);
- yahoo_packet_hash_str(pkt, 97, utf8 ? "1" : 0);
- yahoo_packet_hash_str(pkt, 19, msg2);
- /* get_yahoo_status_from_purple_status() returns YAHOO_STATUS_CUSTOM for
- * the generic away state (YAHOO_STATUS_TYPE_AWAY) with no message */
- yahoo_packet_hash_str(pkt, 19, _("Away"));
- yahoo_packet_hash_str(pkt, 19, "");
- yahoo_packet_hash_str(pkt, 47, "2");
- else if (yd->current_status == YAHOO_STATUS_CUSTOM &&
- !purple_status_is_available(status))
- /* We are still unavailable in this case.
- * Make sure Yahoo knows that */
- yahoo_packet_hash_str(pkt, 47, "1");
- yahoo_packet_send_and_free(pkt, yd);
-GList *yahoo_status_types(PurpleAccount *account)
- PurpleStatusType *type;
- type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, YAHOO_STATUS_TYPE_AVAILABLE,
- NULL, TRUE, TRUE, FALSE,
- "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
- types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_AWAY,
- NULL, TRUE, TRUE, FALSE,
- "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_BRB, _("Be Right Back"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, YAHOO_STATUS_TYPE_BUSY,
- _("Busy"), TRUE, TRUE, FALSE,
- "message", _("Message"),
- purple_value_new(PURPLE_TYPE_STRING), NULL);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTATHOME, _("Not at Home"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTATDESK, _("Not at Desk"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_NOTINOFFICE, _("Not in Office"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_UNAVAILABLE, YAHOO_STATUS_TYPE_ONPHONE, _("On the Phone"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_EXTENDED_AWAY, YAHOO_STATUS_TYPE_ONVACATION, _("On Vacation"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_OUTTOLUNCH, _("Out to Lunch"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_AWAY, YAHOO_STATUS_TYPE_STEPPEDOUT, _("Stepped Out"), TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_INVISIBLE, YAHOO_STATUS_TYPE_INVISIBLE, NULL, TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new(PURPLE_STATUS_OFFLINE, YAHOO_STATUS_TYPE_OFFLINE, NULL, TRUE);
- types = g_list_append(types, type);
- type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, YAHOO_STATUS_TYPE_MOBILE, NULL, FALSE, FALSE, TRUE);
- types = g_list_append(types, type);
-void yahoo_keepalive(PurpleConnection *gc)
- struct yahoo_packet *pkt;
- YahooData *yd = gc->proto_data;
- time_t now = time(NULL);
- /* We're only allowed to send a ping once an hour or the servers will boot us */
- if ((now - yd->last_ping) >= PING_TIMEOUT) {
- /* The native client will only send PING or CHATPING */
- ycht_chat_send_keepalive(yd->ycht);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 109, purple_connection_get_display_name(gc));
- yahoo_packet_send_and_free(pkt, yd);
- pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_send_and_free(pkt, yd);
- if ((now - yd->last_keepalive) >= KEEPALIVE_TIMEOUT) {
- yd->last_keepalive = now;
- pkt = yahoo_packet_new(YAHOO_SERVICE_KEEPALIVE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 0, purple_connection_get_display_name(gc));
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
- YahooData *yd = (YahooData *)gc->proto_data;
- struct yahoo_packet *pkt;
- const char *group = NULL;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- fed_bname = bname = purple_buddy_get_name(buddy);
- if (!purple_privacy_check(purple_connection_get_account(gc), bname))
- fed = yahoo_get_federation_from_name(bname);
- if (fed != YAHOO_FEDERATION_NONE)
- g = purple_buddy_get_group(buddy);
- group = purple_group_get_name(g);
- group2 = yahoo_string_encode(gc, group, NULL);
- pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssssssisss",
- 1, purple_connection_get_display_name(gc),
- yahoo_packet_hash(pkt, "ssssssssss",
- 1, purple_connection_get_display_name(gc),
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
- YahooData *yd = (YahooData *)gc->proto_data;
- struct yahoo_packet *pkt;
- gboolean remove = TRUE;
- const char *bname, *gname;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- bname = purple_buddy_get_name(buddy);
- f = yahoo_friend_find(gc, bname);
- gname = purple_group_get_name(group);
- buddies = purple_find_buddies(purple_connection_get_account(gc), bname);
- for (l = buddies; l; l = l->next) {
- g = purple_buddy_get_group(l->data);
- if (purple_utf8_strcasecmp(gname, purple_group_get_name(g))) {
- g_hash_table_remove(yd->friends, bname);
- f = NULL; /* f no longer valid - Just making it clear */
- cg = yahoo_string_encode(gc, gname, NULL);
- pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id);
- case YAHOO_FEDERATION_MSN:
- case YAHOO_FEDERATION_OCS:
- case YAHOO_FEDERATION_IBM:
- case YAHOO_FEDERATION_NONE:
- yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc),
- yahoo_packet_hash_int(pkt, 241, fed);
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_add_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
- struct yahoo_packet *pkt;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- if (!who || who[0] == '\0')
- fed = yahoo_get_federation_from_name(who);
- pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssis", 1, purple_connection_get_display_name(gc), 7, who+4, 241, fed, 13, "1");
- yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), 7, who, 13, "1");
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_rem_deny(PurpleConnection *gc, const char *who) {
- YahooData *yd = (YahooData *)gc->proto_data;
- struct yahoo_packet *pkt;
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- if (!who || who[0] == '\0')
- fed = yahoo_get_federation_from_name(who);
- pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssis", 1, purple_connection_get_display_name(gc), 7, who+4, 241, fed, 13, "2");
- yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), 7, who, 13, "2");
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_set_permit_deny(PurpleConnection *gc)
- PurpleAccount *account;
- account = purple_connection_get_account(gc);
- switch (account->perm_deny)
- case PURPLE_PRIVACY_ALLOW_ALL:
- for (deny = account->deny; deny; deny = deny->next)
- yahoo_rem_deny(gc, deny->data);
- case PURPLE_PRIVACY_ALLOW_BUDDYLIST:
- case PURPLE_PRIVACY_ALLOW_USERS:
- case PURPLE_PRIVACY_DENY_USERS:
- case PURPLE_PRIVACY_DENY_ALL:
- for (deny = account->deny; deny; deny = deny->next)
- yahoo_add_deny(gc, deny->data);
-void yahoo_change_buddys_group(PurpleConnection *gc, const char *who,
- const char *old_group, const char *new_group)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- YahooFriend *f = yahoo_friend_find(gc, who);
- const char *temp = NULL;
- /* Step 0: If they aren't on the server list anyway,
- * don't bother letting the server know.
- /* If old and new are the same, we would probably
- * end up deleting the buddy, which would be bad.
- * This might happen because of the charset conversation.
- gpn = yahoo_string_encode(gc, new_group, NULL);
- gpo = yahoo_string_encode(gc, old_group, NULL);
- if (!strcmp(gpn, gpo)) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHGRP_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssissss", 1, purple_connection_get_display_name(gc),
- 302, "240", 300, "240", 7, temp, 241, f->fed, 224, gpo, 264, gpn, 301,
- yahoo_packet_hash(pkt, "ssssssss", 1, purple_connection_get_display_name(gc),
- 302, "240", 300, "240", 7, temp, 224, gpo, 264, gpn, 301,
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_rename_group(PurpleConnection *gc, const char *old_name,
- PurpleGroup *group, GList *moved_buddies)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- gpn = yahoo_string_encode(gc, purple_group_get_name(group), NULL);
- gpo = yahoo_string_encode(gc, old_name, NULL);
- if (!strcmp(gpn, gpo)) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc),
- yahoo_packet_send_and_free(pkt, yd);
-/********************************* Commands **********************************/
-yahoopurple_cmd_buzz(PurpleConversation *c, const gchar *cmd, gchar **args, gchar **error, void *data) {
- PurpleAccount *account = purple_conversation_get_account(c);
- return PURPLE_CMD_RET_FAILED;
- purple_prpl_send_attention(account->gc, c->name, YAHOO_BUZZ);
- return PURPLE_CMD_RET_OK;
-yahoopurple_cmd_chat_join(PurpleConversation *conv, const char *cmd,
- char **args, char **error, void *data)
- return PURPLE_CMD_RET_FAILED;
- gc = purple_conversation_get_gc(conv);
- purple_debug_info("yahoo", "Trying to join %s \n", args[0]);
- comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_replace(comp, g_strdup("room"), g_ascii_strdown(args[0], -1));
- g_hash_table_replace(comp, g_strdup("type"), g_strdup("Chat"));
- yahoo_c_join(gc, comp);
- g_hash_table_destroy(comp);
- return PURPLE_CMD_RET_OK;
-yahoopurple_cmd_chat_list(PurpleConversation *conv, const char *cmd,
- char **args, char **error, void *data)
- PurpleAccount *account = purple_conversation_get_account(conv);
- return PURPLE_CMD_RET_FAILED;
- purple_roomlist_show_with_account(account);
- return PURPLE_CMD_RET_OK;
-gboolean yahoo_offline_message(const PurpleBuddy *buddy)
-gboolean yahoo_send_attention(PurpleConnection *gc, const char *username, guint type)
- c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- username, gc->account);
- g_return_val_if_fail(c != NULL, FALSE);
- purple_debug_info("yahoo", "Sending <ding> on account %s to buddy %s.\n",
- purple_conv_im_send_with_flags(PURPLE_CONV_IM(c), "<ding>", PURPLE_MESSAGE_INVISIBLE);
-GList *yahoo_attention_types(PurpleAccount *account)
- static GList *list = NULL;
- /* Yahoo only supports one attention command: the 'buzz'. */
- /* This is index number YAHOO_BUZZ. */
- list = g_list_append(list, purple_attention_type_new("Buzz", _("Buzz"),
- _("%s has buzzed you!"), _("Buzzing %s...")));
--- a/libpurple/protocols/yahoo/libymsg.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
- * @file libymsg.h The Yahoo! and Yahoo! JAPAN Protocol Plugins
- * 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
- * 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
-#define YAHOO_PAGER_HOST_REQ_URL "http://vcs2.msg.yahoo.com/capacity"
-#define YAHOO_PAGER_HOST_FALLBACK "scsa.msg.yahoo.com"
-#define YAHOO_PAGER_PORT 5050
-#define YAHOO_PAGER_PORT_P2P 5101
-#define YAHOO_LOGIN_URL "https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=%s"
-#define YAHOO_TOKEN_URL "https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=%s&passwd=%s&chal=%s"
-#define YAHOO_P2P_KEEPALIVE_SECS 300
-#define YAHOO_P2P_SERVER_TIMEOUT 10
-#define YAHOO_PROFILE_URL "http://profiles.yahoo.com/"
-#define YAHOO_MAIL_URL "http://rd.yahoo.com/messenger/client/?http://mail.yahoo.com/"
-#define YAHOO_XFER_HOST "filetransfer.msg.yahoo.com"
-#define YAHOO_XFER_PORT 80
-#define YAHOO_XFER_RELAY_HOST "relay.msg.yahoo.com"
-#define YAHOO_XFER_RELAY_PORT 80
-#define YAHOO_ROOMLIST_URL "http://insider.msg.yahoo.com/ycontent/"
-#define YAHOO_ROOMLIST_LOCALE "us"
-/* Yahoo! JAPAN stuff */
-#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.yahoo.co.jp/capacity"
-#define YAHOOJP_TOKEN_URL "https://login.yahoo.co.jp/config/pwtoken_get?src=ymsgr&ts=&login=%s&passwd=%s&chal=%s"
-#define YAHOOJP_LOGIN_URL "https://login.yahoo.co.jp/config/pwtoken_login?src=ymsgr&ts=&token=%s"
-#define YAHOOJP_PROFILE_URL "http://profiles.yahoo.co.jp/"
-#define YAHOOJP_MAIL_URL "http://mail.yahoo.co.jp/"
-#define YAHOOJP_XFER_HOST "filetransfer.msg.yahoo.co.jp"
-#define YAHOOJP_WEBCAM_HOST "wc.yahoo.co.jp"
-/* not sure, must test: */
-#define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.co.jp"
-#define YAHOOJP_XFER_RELAY_PORT 80
-#define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/"
-#define YAHOOJP_ROOMLIST_LOCALE "ja"
-#define YAHOO_AUDIBLE_URL "http://l.yimg.com/pu/dl/aud"
-#define WEBMESSENGER_URL "http://login.yahoo.com/config/login?.src=pg"
-#define YAHOO_SMS_CARRIER_URL "http://validate.msg.yahoo.com"
-#define YAHOO_USERINFO_URL "http://address.yahoo.com/yab/us?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
-#define YAHOOJP_USERINFO_URL "http://address.yahoo.co.jp/yab/jp?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
-#define YAHOO_PICURL_SETTING "picture_url"
-#define YAHOO_PICCKSUM_SETTING "picture_checksum"
-#define YAHOO_PICEXPIRE_SETTING "picture_expire"
-#define YAHOO_STATUS_TYPE_OFFLINE "offline"
-#define YAHOO_STATUS_TYPE_AVAILABLE "available"
-#define YAHOO_STATUS_TYPE_BRB "brb"
-#define YAHOO_STATUS_TYPE_BUSY "busy"
-#define YAHOO_STATUS_TYPE_NOTATHOME "notathome"
-#define YAHOO_STATUS_TYPE_NOTATDESK "notatdesk"
-#define YAHOO_STATUS_TYPE_NOTINOFFICE "notinoffice"
-#define YAHOO_STATUS_TYPE_ONPHONE "onphone"
-#define YAHOO_STATUS_TYPE_ONVACATION "onvacation"
-#define YAHOO_STATUS_TYPE_OUTTOLUNCH "outtolunch"
-#define YAHOO_STATUS_TYPE_STEPPEDOUT "steppedout"
-#define YAHOO_STATUS_TYPE_AWAY "away"
-#define YAHOO_STATUS_TYPE_INVISIBLE "invisible"
-#define YAHOO_STATUS_TYPE_MOBILE "mobile"
-#define YAHOO_CLIENT_VERSION_ID "4194239"
-#define YAHOO_CLIENT_VERSION "9.0.0.2162"
-#define YAHOOJP_CLIENT_VERSION_ID "4186047"
-#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. */
- YAHOO_PKT_TYPE_SERVER = 0,
- YAHOO_P2P_WE_ARE_CLIENT =0,
- YAHOO_P2P_WE_ARE_SERVER
-} yahoo_p2p_connection_type;
- YAHOO_STATUS_AVAILABLE = 0,
- YAHOO_STATUS_NOTATHOME,
- YAHOO_STATUS_NOTATDESK,
- YAHOO_STATUS_NOTINOFFICE,
- YAHOO_STATUS_ONVACATION,
- YAHOO_STATUS_OUTTOLUNCH,
- YAHOO_STATUS_STEPPEDOUT,
- YAHOO_STATUS_INVISIBLE = 12,
- YAHOO_STATUS_CUSTOM = 99,
- YAHOO_STATUS_IDLE = 999,
- YAHOO_STATUS_WEBLOGIN = 0x5a55aa55,
- YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */
- YAHOO_STATUS_TYPING = 0x16,
- YAHOO_STATUS_DISCONNECTED = -1 /* 0xffffffff; in ymsg 15. doesnt mean the normal sense of 'disconnected' */
- * Yahoo federated networks. Key 241 in ymsg.
- * If it doesn't exist, it is on Yahoo's netowrk.
- * It if does exist, send to another IM network.
- YAHOO_FEDERATION_NONE = 0, /* No federation - Yahoo! network */
- YAHOO_FEDERATION_OCS = 1, /* LCS or OCS private networks */
- YAHOO_FEDERATION_MSN = 2, /* MSN or Windows Live network */
- YAHOO_FEDERATION_IBM = 9, /* IBM/Sametime network */
- YAHOO_FEDERATION_PBX = 100 /* Yahoo! Pingbox service */
-struct yahoo_buddy_icon_upload_data {
- yahoo_p2p_connection_type connection_type;
-typedef struct _YahooPersonalDetails {
- PurpleCircBuffer *txbuf;
- char **profiles; /* Multiple profiles can be associated with an account */
- YahooPersonalDetails ypd;
- * This is used to keep track of the IMVironment chosen
- * by people you talk to. We don't do very much with
- * this right now... but at least now if the remote user
- * selects an IMVironment we won't reset it back to the
- GHashTable *imvironments;
- GString *tmp_serv_blist, *tmp_serv_ilist, *tmp_serv_plist;
- unsigned int conf_id; /* just a counter */
- char *pending_chat_room;
- char *pending_chat_topic;
- char *pending_chat_goto;
- gboolean wm; /* connected w/ web messenger method */
- /* picture aka buddy icon stuff */
- /* ew. we have to check the icon before we connect,
- * but can't upload it til we're connected. */
- struct yahoo_buddy_icon_upload_data *picture_upload_todo;
- PurpleProxyConnectData *buddy_icon_connect_data;
- struct _YchtConn *ycht;
- * This linked list contains PurpleUtilFetchUrlData structs
- * for when we lookup people profile or photo information.
- GHashTable *xfer_peer_idstring_map;/* Hey, i dont know, but putting this HashTable next to friends gives a run time fault... */
- GSList *cookies;/* contains all cookies, including _y and _t */
- PurpleNetworkListenData *listen_data;
- * We may receive a list15 in multiple packets with no prior warning as to how many we'll be getting;
- * the server expects us to keep track of the group for which it is sending us contact names.
- char *current_list15_grp;
- GHashTable *peers; /* information about p2p data */
- int yahoo_local_p2p_server_fd;
- int yahoo_p2p_server_watcher;
- GHashTable *sms_carrier; /* sms carrier data */
- guint yahoo_p2p_server_timeout_handle;
-#define YAHOO_MAX_STATUS_MESSAGE_LENGTH (255)
- * Current Maximum Length for Instant Messages
- * This was found by experiment.
- * The YMSG protocol allows a message of up to 948 bytes, but the official client
- * limits to 800 characters. According to experiments I conducted, it seems that
- * the discrepancy is to allow some leeway for messages with mixed single- and
- * multi-byte characters, as I was able to send messages of 840 and 932 bytes
- * by using some multibyte characters (some random Chinese or Japanese characters,
- * to be precise). - rekkanoryo
-#define YAHOO_MAX_MESSAGE_LENGTH_BYTES 948
-#define YAHOO_MAX_MESSAGE_LENGTH_CHARS 800
-/* sometimes i wish prpls could #include things from other prpls. then i could just
- * use the routines from libfaim and not have to admit to knowing how they work. */
-#define yahoo_put16(buf, data) ( \
- (*(buf) = (unsigned char)((data)>>8)&0xff), \
- (*((buf)+1) = (unsigned char)(data)&0xff), \
-#define yahoo_get16(buf) ((((*(buf))<<8)&0xff00) + ((*((buf)+1)) & 0xff))
-#define yahoo_put32(buf, data) ( \
- (*((buf)) = (unsigned char)((data)>>24)&0xff), \
- (*((buf)+1) = (unsigned char)((data)>>16)&0xff), \
- (*((buf)+2) = (unsigned char)((data)>>8)&0xff), \
- (*((buf)+3) = (unsigned char)(data)&0xff), \
-#define yahoo_get32(buf) ((((*(buf))<<24)&0xff000000) + \
- (((*((buf)+1))<<16)&0x00ff0000) + \
- (((*((buf)+2))<< 8)&0x0000ff00) + \
- (((*((buf)+3) )&0x000000ff)))
-void yahoo_init_colorht(void);
-void yahoo_dest_colorht(void);
-char *yahoo_codes_to_html(const char *x);
- * This function takes a normal HTML message and converts it to the message
- * format used by Yahoo, which uses a frankensteinish combination of ANSI
- * escape codes and broken HTML.
- * It results in slightly different output than would be sent by official
- * Yahoo clients. The two main differences are:
- * 1. We always close all tags, whereas official Yahoo clients leave tags
- * dangling open at the end of each message (and the client treats them
- * 2. We always close inner tags first before closing outter tags.
- * For example, if you want to send this message:
- * <b> bold <i> bolditalic </i></b><i> italic </i>
- * Official Yahoo clients would send:
- * ESC[1m bold ESC[2m bolditalic ESC[x1m italic
- * ESC[1m bold ESC[2m bolditalic ESC[x2mESC[x1mESC[2m italic ESC[x2m
-char *yahoo_html_to_codes(const char *src);
-yahoo_account_use_http_proxy(PurpleConnection *conn);
- * Encode some text to send to the yahoo server.
- * @param gc The connection handle.
- * @param str The null terminated utf8 string to encode.
- * @param utf8 If not @c NULL, whether utf8 is okay or not.
- * Even if it is okay, we may not use it. If we
- * used it, we set this to @c TRUE, else to
- * @c FALSE. If @c NULL, false is assumed, and
- * it is not dereferenced.
- * @return The g_malloced string in the appropriate encoding.
-char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8);
- * Decode some text received from the server.
- * @param gc The gc handle.
- * @param str The null terminated string to decode.
- * @param utf8 Did the server tell us it was supposed to be utf8?
- * @return The decoded, utf-8 string, which must be g_free()'d.
-char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8);
-char *yahoo_convert_to_numeric(const char *str);
-YahooFederation yahoo_get_federation_from_name(const char *who);
-void yahoo_get_info(PurpleConnection *gc, const char *name);
-/* libymsg.h - these functions were formerly static but need not to be for the
- * new two-prpl model. */
-const char *yahoo_list_icon(PurpleAccount *a, PurpleBuddy *b);
-const char *yahoo_list_emblem(PurpleBuddy *b);
-char *yahoo_status_text(PurpleBuddy *b);
-void yahoo_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full);
-GList *yahoo_status_types(PurpleAccount *account);
-GList *yahoo_blist_node_menu(PurpleBlistNode *node);
-void yahoo_login(PurpleAccount *account);
-void yahoo_close(PurpleConnection *gc);
-int yahoo_send_im(PurpleConnection *gc, const char *who, const char *what, PurpleMessageFlags flags);
-unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state);
-void yahoo_set_status(PurpleAccount *account, PurpleStatus *status);
-void yahoo_set_idle(PurpleConnection *gc, int idle);
-void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g);
-void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group);
-void yahoo_add_deny(PurpleConnection *gc, const char *who);
-void yahoo_rem_deny(PurpleConnection *gc, const char *who);
-void yahoo_set_permit_deny(PurpleConnection *gc);
-void yahoo_keepalive(PurpleConnection *gc);
-void yahoo_change_buddys_group(PurpleConnection *gc, const char *who, const char *old_group, const char *new_group);
-void yahoo_rename_group(PurpleConnection *gc, const char *old_name, PurpleGroup *group, GList *moved_buddies);
-gboolean yahoo_offline_message(const PurpleBuddy *buddy);
-gboolean yahoo_send_attention(PurpleConnection *gc, const char *username, guint type);
-GList *yahoo_attention_types(PurpleAccount *account);
-GList *yahoo_actions(PurplePlugin *plugin, gpointer context);
-void yahoopurple_register_commands(void);
-PurpleCmdRet yahoopurple_cmd_buzz(PurpleConversation *c, const gchar *cmd, gchar **args, gchar **error, void *data);
-PurpleCmdRet yahoopurple_cmd_chat_join(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data);
-PurpleCmdRet yahoopurple_cmd_chat_list(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data);
-/* needed for xfer, thought theyd be useful for other enhancements later on
- Returns list of cookies stored in yahoo_data formatted as a single null terminated string
- returned value must be g_freed
-gchar* yahoo_get_cookies(PurpleConnection *gc);
-/* send p2p pkt containing our encoded ip, asking peer to connect to us */
-void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13);
-#endif /* _LIBYMSG_H_ */
--- a/libpurple/protocols/yahoo/util.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,986 +0,0 @@
- * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com>
- * (marv on irc.freenode.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
-#endif /* HAVE_CONFIG_H */
-yahoo_account_use_http_proxy(PurpleConnection *pc)
- PurpleAccount *account = purple_connection_get_account(pc);
- PurpleProxyInfo *ppi = NULL;
- PurpleProxyType type = PURPLE_PROXY_NONE;
- gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE);
- ppi = purple_proxy_get_setup(account);
- ppi = purple_proxy_get_setup(NULL);
- type = purple_proxy_info_get_type(ppi);
- return (type == PURPLE_PROXY_HTTP || type == PURPLE_PROXY_USE_ENVVAR);
- * Returns cookies formatted as a null terminated string for the given connection.
- * Must g_free return value.
- * TODO:will work, but must test for strict correctness
-gchar* yahoo_get_cookies(PurpleConnection *gc)
- cookies = ((YahooData*)(gc->proto_data))->cookies;
- t2 = g_strrstr(cur, ";expires=");
- t2 = g_strrstr(cur, "; expires=");
- ans = g_strdup_printf("%c=%s", cur[0], cur+2);
- ans = g_strdup_printf("%s; %c=%s", t1, cur[0], cur+2);
- t3 = strstr(t2+1, ";");
- ans = g_strdup_printf("%c=%s%s", cur[0], cur+2, t3);
- ans = g_strdup_printf("%s; %c=%s%s", t1, cur[0], cur+2, t3);
- ans = g_strdup_printf("%c=%s", cur[0], cur+2);
- ans = g_strdup_printf("%s; %c=%s", t1, cur[0], cur+2);
- tmp = g_slist_next(tmp);
- * Encode some text to send to the yahoo server.
- * @param gc The connection handle.
- * @param str The null terminated utf8 string to encode.
- * @param utf8 If not @c NULL, whether utf8 is okay or not.
- * Even if it is okay, we may not use it. If we
- * used it, we set this to @c TRUE, else to
- * @c FALSE. If @c NULL, false is assumed, and
- * it is not dereferenced.
- * @return The g_malloced string in the appropriate encoding.
-char *yahoo_string_encode(PurpleConnection *gc, const char *str, gboolean *utf8)
- YahooData *yd = gc->proto_data;
- const char *to_codeset;
- if (utf8 && *utf8) /* FIXME: maybe don't use utf8 if it'll fit in latin1 */
- to_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset", "ISO-8859-1");
- ret = g_convert_with_fallback(str, -1, to_codeset, "UTF-8", "?", NULL, NULL, &error);
- purple_debug_error("yahoo", "Could not convert %s from UTF-8 to "
- "%s: %d - %s\n", str ? str : "(null)", to_codeset,
- error->message ? error->message : "(null)");
- purple_debug_error("yahoo", "Could not convert %s from UTF-8 to "
- "%s: unkown error\n", str ? str : "(null)", to_codeset);
- * Decode some text received from the server.
- * @param gc The gc handle.
- * @param str The null terminated string to decode.
- * @param utf8 Did the server tell us it was supposed to be utf8?
- * @return The decoded, utf-8 string, which must be g_free()'d.
-char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8)
- YahooData *yd = gc->proto_data;
- const char *from_codeset;
- if (g_utf8_validate(str, -1, NULL))
- purple_debug_warning("yahoo", "Server told us a string was supposed "
- "to be UTF-8, but it was not. Will try another encoding.\n");
- from_codeset = "SHIFT_JIS";
- from_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset", "ISO-8859-1");
- ret = g_convert_with_fallback(str, -1, "UTF-8", from_codeset, NULL, NULL, NULL, &error);
- purple_debug_error("yahoo", "Could not convert %s from %s to "
- "UTF-8: %d - %s\n", str ? str : "(null)", from_codeset,
- error->code, error->message ? error->message : "(null)");
- purple_debug_error("yahoo", "Could not convert %s from %s to "
- "UTF-8: unkown error\n", str ? str : "(null)",
-char *yahoo_convert_to_numeric(const char *str)
- const unsigned char *p;
- gstr = g_string_sized_new(strlen(str) * 6 + 1);
- for (p = (unsigned char *)str; *p; p++) {
- g_string_append_printf(gstr, "&#%u;", *p);
- return g_string_free(gstr, FALSE);
- * The values in this hash table should probably be lowercase, since that's
- * what xhtml expects. Also because yahoo_codes_to_html() does
- * case-sensitive comparisons.
- * I found these on some website but i don't know that they actually
- * work (or are supposed to work). I didn't implement them yet.
- * [0;38m ---light black
- * (shift+comma)lyellow(shift+period) ---light yellow
- * (shift+comma)lgreen(shift+period) ---light green
-static GHashTable *esc_codes_ht = NULL;
-static GHashTable *tags_ht = NULL;
-void yahoo_init_colorht()
- if (esc_codes_ht != NULL)
- /* Hash table has already been initialized */
- /* Key is the escape code string. Value is the HTML that should be
- * inserted in place of the escape code. */
- esc_codes_ht = g_hash_table_new(g_str_hash, g_str_equal);
- /* Key is the name of the HTML tag, for example "font" or "/font"
- * value is the HTML that should be inserted in place of the old tag */
- tags_ht = g_hash_table_new(g_str_hash, g_str_equal);
- /* the numbers in comments are what gyach uses, but i think they're incorrect */
-#ifdef USE_CSS_FORMATTING
- g_hash_table_insert(esc_codes_ht, "30", "<span style=\"color: #000000\">"); /* black */
- g_hash_table_insert(esc_codes_ht, "31", "<span style=\"color: #0000FF\">"); /* blue */
- g_hash_table_insert(esc_codes_ht, "32", "<span style=\"color: #008080\">"); /* cyan */ /* 00b2b2 */
- g_hash_table_insert(esc_codes_ht, "33", "<span style=\"color: #808080\">"); /* gray */ /* 808080 */
- g_hash_table_insert(esc_codes_ht, "34", "<span style=\"color: #008000\">"); /* green */ /* 00c200 */
- g_hash_table_insert(esc_codes_ht, "35", "<span style=\"color: #FF0080\">"); /* pink */ /* ffafaf */
- g_hash_table_insert(esc_codes_ht, "36", "<span style=\"color: #800080\">"); /* purple */ /* b200b2 */
- g_hash_table_insert(esc_codes_ht, "37", "<span style=\"color: #FF8000\">"); /* orange */ /* ffff00 */
- g_hash_table_insert(esc_codes_ht, "38", "<span style=\"color: #FF0000\">"); /* red */
- g_hash_table_insert(esc_codes_ht, "39", "<span style=\"color: #808000\">"); /* olive */ /* 546b50 */
- g_hash_table_insert(esc_codes_ht, "30", "<font color=\"#000000\">"); /* black */
- g_hash_table_insert(esc_codes_ht, "31", "<font color=\"#0000FF\">"); /* blue */
- g_hash_table_insert(esc_codes_ht, "32", "<font color=\"#008080\">"); /* cyan */ /* 00b2b2 */
- g_hash_table_insert(esc_codes_ht, "33", "<font color=\"#808080\">"); /* gray */ /* 808080 */
- g_hash_table_insert(esc_codes_ht, "34", "<font color=\"#008000\">"); /* green */ /* 00c200 */
- g_hash_table_insert(esc_codes_ht, "35", "<font color=\"#FF0080\">"); /* pink */ /* ffafaf */
- g_hash_table_insert(esc_codes_ht, "36", "<font color=\"#800080\">"); /* purple */ /* b200b2 */
- g_hash_table_insert(esc_codes_ht, "37", "<font color=\"#FF8000\">"); /* orange */ /* ffff00 */
- g_hash_table_insert(esc_codes_ht, "38", "<font color=\"#FF0000\">"); /* red */
- g_hash_table_insert(esc_codes_ht, "39", "<font color=\"#808000\">"); /* olive */ /* 546b50 */
-#endif /* !USE_CSS_FORMATTING */
- g_hash_table_insert(esc_codes_ht, "1", "<b>");
- g_hash_table_insert(esc_codes_ht, "x1", "</b>");
- g_hash_table_insert(esc_codes_ht, "2", "<i>");
- g_hash_table_insert(esc_codes_ht, "x2", "</i>");
- g_hash_table_insert(esc_codes_ht, "4", "<u>");
- g_hash_table_insert(esc_codes_ht, "x4", "</u>");
- /* these just tell us the text they surround is supposed
- * to be a link. purple figures that out on its own so we
- g_hash_table_insert(esc_codes_ht, "l", ""); /* link start */
- g_hash_table_insert(esc_codes_ht, "xl", ""); /* link end */
-#ifdef USE_CSS_FORMATTING
- g_hash_table_insert(tags_ht, "black", "<span style=\"color: #000000\">");
- g_hash_table_insert(tags_ht, "blue", "<span style=\"color: #0000FF\">");
- g_hash_table_insert(tags_ht, "cyan", "<span style=\"color: #008284\">");
- g_hash_table_insert(tags_ht, "gray", "<span style=\"color: #848284\">");
- g_hash_table_insert(tags_ht, "green", "<span style=\"color: #008200\">");
- g_hash_table_insert(tags_ht, "pink", "<span style=\"color: #FF0084\">");
- g_hash_table_insert(tags_ht, "purple", "<span style=\"color: #840084\">");
- g_hash_table_insert(tags_ht, "orange", "<span style=\"color: #FF8000\">");
- g_hash_table_insert(tags_ht, "red", "<span style=\"color: #FF0000\">");
- g_hash_table_insert(tags_ht, "yellow", "<span style=\"color: #848200\">");
- g_hash_table_insert(tags_ht, "/black", "</span>");
- g_hash_table_insert(tags_ht, "/blue", "</span>");
- g_hash_table_insert(tags_ht, "/cyan", "</span>");
- g_hash_table_insert(tags_ht, "/gray", "</span>");
- g_hash_table_insert(tags_ht, "/green", "</span>");
- g_hash_table_insert(tags_ht, "/pink", "</span>");
- g_hash_table_insert(tags_ht, "/purple", "</span>");
- g_hash_table_insert(tags_ht, "/orange", "</span>");
- g_hash_table_insert(tags_ht, "/red", "</span>");
- g_hash_table_insert(tags_ht, "/yellow", "</span>");
- g_hash_table_insert(tags_ht, "black", "<font color=\"#000000\">");
- g_hash_table_insert(tags_ht, "blue", "<font color=\"#0000FF\">");
- g_hash_table_insert(tags_ht, "cyan", "<font color=\"#008284\">");
- g_hash_table_insert(tags_ht, "gray", "<font color=\"#848284\">");
- g_hash_table_insert(tags_ht, "green", "<font color=\"#008200\">");
- g_hash_table_insert(tags_ht, "pink", "<font color=\"#FF0084\">");
- g_hash_table_insert(tags_ht, "purple", "<font color=\"#840084\">");
- g_hash_table_insert(tags_ht, "orange", "<font color=\"#FF8000\">");
- g_hash_table_insert(tags_ht, "red", "<font color=\"#FF0000\">");
- g_hash_table_insert(tags_ht, "yellow", "<font color=\"#848200\">");
- g_hash_table_insert(tags_ht, "/black", "</font>");
- g_hash_table_insert(tags_ht, "/blue", "</font>");
- g_hash_table_insert(tags_ht, "/cyan", "</font>");
- g_hash_table_insert(tags_ht, "/gray", "</font>");
- g_hash_table_insert(tags_ht, "/green", "</font>");
- g_hash_table_insert(tags_ht, "/pink", "</font>");
- g_hash_table_insert(tags_ht, "/purple", "</font>");
- g_hash_table_insert(tags_ht, "/orange", "</font>");
- g_hash_table_insert(tags_ht, "/red", "</font>");
- g_hash_table_insert(tags_ht, "/yellow", "</font>");
-#endif /* !USE_CSS_FORMATTING */
- /* We don't support these tags, so discard them */
- g_hash_table_insert(tags_ht, "alt", "");
- g_hash_table_insert(tags_ht, "fade", "");
- g_hash_table_insert(tags_ht, "snd", "");
- g_hash_table_insert(tags_ht, "/alt", "");
- g_hash_table_insert(tags_ht, "/fade", "");
- /* Official clients don't seem to send b, i or u tags. They use
- * the escape codes listed above. Official clients definitely send
- * font tags, though. I wonder if we can remove the opening and
- * closing b, i and u tags from here? */
- g_hash_table_insert(tags_ht, "b", "<b>");
- g_hash_table_insert(tags_ht, "i", "<i>");
- g_hash_table_insert(tags_ht, "u", "<u>");
- g_hash_table_insert(tags_ht, "font", "<font>");
- g_hash_table_insert(tags_ht, "/b", "</b>");
- g_hash_table_insert(tags_ht, "/i", "</i>");
- g_hash_table_insert(tags_ht, "/u", "</u>");
- g_hash_table_insert(tags_ht, "/font", "</font>");
-void yahoo_dest_colorht()
- if (esc_codes_ht == NULL)
- /* Hash table has already been destroyed */
- g_hash_table_destroy(esc_codes_ht);
- g_hash_table_destroy(tags_ht);
-#ifndef USE_CSS_FORMATTING
-static int point_to_html(int x)
-#endif /* !USE_CSS_FORMATTING */
-static void append_attrs_datalist_foreach_cb(GQuark key_id, gpointer data, gpointer user_data)
- key = g_quark_to_string(key_id);
- xmlnode_set_attrib(cur, key, value);
- * @param cur A pointer to the position in the XML tree that we're
- * currently building. This will be modified when opening a tag
- * or closing an existing tag.
-static void yahoo_codes_to_html_add_tag(xmlnode **cur, const char *tag, gboolean is_closing_tag, const gchar *tag_name, gboolean is_font_tag)
- GSList *dangling_tags = NULL;
- /* Move up the DOM until we find the opening tag */
- for (tmp = *cur; tmp != NULL; tmp = xmlnode_get_parent(tmp)) {
- /* Add one to tag_name when doing this comparison because it starts with a / */
- if (g_str_equal(tmp->name, tag_name + 1))
- dangling_tags = g_slist_prepend(dangling_tags, tmp);
- /* This is a closing tag with no opening tag. Useless. */
- purple_debug_error("yahoo", "Ignoring unmatched tag %s", tag);
- g_slist_free(dangling_tags);
- /* Move our current position up, now that we've closed a tag */
- *cur = xmlnode_get_parent(tmp);
- /* Re-open any tags that were nested below the tag we just closed */
- while (dangling_tags != NULL) {
- tmp = dangling_tags->data;
- dangling_tags = g_slist_delete_link(dangling_tags, dangling_tags);
- /* Create a copy of this tag+attributes (but not child tags or
- * data) at our new location */
- *cur = xmlnode_new_child(*cur, tmp->name);
- for (tmp = tmp->child; tmp != NULL; tmp = tmp->next)
- if (tmp->type == XMLNODE_TYPE_ATTRIB)
- xmlnode_set_attrib_full(*cur, tmp->name,
- tmp->xmlns, tmp->prefix, tmp->data);
- if (!purple_markup_find_tag(tag_name, tag, &start, &end, &attributes))
- *cur = xmlnode_new_child(*cur, tag_name);
- /* Special case for the font size attribute */
- fontsize = g_strdup(g_datalist_get_data(&attributes, "size"));
- g_datalist_remove_data(&attributes, "size");
- /* Add all font tag attributes */
- g_datalist_foreach(&attributes, append_attrs_datalist_foreach_cb, *cur);
- g_datalist_clear(&attributes);
- if (fontsize != NULL) {
-#ifdef USE_CSS_FORMATTING
- * The Yahoo font size value is given in pt, even though the HTML
- * standard for <font size="x"> treats the size as a number on a
- * scale between 1 and 7. So we insert the font size as a CSS
- gchar *tmp = g_strdup_printf("font-size: %spt", fontsize);
- *cur = xmlnode_new_child(*cur, "span");
- xmlnode_set_attrib(*cur, "style", tmp);
- * The Yahoo font size value is given in pt, even though the HTML
- * standard for <font size="x"> treats the size as a number on a
- * scale between 1 and 7. So we convert it to an appropriate
- * value. This loses precision, which is why CSS formatting is
- * preferred. The "absz" attribute remains here for backward
- * compatibility with UIs that might use it, but it is totally
- size = strtol(fontsize, NULL, 10);
- htmlsize = point_to_html(size);
- sprintf(tmp, "%u", htmlsize);
- xmlnode_set_attrib(*cur, "size", tmp);
- xmlnode_set_attrib(*cur, "absz", fontsize);
-#endif /* !USE_CSS_FORMATTING */
- * Similar to purple_markup_get_tag_name(), but works with closing tags.
- * @return The lowercase name of the tag. If this is a closing tag then
- * this value starts with a forward slash. The caller must free
- * this string with g_free.
-static gchar *yahoo_markup_get_tag_name(const char *tag, gboolean *is_closing_tag)
- *is_closing_tag = (tag[1] == '/');
- len = strcspn(tag + 1, "> ");
- len = strcspn(tag + 1, "> /");
- return g_utf8_strdown(tag + 1, len);
- * Yahoo! messages generally aren't well-formed. Their markup is
- * more of a flow from start to finish rather than a hierarchy from
- * outer to inner. They tend to open tags and close them only when
- * Example: <font size="8">size 8 <font size="16">size 16 <font size="8">size 8 again
- * But we want to send well-formed HTML to the core, so we step through
- * the input string and build an xmlnode tree containing sanitized HTML.
-char *yahoo_codes_to_html(const char *x)
- GString *cdata = g_string_new(NULL);
- gboolean no_more_gt_brackets = FALSE;
- gchar *xmlstr1, *xmlstr2, *esc;
- html = xmlnode_new("html");
- for (i = 0; i < x_len; i++) {
- if ((x[i] == 0x1b) && (x[i+1] == '[')) {
- /* This escape sequence signifies the beginning of some
- * text formatting code */
- /* Keep looking for the end of this sequence */
- /* We've reached the end of the formatting sequence, yay */
- /* Append any character data that belongs in the current node */
- xmlnode_insert_data(cur, cdata->str, cdata->len);
- g_string_truncate(cdata, 0);
- code = g_strndup(x + i + 2, j - i - 2);
-#ifdef USE_CSS_FORMATTING
- gchar *tmp = g_strdup_printf("color: %s", code);
- cur = xmlnode_new_child(cur, "span");
- xmlnode_set_attrib(cur, "style", tmp);
- cur = xmlnode_new_child(cur, "font");
- xmlnode_set_attrib(cur, "color", code);
-#endif /* !USE_CSS_FORMATTING */
- } else if ((match = g_hash_table_lookup(esc_codes_ht, code))) {
- /* Some tags are in the hash table only because we
- * want to ignore them */
- if (match[0] != '\0') {
- gboolean is_closing_tag;
- tag_name = yahoo_markup_get_tag_name(match, &is_closing_tag);
- yahoo_codes_to_html_add_tag(&cur, match, is_closing_tag, tag_name, FALSE);
- purple_debug_error("yahoo",
- "Ignoring unknown ansi code 'ESC[%sm'.\n", code);
- } else if (x[i] == '<' && !no_more_gt_brackets) {
- /* The start of an HTML tag */
- gboolean is_closing_tag;
- /* We're inside a quoted attribute value. Skip to the end */
- while (j != x_len && x[j] != '"')
- } else if (x[j] == '\'') {
- /* We're inside a quoted attribute value. Skip to the end */
- while (j != x_len && x[j] != '\'')
- /* Keep looking for the end of this tag */
- /* This < has no corresponding > */
- g_string_append_c(cdata, x[i]);
- no_more_gt_brackets = TRUE;
- tag = g_strndup(x + i, j - i + 1);
- tag_name = yahoo_markup_get_tag_name(tag, &is_closing_tag);
- match = g_hash_table_lookup(tags_ht, tag_name);
- /* Unknown tag. The user probably typed a less-than sign */
- g_string_append_c(cdata, x[i]);
- /* Some tags are in the hash table only because we
- * want to ignore them */
- if (match[0] != '\0') {
- /* Append any character data that belongs in the current node */
- xmlnode_insert_data(cur, cdata->str, cdata->len);
- g_string_truncate(cdata, 0);
- if (g_str_equal(tag_name, "font"))
- /* Font tags are a special case. We don't
- * necessarily want to replace the whole thing--
- * we just want to fix the size attribute. */
- yahoo_codes_to_html_add_tag(&cur, tag, is_closing_tag, tag_name, TRUE);
- yahoo_codes_to_html_add_tag(&cur, match, is_closing_tag, tag_name, FALSE);
- g_string_append_c(cdata, x[i]);
- /* Append any remaining character data */
- xmlnode_insert_data(cur, cdata->str, cdata->len);
- g_string_free(cdata, TRUE);
- /* Serialize our HTML */
- xmlstr1 = xmlnode_to_str(html, NULL);
- /* Strip off the outter HTML node */
- /* This probably isn't necessary, especially if we made the outter HTML
- * node an empty span. But the HTML is simpler this way. */
- if (!purple_strequal(xmlstr1, "<html/>"))
- xmlstr2 = g_strndup(xmlstr1 + 6, strlen(xmlstr1) - 13);
- xmlstr2 = g_strdup("");
- esc = g_strescape(x, NULL);
- purple_debug_misc("yahoo", "yahoo_codes_to_html(%s)=%s\n", esc, xmlstr2);
-/* borrowed from gtkimhtml */
-#define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1])
-static const gint _point_sizes [] = { 8, 10, 12, 14, 20, 30, 40 };
-static void yahoo_htc_list_cleanup(GSList *l)
- l = g_slist_delete_link(l, l);
-static void parse_font_tag(GString *dest, const char *tag_name, const char *tag,
- GSList **colors, GSList **tags)
- if (!purple_markup_find_tag(tag_name, tag, &start, &end, &attributes))
- tmp = g_string_new(NULL);
- attribute = g_datalist_get_data(&attributes, "color");
- if (attribute != NULL) {
- g_string_append(tmp, *colors ? (*colors)->data : "\033[#000000m");
- g_string_append_printf(dest, "\033[%sm", attribute);
- *colors = g_slist_prepend(*colors,
- g_strdup_printf("\033[%sm", attribute));
- /* We need to add a value to the colors stack even if we're not
- * setting a color because we ALWAYS pop exactly 1 element from
- * this stack for every </font> tag. If we don't add anything
- * then we'll pop something that we shouldn't when we hit this
- * corresponding </font>. */
- *colors = g_slist_prepend(*colors,
- *colors ? g_strdup((*colors)->data) : g_strdup("\033[#000000m"));
- attribute = g_datalist_get_data(&attributes, "face");
- if (attribute != NULL) {
- g_string_append(dest, "<font ");
- g_string_append_printf(dest, "face=\"%s\" ", attribute);
- attribute = g_datalist_get_data(&attributes, "size");
- if (attribute != NULL) {
- g_string_append(dest, "<font ");
- g_string_append_printf(dest, "size=\"%d\" ",
- POINT_SIZE(strtol(attribute, NULL, 10)));
- dest->str[dest->len-1] = '>';
- *tags = g_slist_prepend(*tags, g_strdup("</font>"));
- g_string_free(tmp, TRUE);
- *tags = g_slist_prepend(*tags, tmp->str);
- g_string_free(tmp, FALSE);
- g_datalist_clear(&attributes);
-char *yahoo_html_to_codes(const char *src)
- * A stack of char*s where each char* is the string that should be
- * appended to dest in order to close all the tags that were opened
- gboolean no_more_gt_brackets = FALSE;
- gboolean is_closing_tag;
- CurrentMsgState current_state;
- memset(¤t_state, 0, sizeof(current_state));
- dest = g_string_sized_new(src_len);
- for (i = 0; i < src_len; i++) {
- if (src[i] == '<' && !no_more_gt_brackets) {
- /* The start of an HTML tag */
- while (j++ < src_len) {
- /* We're inside a quoted attribute value. Skip to the end */
- while (j != src_len && src[j] != '"')
- } else if (src[j] == '\'') {
- /* We're inside a quoted attribute value. Skip to the end */
- while (j != src_len && src[j] != '\'')
- /* Keep looking for the end of this tag */
- /* This < has no corresponding > */
- g_string_append_c(dest, src[i]);
- no_more_gt_brackets = TRUE;
- tag = g_strndup(src + i, j - i + 1);
- tag_name = yahoo_markup_get_tag_name(tag, &is_closing_tag);
- if (g_str_equal(tag_name, "a")) {
- * TODO: Ideally we would replace this:
- * <a href="http://pidgin.im/">Pidgin</a>
- * Pidgin (http://pidgin.im/)
- * Currently we drop the text within the <a> tag and
- * just show the URL. Doing it the fancy way is
- * complicated when dealing with HTML tags within the
- if (!purple_markup_find_tag(tag_name,
- tag, &start, &end, &attributes))
- attribute = g_datalist_get_data(&attributes, "href");
- if (attribute != NULL) {
- if (purple_str_has_prefix(attribute, "mailto:"))
- g_string_append(dest, attribute);
- g_datalist_clear(&attributes);
- /* Skip past the closing </a> tag */
- end = purple_strcasestr(src + j, "</a>");
- } else if (g_str_equal(tag_name, "font")) {
- parse_font_tag(dest, tag_name, tag, &colors, &tags);
- } else if (g_str_equal(tag_name, "b")) {
- g_string_append(dest, "\033[1m");
- current_state.bold = TRUE;
- } else if (g_str_equal(tag_name, "/b")) {
- if (current_state.bold) {
- g_string_append(dest, "\033[x1m");
- current_state.bold = FALSE;
- } else if (g_str_equal(tag_name, "i")) {
- current_state.italic = TRUE;
- g_string_append(dest, "\033[2m");
- } else if (g_str_equal(tag_name, "/i")) {
- if (current_state.italic) {
- g_string_append(dest, "\033[x2m");
- current_state.italic = FALSE;
- } else if (g_str_equal(tag_name, "u")) {
- current_state.underline = TRUE;
- g_string_append(dest, "\033[4m");
- } else if (g_str_equal(tag_name, "/u")) {
- if (current_state.underline) {
- g_string_append(dest, "\033[x4m");
- current_state.underline = FALSE;
- } else if (g_str_equal(tag_name, "/a")) {
- } else if (g_str_equal(tag_name, "br")) {
- g_string_append_c(dest, '\n');
- } else if (g_str_equal(tag_name, "/font")) {
- char *etag = tags->data;
- tags = g_slist_delete_link(tags, tags);
- g_string_append(dest, etag);
- colors = g_slist_delete_link(colors, colors);
- } else if (g_str_equal(tag_name, "span") || g_str_equal(tag_name, "/span")) {
- /* We don't know what the tag is. Send it unmodified. */
- g_string_append(dest, tag);
- entity = purple_markup_unescape_entity(src + i, &length);
- /* src[i] is the start of an HTML entity */
- g_string_append(dest, entity);
- /* src[i] is a normal character */
- g_string_append_c(dest, src[i]);
- esc = g_strescape(dest->str, NULL);
- purple_debug_misc("yahoo", "yahoo_html_to_codes(%s)=%s\n", src, esc);
- yahoo_htc_list_cleanup(colors);
- yahoo_htc_list_cleanup(tags);
- return g_string_free(dest, FALSE);
-YahooFederation yahoo_get_federation_from_name(const char *who)
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- if (!g_ascii_strncasecmp(who, "msn", 3))
- fed = YAHOO_FEDERATION_MSN;
- else if (!g_ascii_strncasecmp(who, "ocs", 3))
- fed = YAHOO_FEDERATION_OCS;
- else if (!g_ascii_strncasecmp(who, "ibm", 3))
- fed = YAHOO_FEDERATION_IBM;
- else if (!g_ascii_strncasecmp(who, "pbx", 3))
- fed = YAHOO_FEDERATION_PBX;
--- a/libpurple/protocols/yahoo/yahoo_aliases.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,729 +0,0 @@
- * 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
- * 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 "yahoo_aliases.h"
-#include "yahoo_friend.h"
-#include "yahoo_packet.h"
-/* I hate hardcoding this stuff, but Yahoo never sends us anything to use. Someone in the know may be able to tweak this URL */
-#define YAHOO_ALIAS_FETCH_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&diffs=1&t=0&tags=short&rt=0&prog-ver=" YAHOO_CLIENT_VERSION "&useutf8=1&legenc=codepage-1252"
-#define YAHOO_ALIAS_UPDATE_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252"
-#define YAHOOJP_ALIAS_FETCH_URL "http://address.yahoo.co.jp/yab/jp?v=XM&prog=ymsgr&.intl=jp&diffs=1&t=0&tags=short&rt=0&prog-ver=" YAHOOJP_CLIENT_VERSION
-#define YAHOOJP_ALIAS_UPDATE_URL "http://address.yahoo.co.jp/yab/jp?v=XM&prog=ymsgr&.intl=jp&sync=1&tags=short&noclear=1"
-void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
- * Stuff we want passed to the callback function
-void yahoo_personal_details_reset(YahooPersonalDetails *ypd, gboolean all)
- g_free(ypd->names.first);
- g_free(ypd->names.last);
- g_free(ypd->names.middle);
- g_free(ypd->names.nick);
- g_free(ypd->phone.work);
- g_free(ypd->phone.home);
- g_free(ypd->phone.mobile);
-/**************************************************************************
- * Alias Fetch Functions
- **************************************************************************/
-yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
- PurpleConnection *gc = user_data;
- YahooData *yd = gc->proto_data;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- purple_debug_info("yahoo", "No Aliases to process.%s%s\n",
- error_message ? " Error:" : "", error_message ? error_message : "");
- gchar *full_name, *nick_name;
- const char *yid, *id, *fn, *ln, *nn, *alias, *mn;
- const char *hp, *wp, *mo;
- xmlnode *item, *contacts;
- PurpleAccount *account;
- account = purple_connection_get_account(gc);
- /* Put our web response into a xmlnode for easy management */
- contacts = xmlnode_from_str(url_text, -1);
- if (contacts == NULL) {
- purple_debug_error("yahoo", "Badly formed Alias XML\n");
- purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT
- " bytes of alias data\n", len);
- /* Loop around and around and around until we have gone through all the received aliases */
- for(item = xmlnode_get_child(contacts, "ct"); item; item = xmlnode_get_next_twin(item)) {
- /* Yahoo replies with two types of contact (ct) record, we are only interested in the alias ones */
- if ((yid = xmlnode_get_attrib(item, "yi"))) {
- YahooPersonalDetails *ypd = NULL;
- /* Grab all the bits of information we can */
- fn = xmlnode_get_attrib(item, "fn");
- ln = xmlnode_get_attrib(item, "ln");
- nn = xmlnode_get_attrib(item, "nn");
- mn = xmlnode_get_attrib(item, "mn");
- id = xmlnode_get_attrib(item, "id");
- hp = xmlnode_get_attrib(item, "hp");
- wp = xmlnode_get_attrib(item, "wp");
- mo = xmlnode_get_attrib(item, "mo");
- full_name = nick_name = NULL;
- /* Yahoo stores first and last names separately, lets put them together into a full name */
- full_name = g_strstrip(g_strdup_printf("%s %s", (ln != NULL ? ln : "") , (fn != NULL ? fn : "")));
- full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : "")));
- nick_name = (nn != NULL ? g_strstrip(g_strdup(nn)) : NULL);
- alias = nick_name; /* If we have a nickname from Yahoo, let's use it */
- else if (strlen(full_name) != 0)
- alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */
- /* Find the local buddy that matches */
- f = yahoo_friend_find(gc, yid);
- b = purple_find_buddy(account, yid);
- /* If we don't find a matching buddy, ignore the alias !! */
- if (f != NULL && b != NULL) {
- const char *buddy_alias = purple_buddy_get_alias(b);
- yahoo_friend_set_alias_id(f, id);
- /* Finally, if we received an alias, we better update the buddy list */
- serv_got_alias(gc, yid, alias);
- purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
- } else if (buddy_alias && *buddy_alias && !g_str_equal(buddy_alias, yid)) {
- /* Or if we have an alias that Yahoo doesn't, send it up */
- yahoo_update_alias(gc, yid, buddy_alias);
- purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
- /* May be the alias is for the account? */
- const char *yidn = purple_normalize(account, yid);
- if (purple_strequal(yidn, purple_connection_get_display_name(gc))) {
- yahoo_personal_details_reset(ypd, TRUE);
- ypd->id = g_strdup(id);
- ypd->names.first = g_strdup(fn);
- ypd->names.middle = g_strdup(mn);
- ypd->names.last = g_strdup(ln);
- ypd->names.nick = g_strdup(nn);
- ypd->phone.work = g_strdup(wp);
- ypd->phone.home = g_strdup(hp);
- ypd->phone.mobile = g_strdup(mo);
- xmlnode_free(contacts);
-yahoo_fetch_aliases(PurpleConnection *gc)
- YahooData *yd = gc->proto_data;
- gchar *request, *webpage, *webaddress;
- PurpleUtilFetchUrlData *url_data;
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- /* Build all the info to make the web request */
- url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL;
- purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL);
- request = g_strdup_printf("GET %s%s/%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT_ALIAS "\r\n"
- "Cookie: T=%s; Y=%s\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage,
- yd->cookie_t, yd->cookie_y,
- /* We have a URL and some header information, let's connect and get some aliases */
- url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc),
- url, use_whole_url, NULL, TRUE, request, FALSE, -1,
- yahoo_fetch_aliases_cb, gc);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-/**************************************************************************
- * Alias Update Functions
- **************************************************************************/
-yahoo_update_alias_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
- xmlnode *node, *result;
- struct callback_data *cb = user_data;
- PurpleConnection *gc = cb->gc;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (len == 0 || error_message != NULL) {
- purple_debug_info("yahoo", "Error updating alias for %s: %s\n",
- error_message ? error_message : "");
- result = xmlnode_from_str(url_text, -1);
- purple_debug_error("yahoo", "Alias update for %s failed: Badly formed response\n",
- if ((node = xmlnode_get_child(result, "ct"))) {
- const char *new_id = xmlnode_get_attrib(node, "id");
- /* We now have an addressbook id for the friend; we should save it */
- YahooFriend *f = yahoo_friend_find(cb->gc, cb->who);
- purple_debug_info("yahoo", "Alias creation for %s succeeded\n", cb->who);
- yahoo_friend_set_alias_id(f, new_id);
- purple_debug_error("yahoo", "Missing YahooFriend. Unable to store new addressbook id.\n");
- purple_debug_error("yahoo", "Missing new addressbook id in add response for %s (weird).\n",
- if (g_ascii_strncasecmp(xmlnode_get_attrib(node, "id"), cb->id, strlen(cb->id))==0)
- purple_debug_info("yahoo", "Alias update for %s succeeded\n", cb->who);
- purple_debug_error("yahoo", "Alias update for %s failed (Contact record return mismatch)\n",
- purple_debug_info("yahoo", "Alias update for %s failed (No contact record returned)\n", cb->who);
-yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias)
- gchar *content, *request, *webpage, *webaddress;
- struct callback_data *cb;
- PurpleUtilFetchUrlData *url_data;
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- g_return_if_fail(who != NULL);
- g_return_if_fail(gc != NULL);
- f = yahoo_friend_find(gc, who);
- purple_debug_error("yahoo", "Missing YahooFriend. Unable to set server alias.\n");
- /* Using callback_data so I have access to gc in the callback function */
- cb = g_new0(struct callback_data, 1);
- cb->who = g_strdup(who);
- cb->id = g_strdup(yahoo_friend_get_alias_id(f));
- /* Build all the info to make the web request */
- url = yd->jp ? YAHOOJP_ALIAS_UPDATE_URL: YAHOO_ALIAS_UPDATE_URL;
- purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL);
- /* No id for this buddy, so create an address book entry */
- purple_debug_info("yahoo", "Creating '%s' as new alias for user '%s'\n", alias, who);
- gchar *alias_jp = g_convert(alias, -1, "EUC-JP", "UTF-8", NULL, NULL, NULL);
- gchar *converted_alias_jp = yahoo_convert_to_numeric(alias_jp);
- content = g_strdup_printf("<ab k=\"%s\" cc=\"9\">\n"
- "<ct a=\"1\" yi='%s' nn='%s' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
- who, converted_alias_jp);
- g_free(converted_alias_jp);
- gchar *escaped_alias = g_markup_escape_text(alias, -1);
- content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"9\">\n"
- "<ct a=\"1\" yi='%s' nn='%s' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
- purple_debug_info("yahoo", "Updating '%s' as new alias for user '%s'\n", alias, who);
- gchar *alias_jp = g_convert(alias, -1, "EUC-JP", "UTF-8", NULL, NULL, NULL);
- gchar *converted_alias_jp = yahoo_convert_to_numeric(alias_jp);
- content = g_strdup_printf("<ab k=\"%s\" cc=\"1\">\n"
- "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
- who, cb->id, converted_alias_jp);
- g_free(converted_alias_jp);
- gchar *escaped_alias = g_markup_escape_text(alias, -1);
- content = g_strdup_printf("<?xml version=\"1.0\" encoding=\"utf-8\"?><ab k=\"%s\" cc=\"1\">\n"
- "<ct e=\"1\" yi='%s' id='%s' nn='%s' pr='0' />\n</ab>\r\n",
- purple_account_get_username(gc->account),
- who, cb->id, escaped_alias);
- request = g_strdup_printf("POST %s%s/%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT_ALIAS "\r\n"
- "Cookie: T=%s; Y=%s\r\n"
- "Content-Length: %" G_GSIZE_FORMAT "\r\n"
- "Cache-Control: no-cache\r\n\r\n"
- use_whole_url ? "http://" : "", use_whole_url ? webaddress : "", webpage,
- yd->cookie_t, yd->cookie_y,
- /* We have a URL and some header information, let's connect and update the alias */
- url_data = purple_util_fetch_url_request_len_with_account(
- purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE,
- request, FALSE, -1, yahoo_update_alias_cb, cb);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-/**************************************************************************
- * User Info Update Functions
- **************************************************************************/
-/* This block of code can be used to send our contact details to
- * everyone in the buddylist. But with the official messenger,
- * doing this pops a conversation window at the receiver's end,
- * which is stupid, and thus not really surprising. */
-yahoo_send_userinfo_to_user(struct yahoo_userinfo *yui, const char *who)
- struct yahoo_packet *pkt;
- pkt = yahoo_packet_new(YAHOO_SERVICE_CONTACT_DETAILS, 0, 0);
- yahoo_packet_hash(pkt, "siisis",
- 1, purple_connection_get_display_name(gc),
- 13, 1, /* This creates a conversation window in the official client */
- yahoo_packet_send_and_free(pkt, yui->yd);
-yahoo_send_userinfo_foreach(gpointer key, gpointer value, gpointer data)
- YahooFriend *f = value;
- if (f->status != YAHOO_STATUS_OFFLINE) {
- yahoo_send_userinfo_to_user(data, who);
-yahoo_sent_userinfo_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
- struct yahoo_userinfo *yui = user_data;
- yahoo_fetch_aliases_cb(url_data, yui->yd->gc, url_text, len, error_message);
- g_hash_table_foreach(yui->yd->friends, yahoo_send_userinfo_foreach, yui);
-yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields)
- xmlnode *node = xmlnode_new("ab");
- xmlnode *ct = xmlnode_new_child(node, "ct");
- YahooData *yd = purple_connection_get_protocol_data(gc);
- PurpleAccount *account;
- PurpleUtilFetchUrlData *url_data;
- char *webaddress, *webpage;
- char *request, *content;
- char * yfields[] = { "fn", "ln", "nn", "mn", "hp", "wp", "mo", NULL };
- account = purple_connection_get_account(gc);
- xmlnode_set_attrib(node, "k", purple_connection_get_display_name(gc));
- xmlnode_set_attrib(node, "cc", "1"); /* XXX: ? */
- xmlnode_set_attrib(ct, "e", "1");
- xmlnode_set_attrib(ct, "yi", purple_request_fields_get_string(fields, "yname"));
- xmlnode_set_attrib(ct, "id", purple_request_fields_get_string(fields, "yid"));
- xmlnode_set_attrib(ct, "pr", "0");
- for (i = 0; yfields[i]; i++) {
- const char *v = purple_request_fields_get_string(fields, yfields[i]);
- xmlnode_set_attrib(ct, yfields[i], v ? v : "");
- content = xmlnode_to_formatted_str(node, &len);
- purple_url_parse(yd->jp ? YAHOOJP_USERINFO_URL : YAHOO_USERINFO_URL, &webaddress, NULL, &webpage, NULL, NULL);
- request = g_strdup_printf("POST %s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT_ALIAS "\r\n"
- "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n"
- "Content-Length: %d\r\n"
- "Cache-Control: no-cache\r\n\r\n"
- yd->cookie_t, yd->cookie_y,
- /* This is if we wanted to send our contact details to everyone
- * in the buddylist. But this cannot be done now, because in the
- * official messenger, doing this pops a conversation window at
- * the receiver's end, which is stupid, and thus not really
- struct yahoo_userinfo *ui = g_new(struct yahoo_userinfo, 1);
- node = xmlnode_new("contact");
- for (i = 0; yfields[i]; i++) {
- const char *v = purple_request_fields_get_string(fields, yfields[i]);
- xmlnode *nd = xmlnode_new_child(node, yfields[i]);
- xmlnode_insert_data(nd, v, -1);
- ui->xml = xmlnode_to_str(node, NULL);
- url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE,
- YAHOO_CLIENT_USERAGENT_ALIAS, TRUE, request, FALSE, -1,
- yahoo_fetch_aliases_cb, gc);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
-static PurpleRequestFields *
-request_fields_from_personal_details(YahooPersonalDetails *ypd, const char *id)
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
- {"fn", N_("First Name"), ypd->names.first},
- {"ln", N_("Last Name"), ypd->names.last},
- {"nn", N_("Nickname"), ypd->names.nick},
- {"mn", N_("Middle Name"), ypd->names.middle},
- {"hp", N_("Home Phone Number"), ypd->phone.home},
- {"wp", N_("Work Phone Number"), ypd->phone.work},
- {"mo", N_("Mobile Phone Number"), ypd->phone.mobile},
- fields = purple_request_fields_new();
- group = purple_request_field_group_new(NULL);
- purple_request_fields_add_group(fields, group);
- field = purple_request_field_string_new("yname", "", id, FALSE);
- purple_request_field_set_visible(field, FALSE);
- purple_request_field_group_add_field(group, field);
- field = purple_request_field_string_new("yid", "", ypd->id, FALSE);
- purple_request_field_set_visible(field, FALSE);
- purple_request_field_group_add_field(group, field);
- for (i = 0; yfields[i].id; i++) {
- field = purple_request_field_string_new(yfields[i].id, _(yfields[i].text),
- yfields[i].value, FALSE);
- purple_request_field_group_add_field(group, field);
-void yahoo_set_userinfo_for_buddy(PurpleConnection *gc, PurpleBuddy *buddy)
- PurpleRequestFields *fields;
- name = purple_buddy_get_name(buddy);
- f = yahoo_friend_find(gc, name);
- fields = request_fields_from_personal_details(&f->ypd, name);
- purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
- _("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
- purple_connection_get_account(gc), NULL, NULL, gc);
-void yahoo_set_userinfo(PurpleConnection *gc)
- YahooData *yd = purple_connection_get_protocol_data(gc);
- PurpleRequestFields *fields = request_fields_from_personal_details(&yd->ypd,
- purple_connection_get_display_name(gc));
- purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
- _("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
- purple_connection_get_account(gc), NULL, NULL, gc);
-parse_contact_details(YahooData *yd, const char *who, const char *xml)
- node = xmlnode_from_str(xml, -1);
- purple_debug_info("yahoo", "Received malformed XML for contact details from '%s':\n%s\n",
- nd = xmlnode_get_child(node, "yi");
- if (!nd || !(yid = xmlnode_get_data(nd))) {
- if (!purple_strequal(yid, who)) {
- /* The user may not want to set the contact details about folks in the buddylist
- to what some random dude might have sent. So it would be good if we popped
- up a prompt requiring the user to confirm the details before we set them.
- However, someone could send details about hundreds of users at the same time,
- which would make things really bad. So for now, until we have a better way of
- dealing with this, ignore this details. */
- purple_debug_info("yahoo", "Ignoring contact details sent by %s about %s\n",
- f = yahoo_friend_find(yd->gc, yid);
- YahooPersonalDetails *ypd = &f->ypd;
- {"fn", &ypd->names.first},
- {"mn", &ypd->names.middle},
- {"ln", &ypd->names.last},
- {"nn", &ypd->names.nick},
- {"wp", &ypd->phone.work},
- {"hp", &ypd->phone.home},
- {"mo", &ypd->phone.mobile},
- yahoo_personal_details_reset(ypd, FALSE);
- for (i = 0; details[i].id; i++) {
- nd = xmlnode_get_child(node, details[i].id);
- *details[i].field = nd ? xmlnode_get_data(nd) : NULL;
- alias = ypd->names.nick;
- else if (ypd->names.first || ypd->names.last) {
- alias = g_strstrip(g_strdup_printf("%s %s",
- ypd->names.first ? ypd->names.first : "",
- ypd->names.last ? ypd->names.last : ""));
- serv_got_alias(yd->gc, yid, alias);
- if (alias != ypd->names.nick)
-/* I don't think this happens for MSN buddies. -- sad */
-void yahoo_process_contact_details(PurpleConnection *gc, struct yahoo_packet *pkt)
- const char *who = NULL, *xml = NULL;
- YahooData *yd = purple_connection_get_protocol_data(gc);
- for (; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- /* This is the person who sent us the details.
- But not necessarily about himself. */
- purple_debug_warning("yahoo", "yahoo_process_contact_details "
- "got non-UTF-8 string for key %d\n", pair->key);
- /* This is '1' if 'who' is sending the contact details about herself,
- '0' if 'who' is sending the contact details she has about buddies
- in her list. However, in all cases, the xml in key 280 always seems
- to contain the yid of the person, so we may as well ignore this field
- and look into the xml instead to see who the information is about. */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- parse_contact_details(yd, who, xml);
- purple_debug_warning("yahoo", "yahoo_process_contact_details "
- "got non-UTF-8 string for key %d\n", pair->key);
--- a/libpurple/protocols/yahoo/yahoo_aliases.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
- * 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
- * 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 "yahoo_packet.h"
-void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
-void yahoo_fetch_aliases(PurpleConnection *gc);
-void yahoo_set_userinfo(PurpleConnection *gc);
-void yahoo_set_userinfo_for_buddy(PurpleConnection *gc, PurpleBuddy *buddy);
-void yahoo_personal_details_reset(YahooPersonalDetails *ypd, gboolean all);
-void yahoo_process_contact_details(PurpleConnection *gc, struct yahoo_packet *pkt);
--- a/libpurple/protocols/yahoo/yahoo_doodle.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,609 +0,0 @@
- * 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
- * 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 "yahoo_packet.h"
-#include "yahoo_friend.h"
-#include "yahoo_filexfer.h"
-#include "yahoo_picture.h"
-#include "yahoo_doodle.h"
-/******************************************************************************
- *****************************************************************************/
-const int DefaultColorRGB24[] =
-/******************************************************************************
- *****************************************************************************/
-PurpleCmdRet yahoo_doodle_purple_cmd_start(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data)
- PurpleAccount *account;
- return PURPLE_CMD_RET_FAILED;
- account = purple_conversation_get_account(conv);
- gc = purple_account_get_connection(account);
- name = purple_conversation_get_name(conv);
- yahoo_doodle_initiate(gc, name);
- /* Write a local message to this conversation showing that a request for a
- * Doodle session has been made
- purple_conv_im_write(PURPLE_CONV_IM(conv), "", _("Sent Doodle request."),
- PURPLE_MESSAGE_NICK | PURPLE_MESSAGE_RECV, time(NULL));
- return PURPLE_CMD_RET_OK;
-void yahoo_doodle_initiate(PurpleConnection *gc, const char *name)
- PurpleAccount *account;
- char *to = (char*)name;
- g_return_if_fail(name);
- account = purple_connection_get_account(gc);
- if(purple_whiteboard_get_session(account, to) == NULL)
- /* Insert this 'session' in the list. At this point, it's only a
- purple_whiteboard_create(account, to, DOODLE_STATE_REQUESTING);
- /* NOTE Perhaps some careful handling of remote assumed established
- yahoo_doodle_command_send_ready(gc, to, DOODLE_IMV_KEY);
- yahoo_doodle_command_send_request(gc, to, DOODLE_IMV_KEY);
-static void yahoo_doodle_command_got_request(PurpleConnection *gc, const char *from, const char *imv_key)
- PurpleAccount *account;
- purple_debug_info("yahoo", "doodle: Got Request (%s)\n", from);
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- /* If a session with the remote user doesn't exist */
- /* Ask user if they wish to accept the request for a doodle session */
- /* TODO Ask local user to start Doodle session with remote user */
- /* NOTE This if/else statement won't work right--must use dialog
- /* char dialog_message[64];
- g_sprintf(dialog_message, "%s is requesting to start a Doodle session with you.", from);
- purple_notify_message(NULL, PURPLE_NOTIFY_MSG_INFO, "Doodle",
- dialog_message, NULL, NULL, NULL);
- wb = purple_whiteboard_create(account, from, DOODLE_STATE_REQUESTED);
- ds->imv_key = g_strdup(imv_key);
- yahoo_doodle_command_send_ready(gc, from, imv_key);
- /* TODO Might be required to clear the canvas of an existing doodle
- * session at this point
-static void yahoo_doodle_command_got_ready(PurpleConnection *gc, const char *from, const char *imv_key)
- PurpleAccount *account;
- purple_debug_info("yahoo", "doodle: Got Ready(%s)\n", from);
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- if(wb->state == DOODLE_STATE_REQUESTING)
- doodle_session *ds = wb->proto_data;
- purple_whiteboard_start(wb);
- wb->state = DOODLE_STATE_ESTABLISHED;
- yahoo_doodle_command_send_confirm(gc, from, imv_key);
- /* Let's steal the imv_key and reuse it */
- ds->imv_key = g_strdup(imv_key);
- else if(wb->state == DOODLE_STATE_ESTABLISHED)
- /* TODO Ask whether to save picture too */
- purple_whiteboard_clear(wb);
- /* NOTE Not sure about this... I am trying to handle if the remote user
- * already thinks we're in a session with them (when their chat message
- * contains the doodle imv key)
- else if(wb->state == DOODLE_STATE_REQUESTED)
- /* purple_whiteboard_start(wb); */
- yahoo_doodle_command_send_ready(gc, from, imv_key);
-static void yahoo_doodle_command_got_draw(PurpleConnection *gc, const char *from, const char *message)
- PurpleAccount *account;
- GList *d_list = NULL; /* a local list of drawing info */
- g_return_if_fail(message != NULL);
- purple_debug_info("yahoo", "doodle: Got Draw (%s)\n", from);
- purple_debug_info("yahoo", "doodle: Draw message: %s\n", message);
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- * Convert drawing packet message to an integer list
- /* Check to see if the message begans and ends with quotes */
- if((message[0] != '\"') || (message[strlen(message) - 1] != '\"'))
- /* Ignore the inital quotation mark. */
- tokens = g_strsplit(message, ",", 0);
- /* Traverse and extract all integers divided by commas */
- for (i = 0; tokens[i] != NULL; i++)
- int last = strlen(tokens[i]) - 1;
- if (tokens[i][last] == '"')
- tokens[i][last] = '\0';
- d_list = g_list_prepend(d_list, GINT_TO_POINTER(atoi(tokens[i])));
- d_list = g_list_reverse(d_list);
- yahoo_doodle_draw_stroke(wb, d_list);
- /* goodle_doodle_session_set_canvas_as_icon(ds); */
-static void yahoo_doodle_command_got_clear(PurpleConnection *gc, const char *from)
- PurpleAccount *account;
- purple_debug_info("yahoo", "doodle: Got Clear (%s)\n", from);
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- if(wb->state == DOODLE_STATE_ESTABLISHED)
- /* TODO Ask user whether to save the image before clearing it */
- purple_whiteboard_clear(wb);
-yahoo_doodle_command_got_extra(PurpleConnection *gc, const char *from, const char *message, const char *imv_key)
- purple_debug_info("yahoo", "doodle: Got Extra (%s)\n", from);
- /* I do not like these 'extra' features, so I'll only handle them in one
- * way, which is returning them with the command/packet to turn them off
- yahoo_doodle_command_send_extra(gc, from, DOODLE_EXTRA_NONE, imv_key);
-static void yahoo_doodle_command_got_confirm(PurpleConnection *gc, const char *from)
- PurpleAccount *account;
- purple_debug_info("yahoo", "doodle: Got Confirm (%s)\n", from);
- /* Get the doodle session */
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- /* TODO Combine the following IF's? */
- /* Check if we requested a doodle session */
- /*if(wb->state == DOODLE_STATE_REQUESTING)
- wb->state = DOODLE_STATE_ESTABLISHED;
- purple_whiteboard_start(wb);
- yahoo_doodle_command_send_confirm(gc, from);
- /* Check if we accepted a request for a doodle session */
- if(wb->state == DOODLE_STATE_REQUESTED)
- wb->state = DOODLE_STATE_ESTABLISHED;
- purple_whiteboard_start(wb);
-void yahoo_doodle_command_got_shutdown(PurpleConnection *gc, const char *from)
- PurpleAccount *account;
- g_return_if_fail(from != NULL);
- purple_debug_info("yahoo", "doodle: Got Shutdown (%s)\n", from);
- account = purple_connection_get_account(gc);
- /* Only handle this if local client requested Doodle session (else local
- * client would have sent one)
- wb = purple_whiteboard_get_session(account, from);
- /* TODO Ask if user wants to save picture before the session is closed */
- wb->state = DOODLE_STATE_CANCELLED;
- purple_whiteboard_destroy(wb);
-static void yahoo_doodle_command_send_generic(const char *type,
- struct yahoo_packet *pkt;
- purple_debug_info("yahoo", "doodle: Sent %s (%s)\n", type, to);
- /* Make and send an acknowledge (ready) Doodle packet */
- pkt = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 49, "IMVIRONMENT");
- yahoo_packet_hash_str(pkt, 1, purple_account_get_username(gc->account));
- yahoo_packet_hash_str(pkt, 14, message);
- yahoo_packet_hash_int(pkt, 13, command);
- yahoo_packet_hash_str(pkt, 5, to);
- yahoo_packet_hash_str(pkt, 63, imv ? imv : DOODLE_IMV_KEY);
- yahoo_packet_hash_str(pkt, 64, sixtyfour);
- yahoo_packet_hash_str(pkt, 1002, "1");
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to, const char *imv_key)
- yahoo_doodle_command_send_generic("Ready", gc, to, "1", DOODLE_CMD_READY, imv_key, "1");
-void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to, const char *imv_key)
- yahoo_doodle_command_send_generic("Request", gc, to, "", DOODLE_CMD_REQUEST, imv_key, "0");
-void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message, const char *imv_key)
- yahoo_doodle_command_send_generic("Draw", gc, to, message, DOODLE_CMD_DRAW, imv_key, "1");
-void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to, const char *imv_key)
- yahoo_doodle_command_send_generic("Clear", gc, to, " ", DOODLE_CMD_CLEAR, imv_key, "1");
-void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message, const char *imv_key)
- yahoo_doodle_command_send_generic("Extra", gc, to, message, DOODLE_CMD_EXTRA, imv_key, "1");
-void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to, const char *imv_key)
- yahoo_doodle_command_send_generic("Confirm", gc, to, "1", DOODLE_CMD_CONFIRM, imv_key, "1");
-void yahoo_doodle_command_send_shutdown(PurpleConnection *gc, const char *to)
- yahoo_doodle_command_send_generic("Shutdown", gc, to, "", DOODLE_CMD_SHUTDOWN, ";0", "0");
-void yahoo_doodle_start(PurpleWhiteboard *wb)
- doodle_session *ds = g_new0(doodle_session, 1);
- /* purple_debug_debug("yahoo", "doodle: yahoo_doodle_start()\n"); */
- /* Set default brush size and color */
- ds->brush_size = DOODLE_BRUSH_SMALL;
- ds->brush_color = DOODLE_COLOR_RED;
-void yahoo_doodle_end(PurpleWhiteboard *wb)
- PurpleConnection *gc = purple_account_get_connection(wb->account);
- doodle_session *ds = wb->proto_data;
- /* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
- if (gc && wb->state != DOODLE_STATE_CANCELLED)
- yahoo_doodle_command_send_shutdown(gc, wb->who);
- g_free(wb->proto_data);
-void yahoo_doodle_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height)
- /* standard Doodle canvases are of one size: 368x256 */
- *width = DOODLE_CANVAS_WIDTH;
- *height = DOODLE_CANVAS_HEIGHT;
-static char *yahoo_doodle_build_draw_string(doodle_session *ds, GList *draw_list)
- g_return_val_if_fail(draw_list != NULL, NULL);
- message = g_string_new("");
- g_string_printf(message, "\"%d,%d", ds->brush_color, ds->brush_size);
- for(; draw_list != NULL; draw_list = draw_list->next)
- g_string_append_printf(message, ",%d", GPOINTER_TO_INT(draw_list->data));
- g_string_append_c(message, '"');
- return g_string_free(message, FALSE);
-void yahoo_doodle_send_draw_list(PurpleWhiteboard *wb, GList *draw_list)
- doodle_session *ds = wb->proto_data;
- g_return_if_fail(draw_list != NULL);
- message = yahoo_doodle_build_draw_string(ds, draw_list);
- yahoo_doodle_command_send_draw(wb->account->gc, wb->who, message, ds->imv_key);
-void yahoo_doodle_clear(PurpleWhiteboard *wb)
- doodle_session *ds = wb->proto_data;
- yahoo_doodle_command_send_clear(wb->account->gc, wb->who, ds->imv_key);
-/* Traverse through the list and draw the points and lines */
-void yahoo_doodle_draw_stroke(PurpleWhiteboard *wb, GList *draw_list)
- g_return_if_fail(draw_list != NULL);
- brush_color = GPOINTER_TO_INT(draw_list->data);
- draw_list = draw_list->next;
- g_return_if_fail(draw_list != NULL);
- brush_size = GPOINTER_TO_INT(draw_list->data);
- draw_list = draw_list->next;
- g_return_if_fail(draw_list != NULL);
- x = GPOINTER_TO_INT(draw_list->data);
- draw_list = draw_list->next;
- g_return_if_fail(draw_list != NULL);
- y = GPOINTER_TO_INT(draw_list->data);
- draw_list = draw_list->next;
- g_return_if_fail(draw_list != NULL);
- purple_debug_debug("yahoo", "doodle: Drawing: color=%d, size=%d, (%d,%d)\n", brush_color, brush_size, x, y);
- while(draw_list != NULL && draw_list->next != NULL)
- int dx = GPOINTER_TO_INT(draw_list->data);
- int dy = GPOINTER_TO_INT(draw_list->next->data);
- purple_whiteboard_draw_line(wb,
- brush_color, brush_size);
- draw_list = draw_list->next->next;
-void yahoo_doodle_get_brush(const PurpleWhiteboard *wb, int *size, int *color)
- doodle_session *ds = wb->proto_data;
- *size = ds->brush_size;
- *color = ds->brush_color;
-void yahoo_doodle_set_brush(PurpleWhiteboard *wb, int size, int color)
- doodle_session *ds = wb->proto_data;
- ds->brush_color = color;
- /* Notify the core about the changes */
- purple_whiteboard_set_brush(wb, size, color);
-void yahoo_doodle_process(PurpleConnection *gc, const char *me, const char *from,
- const char *command, const char *message, const char *imv_key)
- /* Now check to see what sort of Doodle message it is */
- case DOODLE_CMD_REQUEST:
- yahoo_doodle_command_got_request(gc, from, imv_key);
- yahoo_doodle_command_got_ready(gc, from, imv_key);
- yahoo_doodle_command_got_clear(gc, from);
- yahoo_doodle_command_got_draw(gc, from, message);
- yahoo_doodle_command_got_extra(gc, from, message, imv_key);
- case DOODLE_CMD_CONFIRM:
- yahoo_doodle_command_got_confirm(gc, from);
--- a/libpurple/protocols/yahoo/yahoo_doodle.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
- * @file yahoo_doodle.h The Yahoo! protocol plugin Doodle IMVironment object
- * 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
- * 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 _YAHOO_DOODLE_H_
-#define _YAHOO_DOODLE_H_
-/******************************************************************************
- *****************************************************************************/
-#define DOODLE_IMV_KEY "doodle;106"
-/******************************************************************************
- *****************************************************************************/
-/* Doodle communication commands */
-/* TODO: Should be an enum. */
-#define DOODLE_CMD_REQUEST 0
-#define DOODLE_CMD_CLEAR 1
-#define DOODLE_CMD_DRAW 2
-#define DOODLE_CMD_EXTRA 3
-#define DOODLE_CMD_READY 4
-#define DOODLE_CMD_CONFIRM 5
-/* Doodle communication command for shutting down (also 0) */
-#define DOODLE_CMD_SHUTDOWN 0
-#define DOODLE_EXTRA_NONE "\"1\""
-#define DOODLE_EXTRA_TICTACTOE "\"3\""
-#define DOODLE_EXTRA_DOTS "\"2\""
-/* Doodle session states */
-/* TODO: Should be an enum. */
-#define DOODLE_STATE_REQUESTING 0
-#define DOODLE_STATE_REQUESTED 1
-#define DOODLE_STATE_ESTABLISHED 2
-#define DOODLE_STATE_CANCELLED 3
-/* Doodle canvas dimensions */
-#define DOODLE_CANVAS_WIDTH 368
-#define DOODLE_CANVAS_HEIGHT 256
-/* Doodle color codes (most likely RGB) */
-/* TODO: Should be an enum and sorted by color name. */
-#define DOODLE_COLOR_RED 13369344
-#define DOODLE_COLOR_ORANGE 16737792
-#define DOODLE_COLOR_YELLOW 15658496
-#define DOODLE_COLOR_GREEN 52224
-#define DOODLE_COLOR_CYAN 52428
-#define DOODLE_COLOR_BLUE 204
-#define DOODLE_COLOR_VIOLET 5381277
-#define DOODLE_COLOR_PURPLE 13369548
-#define DOODLE_COLOR_TAN 12093547
-#define DOODLE_COLOR_BROWN 5256485
-#define DOODLE_COLOR_BLACK 0
-#define DOODLE_COLOR_GREY 11184810
-#define DOODLE_COLOR_WHITE 16777215
-#define PALETTE_NUM_OF_COLORS 12
-/* Doodle brush sizes (most likely variable) */
-#define DOODLE_BRUSH_SMALL 2
-#define DOODLE_BRUSH_MEDIUM 5
-#define DOODLE_BRUSH_LARGE 10
-#define DOODLE_MAX_BRUSH_MOTIONS 100
-/******************************************************************************
- *****************************************************************************/
-typedef struct _doodle_session
- int brush_size; /* Size of drawing brush */
- int brush_color; /* Color of drawing brush */
-/******************************************************************************
- *****************************************************************************/
-PurpleCmdRet yahoo_doodle_purple_cmd_start(PurpleConversation *conv, const char *cmd, char **args,
- char **error, void *data);
-void yahoo_doodle_process(PurpleConnection *gc, const char *me, const char *from,
- const char *command, const char *message, const char *imv_key);
-void yahoo_doodle_initiate(PurpleConnection *gc, const char *to);
-void yahoo_doodle_command_got_shutdown(PurpleConnection *gc, const char *from);
-void yahoo_doodle_command_send_request(PurpleConnection *gc, const char *to, const char *imv_key);
-void yahoo_doodle_command_send_ready(PurpleConnection *gc, const char *to, const char *imv_key);
-void yahoo_doodle_command_send_draw(PurpleConnection *gc, const char *to, const char *message, const char *imv_key);
-void yahoo_doodle_command_send_clear(PurpleConnection *gc, const char *to, const char *imv_key);
-void yahoo_doodle_command_send_extra(PurpleConnection *gc, const char *to, const char *message, const char *imv_key);
-void yahoo_doodle_command_send_confirm(PurpleConnection *gc, const char *to, const char *imv_key);
-void yahoo_doodle_command_send_shutdown(PurpleConnection *gc, const char *to);
-void yahoo_doodle_start(PurpleWhiteboard *wb);
-void yahoo_doodle_end(PurpleWhiteboard *wb);
-void yahoo_doodle_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height);
-void yahoo_doodle_send_draw_list(PurpleWhiteboard *wb, GList *draw_list);
-void yahoo_doodle_clear(PurpleWhiteboard *wb);
-void yahoo_doodle_draw_stroke(PurpleWhiteboard *wb, GList *draw_list);
-void yahoo_doodle_get_brush(const PurpleWhiteboard *wb, int *size, int *color);
-void yahoo_doodle_set_brush(PurpleWhiteboard *wb, int size, int color);
-#endif /* _YAHOO_DOODLE_H_ */
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2048 +0,0 @@
- * @file yahoo_filexfer.c Yahoo Filetransfer
- * 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
- * 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 "yahoo_packet.h"
-#include "yahoo_filexfer.h"
-#include "yahoo_doodle.h"
-#include "yahoo_friend.h"
-struct yahoo_xfer_data {
- gchar *xfer_peer_idstring;
- gchar *xfer_idstring_for_relay;
- int version; /* 0 for old, 15 for Y7(YMSG 15) */
- /* contains all filenames, in case of multiple transfers, with the first
- * one in the list being the current file's name (ymsg15) */
- GSList *size_list; /* corresponds to filename_list, with size as **STRING** */
- gchar *xfer_url; /* url of the file, used when we are p2p server */
- int yahoo_local_p2p_ft_server_fd;
- int yahoo_local_p2p_ft_server_port;
- int yahoo_p2p_ft_server_watcher;
-static void yahoo_xfer_data_free(struct yahoo_xfer_data *xd)
- /* remove entry from map */
- if(xd->xfer_peer_idstring) {
- xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map, xd->xfer_peer_idstring);
- g_hash_table_remove(yd->xfer_peer_idstring_map, xd->xfer_peer_idstring);
- /* empty file & filesize list */
- for (l = xd->filename_list; l; l = l->next) {
- for (l = xd->size_list; l; l = l->next) {
- g_slist_free(xd->filename_list);
- g_slist_free(xd->size_list);
- g_free(xd->xfer_peer_idstring);
- g_free(xd->xfer_idstring_for_relay);
- purple_input_remove(xd->tx_handler);
-static void yahoo_receivefile_send_cb(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_xfer_data *xd;
- int remaining, written;
- remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);
- purple_xfer_cancel_remote(xfer);
- if (written < remaining) {
- xd->txbuf_written += written;
- purple_input_remove(xd->tx_handler);
- purple_xfer_start(xfer, source, NULL, 0);
-static void yahoo_receivefile_connected(gpointer data, gint source, const gchar *error_message)
- struct yahoo_xfer_data *xd;
- purple_debug_info("yahoo", "in yahoo_receivefile_connected\n");
- if (!(xd = xfer->data))
- if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
- purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
- purple_xfer_cancel_remote(xfer);
- /* The first time we get here, assemble the tx buffer */
- if (xd->txbuflen == 0) {
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
- xd->txbuflen = strlen(xd->txbuf);
- xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE,
- yahoo_receivefile_send_cb, xfer);
- yahoo_receivefile_send_cb(xfer, source, PURPLE_INPUT_WRITE);
-static void yahoo_sendfile_send_cb(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_xfer_data *xd;
- int written, remaining;
- remaining = xd->txbuflen - xd->txbuf_written;
- written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);
- purple_xfer_cancel_remote(xfer);
- if (written < remaining) {
- xd->txbuf_written += written;
- purple_input_remove(xd->tx_handler);
- purple_xfer_start(xfer, source, NULL, 0);
-static void yahoo_sendfile_connected(gpointer data, gint source, const gchar *error_message)
- struct yahoo_xfer_data *xd;
- struct yahoo_packet *pkt;
- gchar *size, *filename, *encoded_filename, *header;
- size_t content_length, header_len, pkt_buf_len;
- PurpleAccount *account;
- purple_debug_info("yahoo", "in yahoo_sendfile_connected\n");
- if (!(xd = xfer->data))
- purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
- purple_xfer_cancel_remote(xfer);
- /* Assemble the tx buffer */
- account = purple_connection_get_account(gc);
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- size = g_strdup_printf("%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer));
- filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
- encoded_filename = yahoo_string_encode(gc, filename, NULL);
- yahoo_packet_hash(pkt, "sssss", 0, purple_connection_get_display_name(gc),
- 5, xfer->who, 14, "", 27, encoded_filename, 28, size);
- g_free(encoded_filename);
- content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt);
- pkt_buf_len = yahoo_packet_build(pkt, 4, FALSE, yd->jp, &pkt_buf);
- yahoo_packet_free(pkt);
- host = purple_account_get_string(account, "xfer_host", YAHOO_XFER_HOST);
- port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);
- header = g_strdup_printf(
- "POST http://%s:%d/notifyft HTTP/1.0\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n"
- "Cookie: Y=%s; T=%s\r\n"
- host, port, content_length + 4 + purple_xfer_get_size(xfer),
- host, port, yd->cookie_y, yd->cookie_t);
- header_len = strlen(header);
- xd->txbuflen = header_len + pkt_buf_len + 4;
- xd->txbuf = g_malloc(xd->txbuflen);
- memcpy(xd->txbuf, header, header_len);
- memcpy(xd->txbuf + header_len, pkt_buf, pkt_buf_len);
- memcpy(xd->txbuf + header_len + pkt_buf_len, "29\xc0\x80", 4);
- if (xd->tx_handler == 0)
- xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE,
- yahoo_sendfile_send_cb, xfer);
- yahoo_sendfile_send_cb(xfer, source, PURPLE_INPUT_WRITE);
-static void yahoo_xfer_init(PurpleXfer *xfer)
- struct yahoo_xfer_data *xfer_data;
- PurpleAccount *account;
- xfer_data = xfer->data;
- account = purple_connection_get_account(gc);
- if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
- if (purple_proxy_connect(gc, account, purple_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST),
- purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
- yahoo_sendfile_connected, xfer) == NULL)
- purple_notify_error(gc, NULL, _("File Transfer Failed"),
- _("Unable to establish file descriptor."));
- purple_xfer_cancel_remote(xfer);
- if (purple_proxy_connect(gc, account, purple_account_get_string(account, "xfer_host", YAHOO_XFER_HOST),
- purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
- yahoo_sendfile_connected, xfer) == NULL)
- purple_notify_error(gc, NULL, _("File Transfer Failed"),
- _("Unable to establish file descriptor."));
- purple_xfer_cancel_remote(xfer);
- if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
- yahoo_receivefile_connected, xfer) == NULL) {
- purple_notify_error(gc, NULL, _("File Transfer Failed"),
- _("Unable to establish file descriptor."));
- purple_xfer_cancel_remote(xfer);
-static void yahoo_xfer_init_15(PurpleXfer *xfer)
- struct yahoo_xfer_data *xfer_data;
- PurpleAccount *account;
- struct yahoo_packet *pkt;
- xfer_data = xfer->data;
- account = purple_connection_get_account(gc);
- if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
- filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
- YAHOO_STATUS_AVAILABLE,
- yahoo_packet_hash(pkt, "sssiiiisiii",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- if(xfer_data->firstoflist == TRUE) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_xfer_start(PurpleXfer *xfer)
- /* We don't need to do anything here, do we? */
-static guint calculate_length(const gchar *l, size_t len)
- for (i = 0; i < len; i++) {
- if (!g_ascii_isdigit(l[i]))
- return strtol(l + i, NULL, 10);
-static gssize yahoo_xfer_read(guchar **buffer, PurpleXfer *xfer)
- struct yahoo_xfer_data *xd = xfer->data;
- if (purple_xfer_get_type(xfer) != PURPLE_XFER_RECEIVE) {
- len = read(xfer->fd, buf, sizeof(buf));
- if ((purple_xfer_get_size(xfer) > 0) &&
- (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))) {
- purple_xfer_set_completed(xfer, TRUE);
- xd->rxqueue = g_realloc(xd->rxqueue, len + xd->rxlen);
- memcpy(xd->rxqueue + xd->rxlen, buf, len);
- length = g_strstr_len(xd->rxqueue, len, "Content-length:");
- /* some proxies re-write this header, changing the capitalization :(
- * technically that's allowed since headers are case-insensitive
- * [RFC 2616, section 4.2] */
- length = g_strstr_len(xd->rxqueue, len, "Content-Length:");
- end = g_strstr_len(length, length - xd->rxqueue, "\r\n");
- if ((filelen = calculate_length(length, len - (length - xd->rxqueue))))
- purple_xfer_set_size(xfer, filelen);
- start = g_strstr_len(xd->rxqueue, len, "\r\n\r\n");
- if (!start || start > (xd->rxqueue + len))
- len -= (start - xd->rxqueue);
- *buffer = g_malloc(len);
- memcpy(*buffer, start, len);
- *buffer = g_malloc(len);
- memcpy(*buffer, buf, len);
-static gssize yahoo_xfer_write(const guchar *buffer, size_t size, PurpleXfer *xfer)
- struct yahoo_xfer_data *xd = xfer->data;
- if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND) {
- len = write(xfer->fd, buffer, size);
- if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer))
- purple_xfer_set_completed(xfer, TRUE);
- if ((errno != EAGAIN) && (errno != EINTR))
-static void yahoo_xfer_cancel_send(PurpleXfer *xfer)
- struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
- if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
- PurpleAccount *account;
- struct yahoo_packet *pkt;
- account = purple_connection_get_account(gc);
- if(xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15,
- YAHOO_STATUS_DISCONNECTED,
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
- YAHOO_STATUS_AVAILABLE,
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- yahoo_packet_send_and_free(pkt, yd);
- yahoo_xfer_data_free(xfer_data);
-static void yahoo_xfer_cancel_recv(PurpleXfer *xfer)
- struct yahoo_xfer_data *xfer_data;
- xfer_data = xfer->data;
- if(purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL && xfer_data->version == 15)
- PurpleAccount *account;
- struct yahoo_packet *pkt;
- account = purple_connection_get_account(gc);
- if(!xfer_data->xfer_idstring_for_relay) /* hack to see if file trans acc/info packet has been received */
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
- YAHOO_STATUS_AVAILABLE,
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
- YAHOO_STATUS_DISCONNECTED,
- yahoo_packet_hash(pkt, "sssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- yahoo_packet_send_and_free(pkt, yd);
- yahoo_xfer_data_free(xfer_data);
-/* Send HTTP OK after receiving file */
-static void yahoo_p2p_ft_server_send_OK(PurpleXfer *xfer)
- tx = g_strdup_printf("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n");
- written = write(xfer->fd, tx, strlen(tx));
- if (written < 0 && errno == EAGAIN)
- purple_debug_info("yahoo", "p2p filetransfer: Unable to write HTTP OK");
-static void yahoo_xfer_end(PurpleXfer *xfer_old)
- struct yahoo_xfer_data *xfer_data;
- PurpleXfer *xfer = NULL;
- xfer_data = xfer_old->data;
- if(xfer_data && xfer_data->version == 15
- && purple_xfer_get_type(xfer_old) == PURPLE_XFER_RECEIVE
- && xfer_data->filename_list) {
- /* Send HTTP OK in case of p2p transfer, when we act as server */
- if((xfer_data->xfer_url != NULL) && (xfer_old->fd >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE))
- yahoo_p2p_ft_server_send_OK(xfer_old);
- /* removing top of filename & size list completely */
- g_free( xfer_data->filename_list->data );
- g_free( xfer_data->size_list->data );
- xfer_data->filename_list->data = NULL;
- xfer_data->size_list->data = NULL;
- xfer_data->filename_list = g_slist_delete_link(xfer_data->filename_list, xfer_data->filename_list);
- xfer_data->size_list = g_slist_delete_link(xfer_data->size_list, xfer_data->size_list);
- /* if there are still more files */
- if(xfer_data->filename_list)
- filename = xfer_data->filename_list->data;
- filesize = atol( xfer_data->size_list->data );
- /* setting up xfer_data for next file's tranfer */
- g_free(xfer_data->host);
- g_free(xfer_data->path);
- g_free(xfer_data->txbuf);
- g_free(xfer_data->rxqueue);
- g_free(xfer_data->xfer_idstring_for_relay);
- if (xfer_data->tx_handler)
- purple_input_remove(xfer_data->tx_handler);
- xfer_data->host = NULL;
- xfer_data->host = NULL;
- xfer_data->expires = 0;
- xfer_data->started = FALSE;
- xfer_data->txbuf = NULL;
- xfer_data->txbuflen = 0;
- xfer_data->txbuf_written = 0;
- xfer_data->tx_handler = 0;
- xfer_data->rxqueue = NULL;
- xfer_data->xfer_idstring_for_relay = NULL;
- xfer_data->info_val_249 = 0;
- xfer_data->status_15 = STARTED;
- xfer_data->firstoflist = FALSE;
- /* Dereference xfer_data from old xfer */
- /* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, xfer_old->who);
- /* Set the info about the incoming file. */
- char *utf8_filename = yahoo_string_decode(gc, filename, TRUE);
- purple_xfer_set_filename(xfer, utf8_filename);
- purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
- /* Setup our I/O op functions */
- purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
- purple_xfer_set_start_fnc(xfer, yahoo_xfer_start);
- purple_xfer_set_end_fnc(xfer, yahoo_xfer_end);
- purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
- purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
- purple_xfer_set_read_fnc(xfer, yahoo_xfer_read);
- purple_xfer_set_write_fnc(xfer, yahoo_xfer_write);
- purple_xfer_set_request_denied_fnc(xfer,yahoo_xfer_cancel_recv);
- /* update map to current xfer */
- g_hash_table_remove(yd->xfer_peer_idstring_map, xfer_data->xfer_peer_idstring);
- g_hash_table_insert(yd->xfer_peer_idstring_map, xfer_data->xfer_peer_idstring, xfer);
- /* Now perform the request */
- purple_xfer_request(xfer);
- yahoo_xfer_data_free(xfer_data);
-void yahoo_process_p2pfilexfer(PurpleConnection *gc, struct yahoo_packet *pkt)
- /* Get all the necessary values from this new packet */
- struct yahoo_pair *pair = l->data;
- case 5: /* Get who the packet is for */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 4: /* Get who the packet is from */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 49: /* Get the type of service */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 14: /* Get the 'message' of the packet */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 13: /* Get the command associated with this packet */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 63: /* IMVironment name and version */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_p2pfilexfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 64: /* Not sure, but it does vary with initialization of Doodle */
- /* If this packet is an IMVIRONMENT, handle it accordingly */
- if(service != NULL && imv != NULL && !strcmp(service, "IMVIRONMENT"))
- /* Check for a Doodle packet and handle it accordingly */
- if(strstr(imv, "doodle;") != NULL)
- yahoo_doodle_process(gc, me, from, command, message, imv);
- /* If an IMVIRONMENT packet comes without a specific imviroment name */
- /* It is unfortunately time to close all IMVironments with the remote client */
- yahoo_doodle_command_got_shutdown(gc, from);
-void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_xfer_data *xfer_data;
- unsigned long filesize = 0L;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetransfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetransfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetransfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- filename = pair->value;
- filesize = atol(pair->value);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetransfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetransfer "
- "got non-UTF-8 string for key %d\n", pair->key);
- * The remote user has changed their IMVironment. We
- * record it for later use.
- if (from && imv && service && (strcmp("IMVIRONMENT", service) == 0)) {
- g_hash_table_replace(yd->imvironments, g_strdup(from), g_strdup(imv));
- if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) {
- if (service && (strcmp("FILEXFER", service) != 0)) {
- purple_debug_misc("yahoo", "unhandled service 0x%02x\n", pkt->service);
- tmp = strchr(msg, '\006');
- /* Setup the Yahoo-specific file transfer data */
- xfer_data = g_new0(struct yahoo_xfer_data, 1);
- if (!purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) {
- purple_debug_misc("yahoo_filexfer", "Host is %s, port is %d, path is %s, and the full url was %s.\n",
- xfer_data->host, xfer_data->port, xfer_data->path, url);
- /* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
- xfer->data = xfer_data;
- /* Set the info about the incoming file. */
- char *utf8_filename = yahoo_string_decode(gc, filename, TRUE);
- purple_xfer_set_filename(xfer, utf8_filename);
- start = g_strrstr(xfer_data->path, "/");
- end = g_strrstr(xfer_data->path, "?");
- if (start && *start && end) {
- filename = g_strndup(start, end - start);
- utf8_filename = yahoo_string_decode(gc, filename, TRUE);
- purple_xfer_set_filename(xfer, utf8_filename);
- purple_xfer_set_size(xfer, filesize);
- /* Setup our I/O op functions */
- purple_xfer_set_init_fnc(xfer, yahoo_xfer_init);
- purple_xfer_set_start_fnc(xfer, yahoo_xfer_start);
- purple_xfer_set_end_fnc(xfer, yahoo_xfer_end);
- purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
- purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
- purple_xfer_set_read_fnc(xfer, yahoo_xfer_read);
- purple_xfer_set_write_fnc(xfer, yahoo_xfer_write);
- /* Now perform the request */
- purple_xfer_request(xfer);
-PurpleXfer *yahoo_new_xfer(PurpleConnection *gc, const char *who)
- struct yahoo_xfer_data *xfer_data;
- g_return_val_if_fail(who != NULL, NULL);
- xfer_data = g_new0(struct yahoo_xfer_data, 1);
- /* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
- g_return_val_if_reached(NULL);
- xfer->data = xfer_data;
- /* Setup our I/O op functions */
- purple_xfer_set_init_fnc(xfer, yahoo_xfer_init);
- purple_xfer_set_start_fnc(xfer, yahoo_xfer_start);
- purple_xfer_set_end_fnc(xfer, yahoo_xfer_end);
- purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
- purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
- purple_xfer_set_read_fnc(xfer, yahoo_xfer_read);
- purple_xfer_set_write_fnc(xfer, yahoo_xfer_write);
-static gchar* yahoo_xfer_new_xfer_id(void)
- ans = g_strnfill(24, ' ');
- for(i = 0; i < 22; i++)
- j = g_random_int_range (0,61);
-static void yahoo_xfer_dns_connected_15(GSList *hosts, gpointer data, const char *error_message)
- struct yahoo_xfer_data *xd;
- struct sockaddr_in *addr;
- struct yahoo_packet *pkt;
- PurpleAccount *account;
- if (!(xd = xfer->data))
- account = purple_connection_get_account(gc);
- purple_debug_error("yahoo", "Unable to find an IP address for relay.msg.yahoo.com\n");
- purple_xfer_cancel_remote(xfer);
- /* Discard the length... */
- hosts = g_slist_remove(hosts, hosts->data);
- purple_debug_error("yahoo", "Unable to find an IP address for relay.msg.yahoo.com\n");
- purple_xfer_cancel_remote(xfer);
- /* TODO:actually, u must try with addr no.1 , if its not working addr no.2 ..... */
- actaddr = addr->sin_addr.s_addr;
- xd->port = YAHOOJP_XFER_RELAY_PORT;
- xd->port = YAHOO_XFER_RELAY_PORT;
- url = g_strdup_printf("%u.%u.%u.%u", d, c, b, a);
- /* Free the address... */
- hosts = g_slist_remove(hosts, hosts->data);
- /* Discard the length... */
- hosts = g_slist_remove(hosts, hosts->data);
- /* Free the address... */
- hosts = g_slist_remove(hosts, hosts->data);
- if (!purple_url_parse(url, &(xd->host), &(xd->port), &(xd->path), NULL, NULL)) {
- purple_xfer_cancel_remote(xfer);
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
- filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
- yahoo_packet_hash(pkt, "ssssis",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xd->xfer_peer_idstring,
- yahoo_packet_send_and_free(pkt, yd);
-gboolean yahoo_can_receive_file(PurpleConnection *gc, const char *who)
- if (!who || yahoo_get_federation_from_name(who) != YAHOO_FEDERATION_NONE)
-void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
- struct yahoo_xfer_data *xfer_data;
- YahooData *yd = gc->proto_data;
- PurpleXfer *xfer = yahoo_new_xfer(gc, who);
- g_return_if_fail(xfer != NULL);
- /* if we don't have a p2p connection, try establishing it now */
- if( !g_hash_table_lookup(yd->peers, who) )
- yahoo_send_p2p_pkt(gc, who, 0);
- xfer_data = xfer->data;
- xfer_data->status_15 = STARTED;
- purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
- xfer_data->version = 15;
- xfer_data->xfer_peer_idstring = yahoo_xfer_new_xfer_id();
- g_hash_table_insert(yd->xfer_peer_idstring_map, xfer_data->xfer_peer_idstring, xfer);
- /* Now perform the request */
- purple_xfer_request_accepted(xfer, file);
- purple_xfer_request(xfer);
-static void yahoo_p2p_ft_server_listen_cb(int listenfd, gpointer data); /* using this in yahoo_xfer_send_cb_15 */
-static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *error_message);/* using this in recv_cb */
-static void yahoo_xfer_recv_cb_15(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_xfer_data *xd;
- PurpleAccount *account;
- account = purple_connection_get_account(xd->gc);
- buf=g_strnfill(1000, 0);
- while((did = read(source, buf, 998)) > 0)
- xd->txbuf = g_strconcat(t,buf,NULL);
- if (did < 0 && errno == EAGAIN)
- purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);
- purple_xfer_cancel_remote(xfer);
- purple_input_remove(xd->tx_handler);
- if(xd->status_15 == HEAD_REQUESTED) {
- xd->status_15 = HEAD_REPLY_RECEIVED;
- close(source);/* Is this required? */
- if (purple_proxy_connect(gc, account, xd->host, xd->port, yahoo_xfer_connected_15, xfer) == NULL)
- purple_notify_error(gc, NULL, _("File Transfer Failed"),
- _("Unable to establish file descriptor."));
- purple_xfer_cancel_remote(xfer);
- purple_debug_error("yahoo","Unrecognized yahoo file transfer mode and stage (ymsg15):%d,%d\n",
- purple_xfer_get_type(xfer),
-static void yahoo_xfer_send_cb_15(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_xfer_data *xd;
- int remaining, written;
- remaining = xd->txbuflen - xd->txbuf_written;
- written = write(source, xd->txbuf + xd->txbuf_written, remaining);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);
- purple_xfer_cancel_remote(xfer);
- if (written < remaining) {
- xd->txbuf_written += written;
- purple_input_remove(xd->tx_handler);
- if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
- xd->status_15 = HEAD_REQUESTED;
- xd->tx_handler = purple_input_add(source, PURPLE_INPUT_READ, yahoo_xfer_recv_cb_15, xfer);
- yahoo_xfer_recv_cb_15(xfer, source, PURPLE_INPUT_READ);
- else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == HEAD_REPLY_RECEIVED)
- xd->status_15 = TRANSFER_PHASE;
- purple_xfer_start(xfer, source, NULL, 0);
- else if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && (xd->status_15 == ACCEPTED || xd->status_15 == P2P_GET_REQUESTED) )
- xd->status_15 = TRANSFER_PHASE;
- /* Remove Read event */
- purple_input_remove(xd->input_event);
- purple_xfer_start(xfer, source, NULL, 0);
- else if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && xd->status_15 == P2P_HEAD_REQUESTED)
- xd->status_15 = P2P_HEAD_REPLIED;
- /* Remove Read event and close descriptor */
- purple_input_remove(xd->input_event);
- /* start local server, listen for connections */
- purple_network_listen(xd->yahoo_local_p2p_ft_server_port, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer);
- purple_debug_error("yahoo", "Unrecognized yahoo file transfer mode and stage (ymsg15):%d,%d\n", purple_xfer_get_type(xfer), xd->status_15);
-static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *error_message)
- struct yahoo_xfer_data *xd;
- PurpleAccount *account;
- if (!(xd = xfer->data))
- account = purple_connection_get_account(gc);
- if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
- purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
- xfer->who, _("Unable to connect."));
- purple_xfer_cancel_remote(xfer);
- /* The first time we get here, assemble the tx buffer */
- YahooData *yd = gc->proto_data;
- /* cookies = yahoo_get_cookies(gc);
- * This doesn't seem to be working. The function is returning NULL, which yahoo servers don't like
- * For now let us not use this function */
- cookies = g_strdup_printf("Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
- if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && xd->status_15 == ACCEPTED)
- if(xd->info_val_249 == 2)
- /* sending file via p2p, we are connected as client */
- xd->txbuf = g_strdup_printf("POST /%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: %ld\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- (long int)xfer->size); /* to do, add Referer */
- /* sending file via relaying */
- xd->txbuf = g_strdup_printf("POST /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: %ld\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- purple_url_encode(xd->xfer_idstring_for_relay),
- purple_normalize(account, purple_account_get_username(account)),
- else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
- if(xd->info_val_249 == 1)
- /* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("HEAD /%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: 0\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- /* receiving file via relaying */
- xd->txbuf = g_strdup_printf("HEAD /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Content-Length: 0\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- purple_url_encode(xd->xfer_idstring_for_relay),
- purple_normalize(account, purple_account_get_username(account)),
- else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == HEAD_REPLY_RECEIVED)
- if(xd->info_val_249 == 1)
- /* receiving file via p2p, connected as client */
- xd->txbuf = g_strdup_printf("GET /%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Connection: Keep-Alive\r\n\r\n",
- /* receiving file via relaying */
- xd->txbuf = g_strdup_printf("GET /relay?token=%s&sender=%s&recver=%s HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Connection: Keep-Alive\r\n\r\n",
- purple_url_encode(xd->xfer_idstring_for_relay),
- purple_normalize(account, purple_account_get_username(account)),
- purple_debug_error("yahoo", "Unrecognized yahoo file transfer mode and stage (ymsg15):%d,%d\n", purple_xfer_get_type(xfer), xd->status_15);
- xd->txbuflen = strlen(xd->txbuf);
- xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE,
- yahoo_xfer_send_cb_15, xfer);
- yahoo_xfer_send_cb_15(xfer, source, PURPLE_INPUT_WRITE);
-static void yahoo_p2p_ft_POST_cb(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_xfer_data *xd;
- if (!(xd = xfer->data)) {
- purple_xfer_cancel_remote(xfer);
- purple_input_remove(xd->input_event);
- xd->status_15 = TRANSFER_PHASE;
- purple_xfer_start(xfer, source, NULL, 0);
-static void yahoo_p2p_ft_HEAD_GET_cb(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_xfer_data *xd;
- if (!(xd = xfer->data)) {
- purple_xfer_cancel_remote(xfer);
- len = read(source, buf, sizeof(buf));
- if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
- return ; /* No Worries*/
- purple_debug_warning("yahoo","p2p-ft: Error in connection, or host disconnected\n");
- purple_input_remove(xd->input_event);
- purple_xfer_cancel_remote(xfer);
- url_head = g_strdup_printf("HEAD %s", xd->xfer_url);
- url_get = g_strdup_printf("GET %s", xd->xfer_url);
- if( strncmp(url_head, (char *)buf, strlen(url_head)) == 0 )
- xd->status_15 = P2P_HEAD_REQUESTED;
- else if( strncmp(url_get, (char *)buf, strlen(url_get)) == 0 )
- xd->status_15 = P2P_GET_REQUESTED;
- 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);
- unix_time = time(NULL);
- time_str = ctime(&unix_time);
- time_str[strlen(time_str) - 1] = '\0';
- if (xd->txbuflen == 0) {
- xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
- "MIME-version: 1.0\r\n"
- "Last-modified: %s GMT\r\n"
- "Content-length: %" G_GSIZE_FORMAT "\r\n\r\n",
- time_str, time_str, xfer->size);
- xd->txbuflen = strlen(xd->txbuf);
- xd->tx_handler = purple_input_add(source, PURPLE_INPUT_WRITE, yahoo_xfer_send_cb_15, xfer);
- yahoo_xfer_send_cb_15(xfer, source, PURPLE_INPUT_WRITE);
-static void yahoo_p2p_ft_server_send_connected_cb(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_xfer_data *xd;
- if (!(xd = xfer->data)) {
- purple_xfer_cancel_remote(xfer);
- acceptfd = accept(source, NULL, 0);
- if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
- else if(acceptfd == -1) {
- purple_debug_warning("yahoo","yahoo_p2p_server_send_connected_cb: accept: %s\n", g_strerror(errno));
- purple_xfer_cancel_remote(xfer);
- /* remove watcher and close p2p ft server */
- purple_input_remove(xd->yahoo_p2p_ft_server_watcher);
- close(xd->yahoo_local_p2p_ft_server_fd);
- /* remove watcher and close p2p ft server */
- purple_input_remove(xd->yahoo_p2p_ft_server_watcher);
- close(xd->yahoo_local_p2p_ft_server_fd);
- /* Add an Input Read event to the file descriptor */
- if(xfer->type == PURPLE_XFER_RECEIVE)
- xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_POST_cb, data);
- xd->input_event = purple_input_add(acceptfd, PURPLE_INPUT_READ, yahoo_p2p_ft_HEAD_GET_cb, data);
-static void yahoo_p2p_ft_server_listen_cb(int listenfd, gpointer data)
- struct yahoo_xfer_data *xd;
- struct yahoo_packet *pkt;
- PurpleAccount *account;
- gchar *url_to_send = NULL;
- char *filename_without_spaces = NULL;
- if (!(xd = xfer->data) || (listenfd == -1)) {
- purple_debug_warning("yahoo","p2p: error starting server for p2p file transfer\n");
- purple_xfer_cancel_remote(xfer);
- if( (xfer->type == PURPLE_XFER_RECEIVE) || (xd->status_15 != P2P_HEAD_REPLIED) ) {
- yd = xd->gc->proto_data;
- account = purple_connection_get_account(xd->gc);
- local_ip = purple_network_get_my_ip(listenfd);
- xd->yahoo_local_p2p_ft_server_port = purple_network_get_port_from_fd(listenfd);
- filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
- filename_without_spaces = g_strdup(filename);
- purple_util_chrreplace(filename_without_spaces, ' ', '+');
- xd->xfer_url = g_strdup_printf("/Messenger.%s.%d000%s?AppID=Messenger&UserID=%s&K=lc9lu2u89gz1llmplwksajkjx", xfer->who, (int)time(NULL), filename_without_spaces, xfer->who);
- url_to_send = g_strdup_printf("http://%s:%d%s", local_ip, xd->yahoo_local_p2p_ft_server_port, xd->xfer_url);
- if(xfer->type == PURPLE_XFER_RECEIVE) {
- xd->info_val_249 = 2; /* 249=2: we are p2p server, and receiving file */
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssis",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xd->xfer_peer_idstring,
- xd->info_val_249 = 1; /* 249=1: we are p2p server, and sending file */
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssis",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xd->xfer_peer_idstring,
- yahoo_packet_send_and_free(pkt, yd);
- g_free(filename_without_spaces);
- /* Add an Input Read event to the file descriptor */
- xd->yahoo_local_p2p_ft_server_fd = listenfd;
- xd->yahoo_p2p_ft_server_watcher = purple_input_add(listenfd, PURPLE_INPUT_READ, yahoo_p2p_ft_server_send_connected_cb, data);
-/* send (p2p) file transfer information */
-static void yahoo_p2p_client_send_ft_info(PurpleConnection *gc, PurpleXfer *xfer)
- struct yahoo_xfer_data *xd;
- struct yahoo_packet *pkt;
- PurpleAccount *account;
- struct yahoo_p2p_data *p2p_data;
- if (!(xd = xfer->data))
- account = purple_connection_get_account(gc);
- p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
- if( p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER )
- if(purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer))
- pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_INFO_15, YAHOO_STATUS_AVAILABLE, yd->session_id);
- filename = g_path_get_basename(purple_xfer_get_local_filename(xfer));
- yahoo_packet_hash(pkt, "ssssi",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xd->xfer_peer_idstring,
- 249, 2); /* 249=2: we are p2p client */
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_xfer_data *xfer_data;
- char *xfer_peer_idstring = NULL;
- unsigned long filesize = 0L;
- GSList *filename_list = NULL;
- GSList *size_list = NULL;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetrans_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- xfer_peer_idstring = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_filetrans_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- filename_list = g_slist_prepend(filename_list, g_strdup(pair->value));
- if (g_utf8_validate(pair->value, -1, NULL)) {
- size_list = g_slist_prepend(size_list, g_strdup(pair->value));
- purple_debug_warning("yahoo", "yahoo_process_filetrans_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- val_222 = atol(pair->value);
- /* 1=send, 2=cancel, 3=accept, 4=reject */
- /* check for p2p and imviron .... not sure it comes by this service packet. Since it was bundled with filexfer in old ymsg version, still keeping it. */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetrans_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetrans_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if(!xfer_peer_idstring)
- if(val_222 == 2 || val_222 == 4)
- xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map,
- purple_xfer_cancel_remote(xfer);
- PurpleAccount *account;
- xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map,
- * In the file trans info packet that we must reply with, we are
- * supposed to mention the ip address...
- * purple connect does not give me a way of finding the ip address...
- * so, purple dnsquery is used... but retries, trying with next ip
- * address etc. is not implemented..TODO
- /* To send through p2p */
- if( g_hash_table_lookup(yd->peers, from) ) {
- /* send p2p file transfer information */
- yahoo_p2p_client_send_ft_info(gc, xfer);
- account = purple_connection_get_account(gc);
- purple_dnsquery_a_account(account, YAHOOJP_XFER_RELAY_HOST,
- YAHOOJP_XFER_RELAY_PORT,
- yahoo_xfer_dns_connected_15, xfer);
- purple_dnsquery_a_account(account, YAHOO_XFER_RELAY_HOST,
- yahoo_xfer_dns_connected_15, xfer);
- /* processing for p2p and imviron .... not sure it comes by this service packet. Since it was bundled with filexfer in old ymsg version, still keeping it. */
- * The remote user has changed their IMVironment. We
- * record it for later use.
- if (from && imv && service && (strcmp("IMVIRONMENT", service) == 0)) {
- g_hash_table_replace(yd->imvironments, g_strdup(from), g_strdup(imv));
- if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) {
- if (service && (strcmp("FILEXFER", service) != 0)) {
- purple_debug_misc("yahoo", "unhandled service 0x%02x\n", pkt->service);
- /* have to change list into order in which client at other end sends */
- filename_list = g_slist_reverse(filename_list);
- size_list = g_slist_reverse(size_list);
- filename = filename_list->data;
- filesize = atol(size_list->data);
- xfer_data = g_new0(struct yahoo_xfer_data, 1);
- xfer_data->version = 15;
- xfer_data->firstoflist = TRUE;
- xfer_data->xfer_peer_idstring = g_strdup(xfer_peer_idstring);
- xfer_data->filename_list = filename_list;
- xfer_data->size_list = size_list;
- /* Build the file transfer handle. */
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
- /* Set the info about the incoming file. */
- utf8_filename = yahoo_string_decode(gc, filename, TRUE);
- purple_xfer_set_filename(xfer, utf8_filename);
- purple_xfer_set_size(xfer, filesize);
- xfer->data = xfer_data;
- /* Setup our I/O op functions */
- purple_xfer_set_init_fnc(xfer, yahoo_xfer_init_15);
- purple_xfer_set_start_fnc(xfer, yahoo_xfer_start);
- purple_xfer_set_end_fnc(xfer, yahoo_xfer_end);
- purple_xfer_set_cancel_send_fnc(xfer, yahoo_xfer_cancel_send);
- purple_xfer_set_cancel_recv_fnc(xfer, yahoo_xfer_cancel_recv);
- purple_xfer_set_read_fnc(xfer, yahoo_xfer_read);
- purple_xfer_set_write_fnc(xfer, yahoo_xfer_write);
- purple_xfer_set_request_denied_fnc(xfer,yahoo_xfer_cancel_recv);
- g_hash_table_insert(yd->xfer_peer_idstring_map,
- xfer_data->xfer_peer_idstring,
- message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), xfer->who, nooffiles);
- purple_xfer_conversation_write(xfer, message, FALSE);
- /* Now perform the request */
- purple_xfer_request(xfer);
-void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_xfer_data *xfer_data;
- char *xfer_peer_idstring = NULL;
- char *xfer_idstring_for_relay = NULL;
- struct yahoo_packet *pkt_to_send;
- struct yahoo_p2p_data *p2p_data;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- xfer_peer_idstring = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 27: /* filename */
- val_66 = strtol(pair->value, NULL, 10);
- val_249 = strtol(pair->value, NULL, 10);
- /* 249 has value 1 or 2 when doing p2p transfer and value 3 when relaying through yahoo server */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- xfer_idstring_for_relay = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_filetrans_info_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if(!xfer_peer_idstring)
- xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map, xfer_peer_idstring);
- purple_xfer_cancel_remote(xfer);
- xfer_data = xfer->data;
- xfer_data->info_val_249 = val_249;
- xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
- if(val_249 == 1 || val_249 == 3) {
- PurpleAccount *account;
- if (!purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL)) {
- purple_xfer_cancel_remote(xfer);
- account = purple_connection_get_account(xfer_data->gc);
- pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt_to_send, "ssssis",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 265, xfer_data->xfer_peer_idstring,
- 249, xfer_data->info_val_249,
- 251, xfer_data->xfer_idstring_for_relay);
- yahoo_packet_send_and_free(pkt_to_send, yd);
- if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
- yahoo_xfer_connected_15, xfer) == NULL) {
- purple_notify_error(gc, NULL, _("File Transfer Failed"),
- _("Unable to establish file descriptor."));
- purple_xfer_cancel_remote(xfer);
- else if(val_249 == 2) {
- p2p_data = g_hash_table_lookup(yd->peers, xfer->who);
- if( !( p2p_data && (p2p_data->connection_type == YAHOO_P2P_WE_ARE_SERVER) ) ) {
- purple_xfer_cancel_remote(xfer);
- if(!purple_network_listen_range(0, 0, SOCK_STREAM, yahoo_p2p_ft_server_listen_cb, xfer)) {
- purple_xfer_cancel_remote(xfer);
-/* TODO: Check filename etc. No probs till some hacker comes in the way */
-void yahoo_process_filetrans_acc_15(PurpleConnection *gc, struct yahoo_packet *pkt)
- gchar *xfer_peer_idstring = NULL;
- gchar *xfer_idstring_for_relay = NULL;
- struct yahoo_xfer_data *xfer_data;
- PurpleAccount *account;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- xfer_idstring_for_relay = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_filetrans_acc_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- xfer_peer_idstring = pair->value;
- purple_debug_warning("yahoo", "yahoo_process_filetrans_acc_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- val_66 = atol(pair->value);
- val_249 = atol(pair->value);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- /* we get a p2p url here when sending file, connected as client */
- purple_debug_warning("yahoo", "yahoo_process_filetrans_acc_15 "
- "got non-UTF-8 string for key %d\n", pair->key);
- xfer = g_hash_table_lookup(yd->xfer_peer_idstring_map, xfer_peer_idstring);
- if(val_66 == -1 || ( (!(xfer_idstring_for_relay)) && (val_249 != 2) ))
- purple_xfer_cancel_remote(xfer);
- if( (val_249 == 2) && (!(url)) )
- purple_xfer_cancel_remote(xfer);
- xfer_data = xfer->data;
- purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL);
- xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
- xfer_data->status_15 = ACCEPTED;
- account = purple_connection_get_account(gc);
- if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
- yahoo_xfer_connected_15, xfer) == NULL)
- purple_notify_error(gc, NULL, _("File Transfer Failed"),_("Unable to connect"));
- purple_xfer_cancel_remote(xfer);
--- a/libpurple/protocols/yahoo/yahoo_filexfer.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
- * 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
- * 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 _YAHOO_FILEXFER_H_
-#define _YAHOO_FILEXFER_H_
- * Process ymsg events, particular IMViroments like Doodle
-void yahoo_process_p2pfilexfer( PurpleConnection *gc, struct yahoo_packet *pkt );
- * Process ymsg file receive invites.
-void yahoo_process_filetransfer(PurpleConnection *gc, struct yahoo_packet *pkt);
- * Create a new PurpleXfer
- * @param gc The PurpleConnection handle.
- * @param who Who will we be sending it to?
-PurpleXfer *yahoo_new_xfer(PurpleConnection *gc, const char *who);
- * Returns TRUE if the buddy can receive file, FALSE otherwise.
- * Federated users cannot receive files. So this will return FALSE only
- * @param gc The connection
- * @param who The name of the remote user
- * @return TRUE or FALSE
-gboolean yahoo_can_receive_file(PurpleConnection *gc, const char *who);
- * @param gc The PurpleConnection handle.
- * @param who Who are we sending it to?
- * @param file What file? If NULL, user will choose after this call.
-void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file);
-void yahoo_process_filetrans_15(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_filetrans_info_15(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_filetrans_acc_15(PurpleConnection *gc, struct yahoo_packet *pkt);
--- a/libpurple/protocols/yahoo/yahoo_friend.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,330 +0,0 @@
- * 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
- * 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 "yahoo_friend.h"
-#include "yahoo_aliases.h"
-static YahooFriend *yahoo_friend_new(void)
- ret = g_new0(YahooFriend, 1);
- ret->status = YAHOO_STATUS_OFFLINE;
- ret->presence = YAHOO_PRESENCE_DEFAULT;
-YahooFriend *yahoo_friend_find(PurpleConnection *gc, const char *name)
- g_return_val_if_fail(gc != NULL, NULL);
- g_return_val_if_fail(gc->proto_data != NULL, NULL);
- norm = purple_normalize(purple_connection_get_account(gc), name);
- return g_hash_table_lookup(yd->friends, norm);
-YahooFriend *yahoo_friend_find_or_new(PurpleConnection *gc, const char *name)
- g_return_val_if_fail(gc != NULL, NULL);
- g_return_val_if_fail(gc->proto_data != NULL, NULL);
- norm = purple_normalize(purple_connection_get_account(gc), name);
- f = g_hash_table_lookup(yd->friends, norm);
- f = yahoo_friend_new();
- g_hash_table_insert(yd->friends, g_strdup(norm), f);
-void yahoo_friend_set_ip(YahooFriend *f, const char *ip)
-const char *yahoo_friend_get_ip(YahooFriend *f)
-void yahoo_friend_set_game(YahooFriend *f, const char *game)
- f->game = g_strdup(game);
-const char *yahoo_friend_get_game(YahooFriend *f)
-void yahoo_friend_set_status_message(YahooFriend *f, char *msg)
-const char *yahoo_friend_get_status_message(YahooFriend *f)
-void yahoo_friend_set_buddy_icon_need_request(YahooFriend *f, gboolean needs)
- f->bicon_sent_request = !needs;
-gboolean yahoo_friend_get_buddy_icon_need_request(YahooFriend *f)
- return !f->bicon_sent_request;
-void yahoo_friend_set_alias_id(YahooFriend *f, const char *alias_id)
- f->ypd.id = g_strdup(alias_id);
-const char *yahoo_friend_get_alias_id(YahooFriend *f)
-void yahoo_friend_free(gpointer p)
- yahoo_personal_details_reset(&f->ypd, TRUE);
-void yahoo_process_presence(PurpleConnection *gc, struct yahoo_packet *pkt)
- YahooFederation fed = YAHOO_FEDERATION_NONE;
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_presence "
- "got non-UTF-8 string for key %d\n", pair->key);
- value = strtol(pair->value, NULL, 10);
- fed = strtol(pair->value, NULL, 10);
- if (value != 1 && value != 2) {
- purple_debug_error("yahoo", "Received unknown value for presence key: %d\n", value);
- case YAHOO_FEDERATION_MSN:
- who = g_strconcat("msn/", temp, NULL);
- case YAHOO_FEDERATION_OCS:
- who = g_strconcat("ocs/", temp, NULL);
- case YAHOO_FEDERATION_IBM:
- who = g_strconcat("ibm/", temp, NULL);
- case YAHOO_FEDERATION_PBX:
- who = g_strconcat("pbx/", temp, NULL);
- case YAHOO_FEDERATION_NONE:
- g_return_if_fail(who != NULL);
- f = yahoo_friend_find(gc, who);
- if (pkt->service == YAHOO_SERVICE_PRESENCE_PERM) {
- purple_debug_info("yahoo", "Setting permanent presence for %s to %d.\n", who, (value == 1));
- /* If setting from perm offline to online when in invisible status,
- * this has already been taken care of (when the temp status changed) */
- if (value == 2 && f->presence == YAHOO_PRESENCE_ONLINE) {
- if (value == 1) /* Setting Perm offline */
- f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
- f->presence = YAHOO_PRESENCE_DEFAULT;
- purple_debug_info("yahoo", "Setting session presence for %s to %d.\n", who, (value == 1));
- f->presence = YAHOO_PRESENCE_ONLINE;
- f->presence = YAHOO_PRESENCE_DEFAULT;
-void yahoo_friend_update_presence(PurpleConnection *gc, const char *name,
- YahooPresenceVisibility presence)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt = NULL;
- const char *thirtyone, *thirteen;
- const char *temp = NULL;
- f = yahoo_friend_find(gc, name);
- if(f->fed != YAHOO_FEDERATION_NONE)
- /* No need to change the value if it is already correct */
- if (f->presence == presence) {
- purple_debug_info("yahoo", "Not setting presence because there are no changes.\n");
- if (presence == YAHOO_PRESENCE_PERM_OFFLINE) {
- service = YAHOO_SERVICE_PRESENCE_PERM;
- } else if (presence == YAHOO_PRESENCE_DEFAULT) {
- if (f->presence == YAHOO_PRESENCE_PERM_OFFLINE) {
- service = YAHOO_SERVICE_PRESENCE_PERM;
- } else if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
- service = YAHOO_SERVICE_PRESENCE_SESSION;
- } else if (presence == YAHOO_PRESENCE_ONLINE) {
- if (f->presence == YAHOO_PRESENCE_PERM_OFFLINE) {
- pkt = yahoo_packet_new(YAHOO_SERVICE_PRESENCE_PERM,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssssiss",
- 1, purple_connection_get_display_name(gc),
- 302, "319", 300, "319",
- 301, "319", 303, "319");
- yahoo_packet_hash(pkt, "ssssssss",
- 1, purple_connection_get_display_name(gc),
- 302, "319", 300, "319",
- 301, "319", 303, "319");
- yahoo_packet_send_and_free(pkt, yd);
- service = YAHOO_SERVICE_PRESENCE_SESSION;
- pkt = yahoo_packet_new(service,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssssiss",
- 1, purple_connection_get_display_name(gc),
- 31, thirtyone, 13, thirteen,
- 302, "319", 300, "319",
- 301, "319", 303, "319");
- yahoo_packet_hash(pkt, "ssssssss",
- 1, purple_connection_get_display_name(gc),
- 31, thirtyone, 13, thirteen,
- 302, "319", 300, "319",
- 301, "319", 303, "319");
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_friend_set_p2p_status(YahooFriend *f, YahooP2PStatus p2p_status)
- f->p2p_status = p2p_status;
-YahooP2PStatus yahoo_friend_get_p2p_status(YahooFriend *f)
--- a/libpurple/protocols/yahoo/yahoo_friend.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
- * @file yahoo_friend.h The Yahoo! protocol plugin YahooFriend object
- * 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
- * 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 _YAHOO_FRIEND_H_
-#define _YAHOO_FRIEND_H_
-#include "yahoo_packet.h"
- YAHOO_PRESENCE_DEFAULT = 0,
- YAHOO_PRESENCE_PERM_OFFLINE
-} YahooPresenceVisibility;
- YAHOO_P2PSTATUS_NOT_CONNECTED = 0,
- YAHOO_P2PSTATUS_DO_NOT_CONNECT,
- YAHOO_P2PSTATUS_WE_ARE_SERVER,
- YAHOO_P2PSTATUS_WE_ARE_CLIENT
-/* these are called friends instead of buddies mainly so I can use variables
- * named f and not confuse them with variables named b
-typedef struct _YahooFriend {
- enum yahoo_status status;
- gboolean bicon_sent_request;
- YahooPresenceVisibility presence;
- YahooPersonalDetails ypd;
- YahooP2PStatus p2p_status;
- gboolean p2p_packet_sent; /* 0:not sent, 1=sent */
- gint session_id; /* session id of friend */
-YahooFriend *yahoo_friend_find(PurpleConnection *gc, const char *name);
-YahooFriend *yahoo_friend_find_or_new(PurpleConnection *gc, const char *name);
-void yahoo_friend_set_ip(YahooFriend *f, const char *ip);
-const char *yahoo_friend_get_ip(YahooFriend *f);
-void yahoo_friend_set_game(YahooFriend *f, const char *game);
-const char *yahoo_friend_get_game(YahooFriend *f);
-void yahoo_friend_set_status_message(YahooFriend *f, char *msg);
-const char *yahoo_friend_get_status_message(YahooFriend *f);
-void yahoo_friend_set_alias_id(YahooFriend *f, const char *alias_id);
-const char *yahoo_friend_get_alias_id(YahooFriend *f);
-void yahoo_friend_set_buddy_icon_need_request(YahooFriend *f, gboolean needs);
-gboolean yahoo_friend_get_buddy_icon_need_request(YahooFriend *f);
-void yahoo_friend_free(gpointer p);
-void yahoo_process_presence(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_friend_update_presence(PurpleConnection *gc, const char *name,
- YahooPresenceVisibility presence);
-void yahoo_friend_set_p2p_status(YahooFriend *f, YahooP2PStatus p2p_status);
-YahooP2PStatus yahoo_friend_get_p2p_status(YahooFriend *f);
-#endif /* _YAHOO_FRIEND_H_ */
--- a/libpurple/protocols/yahoo/yahoo_packet.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
- * 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
- * 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 "yahoo_packet.h"
-struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id)
- struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1);
- pkt->service = service;
-void yahoo_packet_hash_str(struct yahoo_packet *pkt, int key, const char *value)
- struct yahoo_pair *pair;
- g_return_if_fail(value != NULL);
- pair = g_new0(struct yahoo_pair, 1);
- pair->value = g_strdup(value);
- pkt->hash = g_slist_prepend(pkt->hash, pair);
-void yahoo_packet_hash_int(struct yahoo_packet *pkt, int key, int value)
- struct yahoo_pair *pair;
- pair = g_new0(struct yahoo_pair, 1);
- pair->value = g_strdup_printf("%d", value);
- pkt->hash = g_slist_prepend(pkt->hash, pair);
-void yahoo_packet_hash(struct yahoo_packet *pkt, const char *fmt, ...)
- for (cur = fmt; *cur; cur++) {
- intval = va_arg(ap, int);
- yahoo_packet_hash_int(pkt, key, intval);
- strval = va_arg(ap, char *);
- yahoo_packet_hash_str(pkt, key, strval);
- purple_debug_error("yahoo", "Invalid format character '%c'\n", *cur);
-size_t yahoo_packet_length(struct yahoo_packet *pkt)
- struct yahoo_pair *pair = l->data;
- len += strlen(pair->value);
- * 'len' is the value given to us by the server that is supposed to
- * be the length of 'data'. But apparently there's a time when this
- * length is incorrect. Christopher Layne thinks it might be a bug
- * in their server code.
- * The following information is from Christopher:
- * It sometimes happens when Yahoo! sends a packet continuation within
- * chat. Sometimes when joining a large chatroom the initial
- * SERVICE_CHATJOIN packet will be so large that it will need to be
- * split into multiple packets. That's fine, except that the length
- * of the second packet is wrong. The packet has the same length as
- * the first packet, and the length given in the header is the same,
- * however the actual data in the packet is shorter than this length.
- * So half of the packet contains good, valid data, and then the rest
- * of the packet is junk. Luckily there is a null terminator after
- * the valid data and before the invalid data.
- * What does all this mean? It means that we parse through the data
- * pulling out key/value pairs until we've parsed 'len' bytes, or until
- * we run into a null terminator, whichever comes first.
-void yahoo_packet_read(struct yahoo_packet *pkt, const guchar *data, int len)
- const guchar *delimiter;
- struct yahoo_pair *pair;
- pair = g_new0(struct yahoo_pair, 1);
- while (pos + 1 < len) {
- if (data[pos] == 0xc0 && data[pos + 1] == 0x80)
- if (x >= sizeof(key)-1) {
- key[x++] = data[pos++];
- if (x >= sizeof(key)-1) {
- pair->key = strtol(key, NULL, 10);
- accept = x; /* if x is 0 there was no key, so don't accept it */
- /* Malformed packet! (Truncated--garbage or something) */
- delimiter = (const guchar *)g_strstr_len((const char *)&data[pos], len - pos, "\xc0\x80");
- /* Malformed packet! (It doesn't end in 0xc0 0x80) */
- pair->value = g_strndup((const gchar *)&data[pos], x - pos);
- pkt->hash = g_slist_prepend(pkt->hash, pair);
- if (purple_debug_is_verbose() || g_getenv("PURPLE_YAHOO_DEBUG")) {
- esc = g_strescape(pair->value, NULL);
- purple_debug_misc("yahoo", "Key: %d \tValue: %s\n", pair->key, esc);
- if (pos + 1 > len) break;
- /* Skip over garbage we've noticed in the mail notifications */
- if (data[0] == '9' && data[pos] == 0x01)
- * Originally this function used g_slist_append(). I changed
- * it to use g_slist_prepend() for improved performance.
- * Ideally the Yahoo! PRPL code would be indifferent to the
- * order of the key/value pairs, but I don't know if this is
- * the case for all incoming messages. To be on the safe side
- pkt->hash = g_slist_reverse(pkt->hash);
-void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data)
- /* This is only called from one place, and the list is
- l = pkt->hash = g_slist_reverse(pkt->hash);
- struct yahoo_pair *pair = l->data;
- g_snprintf(buf, sizeof(buf), "%d", pair->key);
- strcpy((char *)&data[pos], buf);
- strcpy((char *)&data[pos], pair->value);
- pos += strlen(pair->value);
-void yahoo_packet_dump(guchar *data, int len)
- purple_debug_misc("yahoo", "");
- for (i = 0; i + 1 < len; i += 2) {
- if ((i % 16 == 0) && i) {
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- purple_debug_misc(NULL, "%02x%02x ", data[i], data[i + 1]);
- purple_debug_misc(NULL, "%02x", data[i]);
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- for (i = 0; i < len; i++) {
- if ((i % 16 == 0) && i) {
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- if (g_ascii_isprint(data[i]))
- purple_debug_misc(NULL, "%c ", data[i]);
- purple_debug_misc(NULL, ". ");
- purple_debug_misc(NULL, "\n");
-#endif /* YAHOO_DEBUG */
-yahoo_packet_send_can_write(gpointer data, gint source, PurpleInputCondition cond)
- writelen = purple_circ_buffer_get_max_read(yd->txbuf);
- purple_input_remove(yd->txhandler);
- ret = write(yd->fd, yd->txbuf->outptr, writelen);
- if (ret < 0 && errno == EAGAIN)
- /* TODO: what to do here - do we really have to disconnect? */
- purple_connection_error_reason(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- purple_circ_buffer_mark_read(yd->txbuf, ret);
-size_t yahoo_packet_build(struct yahoo_packet *pkt, int pad, gboolean wm,
- gboolean jp, guchar **buf)
- size_t pktlen = yahoo_packet_length(pkt);
- size_t len = YAHOO_PACKET_HDRLEN + pktlen;
- data = g_malloc0(len + 1);
- memcpy(data + pos, "YMSG", 4); pos += 4;
- pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER);
- pos += yahoo_put16(data + pos, YAHOO_PROTO_VER_JAPAN);
- pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
- pos += yahoo_put16(data + pos, 0x0000);
- pos += yahoo_put16(data + pos, pktlen + pad);
- pos += yahoo_put16(data + pos, pkt->service);
- pos += yahoo_put32(data + pos, pkt->status);
- pos += yahoo_put32(data + pos, pkt->id);
- yahoo_packet_write(pkt, data + pos);
-int yahoo_packet_send(struct yahoo_packet *pkt, YahooData *yd)
- len = yahoo_packet_build(pkt, 0, yd->wm, yd->jp, &data);
- yahoo_packet_dump(data, len);
- if (yd->txhandler == 0)
- ret = write(yd->fd, data, len);
- if (ret < 0 && errno == EAGAIN)
- purple_debug_warning("yahoo", "Only wrote %" G_GSSIZE_FORMAT
- " of %" G_GSIZE_FORMAT " bytes!\n", ret, len);
- if ((gsize)ret < len) {
- if (yd->txhandler == 0)
- yd->txhandler = purple_input_add(yd->fd, PURPLE_INPUT_WRITE,
- yahoo_packet_send_can_write, yd);
- purple_circ_buffer_append(yd->txbuf, data + ret, len - ret);
-int yahoo_packet_send_and_free(struct yahoo_packet *pkt, YahooData *yd)
- ret = yahoo_packet_send(pkt, yd);
- yahoo_packet_free(pkt);
-void yahoo_packet_free(struct yahoo_packet *pkt)
- struct yahoo_pair *pair = pkt->hash->data;
- pkt->hash = g_slist_delete_link(pkt->hash, pkt->hash);
--- a/libpurple/protocols/yahoo/yahoo_packet.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
- * @file yahoo_packet.h The Yahoo! protocol plugin
- * 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
- * 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 _YAHOO_PACKET_H_
-#define _YAHOO_PACKET_H_
-enum yahoo_service { /* these are easier to see in hex */
- YAHOO_SERVICE_LOGON = 1,
- YAHOO_SERVICE_IDLE, /* 5 (placemarker) */
- YAHOO_SERVICE_MAILSTAT,
- YAHOO_SERVICE_USERSTAT, /* 0xa */
- YAHOO_SERVICE_CHATINVITE,
- YAHOO_SERVICE_CALENDAR,
- YAHOO_SERVICE_NEWPERSONALMAIL,
- YAHOO_SERVICE_NEWCONTACT,
- YAHOO_SERVICE_ADDIDENT, /* 0x10 */
- YAHOO_SERVICE_ADDIGNORE,
- YAHOO_SERVICE_GOTGROUPRENAME,
- YAHOO_SERVICE_SYSMESSAGE = 0x14,
- YAHOO_SERVICE_SKINNAME = 0x15,
- YAHOO_SERVICE_PASSTHROUGH2 = 0x16,
- YAHOO_SERVICE_CONFINVITE = 0x18,
- YAHOO_SERVICE_CONFLOGON,
- YAHOO_SERVICE_CONFDECLINE,
- YAHOO_SERVICE_CONFLOGOFF,
- YAHOO_SERVICE_CONFADDINVITE,
- YAHOO_SERVICE_CHATLOGON,
- YAHOO_SERVICE_CHATLOGOFF,
- YAHOO_SERVICE_CHATMSG = 0x20,
- YAHOO_SERVICE_GAMELOGON = 0x28,
- YAHOO_SERVICE_GAMELOGOFF,
- YAHOO_SERVICE_GAMEMSG = 0x2a,
- YAHOO_SERVICE_FILETRANSFER = 0x46,
- YAHOO_SERVICE_VOICECHAT = 0x4A,
- YAHOO_SERVICE_NOTIFY = 0x4B,
- YAHOO_SERVICE_P2PFILEXFER,
- YAHOO_SERVICE_PEERTOPEER = 0x4F,
- YAHOO_SERVICE_AUTHRESP = 0x54,
- YAHOO_SERVICE_LIST = 0x55,
- YAHOO_SERVICE_AUTH = 0x57,
- YAHOO_SERVICE_AUTHBUDDY = 0x6d,
- YAHOO_SERVICE_ADDBUDDY = 0x83,
- YAHOO_SERVICE_REMBUDDY = 0x84,
- YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/
- YAHOO_SERVICE_REJECTCONTACT,
- YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */
- YAHOO_SERVICE_KEEPALIVE = 0x8A,
- YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/
- YAHOO_SERVICE_CHATGOTO,
- YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */
- YAHOO_SERVICE_CHATLEAVE,
- YAHOO_SERVICE_CHATEXIT = 0x9b,
- YAHOO_SERVICE_CHATADDINVITE = 0x9d,
- YAHOO_SERVICE_CHATLOGOUT = 0xa0,
- YAHOO_SERVICE_CHATPING,
- YAHOO_SERVICE_COMMENT = 0xa8,
- YAHOO_SERVICE_PRESENCE_PERM = 0xb9,
- YAHOO_SERVICE_PRESENCE_SESSION = 0xba,
- YAHOO_SERVICE_AVATAR = 0xbc,
- YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
- YAHOO_SERVICE_PICTURE = 0xbe,
- YAHOO_SERVICE_PICTURE_UPDATE = 0xc1,
- YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2,
- YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5,
- YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6,
- YAHOO_SERVICE_AVATAR_UPDATE = 0xc7,
- YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8,
- YAHOO_SERVICE_AUDIBLE = 0xd0,
- YAHOO_SERVICE_CONTACT_DETAILS = 0xd3,
- /* YAHOO_SERVICE_CHAT_SESSION = 0xd4,?? Reports start of chat session, gets an id from server */
- YAHOO_SERVICE_AUTH_REQ_15 = 0xd6,
- YAHOO_SERVICE_FILETRANS_15 = 0xdc,
- YAHOO_SERVICE_FILETRANS_INFO_15 = 0xdd,
- YAHOO_SERVICE_FILETRANS_ACC_15 = 0xde,
- /* photo sharing services ?? - 0xd2, 0xd7, 0xd8, 0xda */
- YAHOO_SERVICE_CHGRP_15 = 0xe7,
- YAHOO_SERVICE_STATUS_15 = 0xf0,
- YAHOO_SERVICE_LIST_15 = 0xf1,
- YAHOO_SERVICE_MESSAGE_ACK = 0xfb,
- YAHOO_SERVICE_WEBLOGIN = 0x0226,
- YAHOO_SERVICE_SMS_MSG = 0x02ea
- /* YAHOO_SERVICE_DISCONNECT = 0x07d1 Server forces us to disconnect. Is sent with TCP FIN flag set */
-#define YAHOO_WEBMESSENGER_PROTO_VER 0x0065
-#define YAHOO_PROTO_VER 0x0010
-#define YAHOO_PROTO_VER_JAPAN 0x0010
-#define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4)
-struct yahoo_packet *yahoo_packet_new(enum yahoo_service service,
- enum yahoo_status status, int id);
-void yahoo_packet_hash(struct yahoo_packet *pkt, const char *fmt, ...);
-void yahoo_packet_hash_str(struct yahoo_packet *pkt, int key, const char *value);
-void yahoo_packet_hash_int(struct yahoo_packet *pkt, int key, int value);
-int yahoo_packet_send(struct yahoo_packet *pkt, YahooData *yd);
-int yahoo_packet_send_and_free(struct yahoo_packet *pkt, YahooData *yd);
-size_t yahoo_packet_build(struct yahoo_packet *pkt, int pad, gboolean wm, gboolean jp,
-void yahoo_packet_read(struct yahoo_packet *pkt, const guchar *data, int len);
-void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data);
-void yahoo_packet_dump(guchar *data, int len);
-size_t yahoo_packet_length(struct yahoo_packet *pkt);
-void yahoo_packet_free(struct yahoo_packet *pkt);
-#endif /* _YAHOO_PACKET_H_ */
--- a/libpurple/protocols/yahoo/yahoo_picture.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,611 +0,0 @@
- * 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
- * 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 "yahoo_packet.h"
-#include "yahoo_friend.h"
-#include "yahoo_picture.h"
-struct yahoo_fetch_picture_data {
-yahoo_fetch_picture_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *pic_data, size_t len, const gchar *error_message)
- struct yahoo_fetch_picture_data *d;
- yd = d->gc->proto_data;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- if (error_message != NULL) {
- purple_debug_error("yahoo", "Fetching buddy icon failed: %s\n", error_message);
- purple_debug_error("yahoo", "Fetched an icon with length 0. Strange.\n");
- char *checksum = g_strdup_printf("%i", d->checksum);
- purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, g_memdup(pic_data, len), len, checksum);
-void yahoo_process_picture(PurpleConnection *gc, struct yahoo_packet *pkt)
- gboolean got_icon_info = FALSE, send_icon_info = FALSE;
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_picture "
- "got non-UTF-8 string for key %d\n", pair->key);
- tmp = strtol(pair->value, NULL, 10);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_picture "
- "got non-UTF-8 string for key %d\n", pair->key);
- checksum = strtol(pair->value, NULL, 10);
- if (!purple_privacy_check(purple_connection_get_account(gc), who)) {
- purple_debug_info("yahoo", "Picture packet from %s dropped.\n", who);
- /* Yahoo IM 6 spits out 0.png as the URL if the buddy icon is not set */
- if (who && got_icon_info && url && !g_ascii_strncasecmp(url, "http://", 7)) {
- /* TODO: make this work p2p, try p2p before the url */
- PurpleUtilFetchUrlData *url_data;
- struct yahoo_fetch_picture_data *data;
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- data = g_new0(struct yahoo_fetch_picture_data, 1);
- data->who = g_strdup(who);
- data->checksum = checksum;
- /* TODO: Does this need to be MSIE 5.0? */
- url_data = purple_util_fetch_url(url, use_whole_url,
- "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE,
- yahoo_fetch_picture_cb, data);
- if (url_data != NULL) {
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- } else if (who && send_icon_info) {
- yahoo_send_picture_info(gc, who);
-void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_picture_checksum "
- "got non-UTF-8 string for key %d\n", pair->key);
- checksum = strtol(pair->value, NULL, 10);
- PurpleBuddy *b = purple_find_buddy(gc->account, who);
- const char *locksum = NULL;
- /* FIXME: Cleanup this strtol() stuff if possible. */
- locksum = purple_buddy_icons_get_checksum_for_user(b);
- if (!locksum || (checksum != strtol(locksum, NULL, 10)))
- yahoo_send_picture_request(gc, who);
-void yahoo_process_picture_upload(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- struct yahoo_pair *pair = l->data;
- /* filename on our computer. */
- case 20: /* url at yahoo */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_picture_upload "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 38: /* timestamp */
- g_free(yd->picture_url);
- yd->picture_url = g_strdup(url);
- purple_account_set_string(account, YAHOO_PICURL_SETTING, url);
- purple_account_set_int(account, YAHOO_PICCKSUM_SETTING, yd->picture_checksum);
- yahoo_send_picture_checksum(gc);
- yahoo_send_picture_update(gc, 2);
-void yahoo_process_avatar_update(PurpleConnection *gc, struct yahoo_packet *pkt)
- struct yahoo_pair *pair = l->data;
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_avatar_upload "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 206: /* Older versions. Still needed? */
- case 213: /* Newer versions */
- * 0 - No icon or avatar
- avatar = strtol(pair->value, NULL, 10);
- yahoo_send_picture_request(gc, who);
- else if ((avatar == 0) || (avatar == 1)) {
- purple_buddy_icons_set_for_user(gc->account, who, NULL, 0, NULL);
- if ((f = yahoo_friend_find(gc, who)))
- yahoo_friend_set_buddy_icon_need_request(f, TRUE);
- purple_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who);
-void yahoo_send_picture_info(PurpleConnection *gc, const char *who)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- if (!yd->picture_url) {
- purple_debug_warning("yahoo", "Attempted to send picture info without a picture\n");
- pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssssi", 1, purple_connection_get_display_name(gc),
- 13, "2", 20, yd->picture_url, 192, yd->picture_checksum);
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_send_picture_request(PurpleConnection *gc, const char *who)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, purple_connection_get_display_name(gc)); /* me */
- yahoo_packet_hash_str(pkt, 5, who); /* the other guy */
- yahoo_packet_hash_str(pkt, 13, "1"); /* 1 = request, 2 = reply */
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_send_picture_checksum(PurpleConnection *gc)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssi", 1, purple_connection_get_display_name(gc),
- 212, "1", 192, yd->picture_checksum);
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_send_picture_update_to_user(PurpleConnection *gc, const char *who, int type)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- pkt = yahoo_packet_new(YAHOO_SERVICE_AVATAR_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "si", 3, who, 213, type);
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_send_picture_update_foreach(gpointer key, gpointer value, gpointer data)
- YahooFriend *f = value;
- struct yspufe *d = data;
- if (f->status != YAHOO_STATUS_OFFLINE)
- yahoo_send_picture_update_to_user(d->gc, who, d->type);
-void yahoo_send_picture_update(PurpleConnection *gc, int type)
- YahooData *yd = gc->proto_data;
- g_hash_table_foreach(yd->friends, yahoo_send_picture_update_foreach, &data);
-void yahoo_buddy_icon_upload_data_free(struct yahoo_buddy_icon_upload_data *d)
- purple_debug_misc("yahoo", "In yahoo_buddy_icon_upload_data_free()\n");
- g_string_free(d->str, TRUE);
- purple_input_remove(d->watcher);
-/* we couldn't care less about the server's response, but yahoo gets grumpy if we close before it sends it */
-static void yahoo_buddy_icon_upload_reading(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_buddy_icon_upload_data *d = data;
- PurpleConnection *gc = d->gc;
- if (!PURPLE_CONNECTION_IS_VALID(gc)) {
- yahoo_buddy_icon_upload_data_free(d);
- ret = read(d->fd, buf, sizeof(buf));
- if (ret < 0 && errno == EAGAIN)
- /* There are other problems if d->str->len overflows, so shut up the
- * warning on 64-bit. */
- purple_debug_info("yahoo", "Buddy icon upload response (%" G_GSIZE_FORMAT ") bytes (> ~400 indicates failure):\n%.*s\n",
- d->str->len, (guint)d->str->len, d->str->str);
- yahoo_buddy_icon_upload_data_free(d);
- g_string_append_len(d->str, buf, ret);
-static void yahoo_buddy_icon_upload_pending(gpointer data, gint source, PurpleInputCondition condition)
- struct yahoo_buddy_icon_upload_data *d = data;
- PurpleConnection *gc = d->gc;
- if (!PURPLE_CONNECTION_IS_VALID(gc)) {
- yahoo_buddy_icon_upload_data_free(d);
- wrote = write(d->fd, d->str->str + d->pos, d->str->len - d->pos);
- if (wrote < 0 && errno == EAGAIN)
- purple_debug_info("yahoo", "Error uploading buddy icon.\n");
- yahoo_buddy_icon_upload_data_free(d);
- if ((size_t)d->pos >= d->str->len) {
- purple_debug_misc("yahoo", "Finished uploading buddy icon.\n");
- purple_input_remove(d->watcher);
- /* Clean out the sent buffer and reuse it to read the result */
- g_string_free(d->str, TRUE);
- d->str = g_string_new("");
- d->watcher = purple_input_add(d->fd, PURPLE_INPUT_READ, yahoo_buddy_icon_upload_reading, d);
-static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, const gchar *error_message)
- struct yahoo_buddy_icon_upload_data *d = data;
- struct yahoo_packet *pkt;
- PurpleConnection *gc = d->gc;
- PurpleAccount *account;
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
- account = purple_connection_get_account(gc);
- /* Buddy icon connect is now complete; clear the PurpleProxyConnectData */
- yd->buddy_icon_connect_data = NULL;
- purple_debug_error("yahoo", "Buddy icon upload failed: %s\n", error_message);
- yahoo_buddy_icon_upload_data_free(d);
- pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id);
- tmp = g_strdup_printf("%" G_GSIZE_FORMAT, d->str->len);
- /* 1 = me, 38 = expire time(?), 0 = me, 28 = size, 27 = filename, 14 = NULL, 29 = data */
- yahoo_packet_hash_str(pkt, 1, purple_connection_get_display_name(gc));
- yahoo_packet_hash_str(pkt, 38, "604800"); /* time til expire */
- purple_account_set_int(account, YAHOO_PICEXPIRE_SETTING, time(NULL) + 604800);
- yahoo_packet_hash_str(pkt, 0, purple_connection_get_display_name(gc));
- yahoo_packet_hash_str(pkt, 28, tmp);
- yahoo_packet_hash_str(pkt, 27, d->filename);
- yahoo_packet_hash_str(pkt, 14, "");
- /* 4 padding for the 29 key name */
- pkt_buf_len = yahoo_packet_build(pkt, 4, FALSE, yd->jp, &pkt_buf);
- yahoo_packet_free(pkt);
- /* header + packet + "29" + 0xc0 + 0x80) + pictureblob */
- host = purple_account_get_string(account, "xfer_host", yd->jp? YAHOOJP_XFER_HOST : YAHOO_XFER_HOST);
- port = purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT);
- tmp = g_strdup_printf("%s:%d", host, port);
- header = g_strdup_printf("POST %s%s/notifyft HTTP/1.1\r\n"
- "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
- "Cookie: T=%s; Y=%s\r\n"
- "Content-Length: %" G_GSIZE_FORMAT "\r\n"
- "Cache-Control: no-cache\r\n\r\n",
- use_whole_url ? "http://" : "", use_whole_url ? tmp : "",
- yd->cookie_t, yd->cookie_y,
- pkt_buf_len + 4 + d->str->len);
- /* There's no magic here, we just need to prepend in reverse order */
- g_string_prepend(d->str, "29\xc0\x80");
- g_string_prepend_len(d->str, (char *)pkt_buf, pkt_buf_len);
- g_string_prepend(d->str, header);
- /* There are other problems if we're uploading over 4GB of data */
- purple_debug_info("yahoo", "Buddy icon upload data:\n%.*s\n", (guint)d->str->len, d->str->str);
- d->watcher = purple_input_add(d->fd, PURPLE_INPUT_WRITE, yahoo_buddy_icon_upload_pending, d);
- yahoo_buddy_icon_upload_pending(d, d->fd, PURPLE_INPUT_WRITE);
-void yahoo_buddy_icon_upload(PurpleConnection *gc, struct yahoo_buddy_icon_upload_data *d)
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = gc->proto_data;
- if (yd->buddy_icon_connect_data != NULL) {
- /* Cancel any in-progress buddy icon upload */
- purple_proxy_connect_cancel(yd->buddy_icon_connect_data);
- yd->buddy_icon_connect_data = NULL;
- yd->buddy_icon_connect_data = purple_proxy_connect(NULL, account,
- purple_account_get_string(account, "xfer_host",
- yd->jp? YAHOOJP_XFER_HOST : YAHOO_XFER_HOST),
- purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
- yahoo_buddy_icon_upload_connected, d);
- if (yd->buddy_icon_connect_data == NULL)
- purple_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n");
- yahoo_buddy_icon_upload_data_free(d);
-static int yahoo_buddy_icon_calculate_checksum(const guchar *data, gsize len)
- /* This code is borrowed from Kopete, which seems to be managing to calculate
- checksums in such a manner that Yahoo!'s servers are happy */
- const guchar *p = data;
- int checksum = 0, g, i = len;
- checksum = (checksum << 4) + *p++;
- if((g = (checksum & 0xf0000000)) != 0)
- purple_debug_misc("yahoo", "Calculated buddy icon checksum: %d\n", checksum);
-void yahoo_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
- YahooData *yd = gc->proto_data;
- PurpleAccount *account = gc->account;
- g_free(yd->picture_url);
- yd->picture_url = NULL;
- /* TODO: don't we have to clear it on the server too?! */
- purple_account_set_string(account, YAHOO_PICURL_SETTING, NULL);
- purple_account_set_int(account, YAHOO_PICCKSUM_SETTING, 0);
- purple_account_set_int(account, YAHOO_PICEXPIRE_SETTING, 0);
- /* Tell everyone we ain't got one no more */
- yahoo_send_picture_update(gc, 0);
- gconstpointer data = purple_imgstore_get_data(img);
- size_t len = purple_imgstore_get_size(img);
- GString *s = g_string_new_len(data, len);
- struct yahoo_buddy_icon_upload_data *d;
- int oldcksum = purple_account_get_int(account, YAHOO_PICCKSUM_SETTING, 0);
- int expire = purple_account_get_int(account, YAHOO_PICEXPIRE_SETTING, 0);
- const char *oldurl = purple_account_get_string(account, YAHOO_PICURL_SETTING, NULL);
- yd->picture_checksum = yahoo_buddy_icon_calculate_checksum(data, len);
- if ((yd->picture_checksum == oldcksum) &&
- (expire > (time(NULL) + 60*60*24)) && oldurl)
- purple_debug_misc("yahoo", "buddy icon is up to date. Not reuploading.\n");
- g_string_free(s, TRUE);
- g_free(yd->picture_url);
- yd->picture_url = g_strdup(oldurl);
- /* We use this solely for sending a filename to the server */
- d = g_new0(struct yahoo_buddy_icon_upload_data, 1);
- d->filename = g_strdup(purple_imgstore_get_filename(img));
- yd->picture_upload_todo = d;
- yahoo_buddy_icon_upload(gc, d);
--- a/libpurple/protocols/yahoo/yahoo_picture.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
- * 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
- * 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 _YAHOO_PICTURE_H_
-#define _YAHOO_PICTURE_H_
-void yahoo_send_picture_request(PurpleConnection *gc, const char *who);
-void yahoo_send_picture_info(PurpleConnection *gc, const char *who);
-void yahoo_send_picture_checksum(PurpleConnection *gc);
-void yahoo_send_picture_update(PurpleConnection *gc, int type);
-void yahoo_send_picture_update_to_user(PurpleConnection *gc, const char *who, int type);
-void yahoo_process_picture(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_picture_checksum(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_picture_upload(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_avatar_update(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img);
-void yahoo_buddy_icon_upload(PurpleConnection *gc, struct yahoo_buddy_icon_upload_data *d);
-void yahoo_buddy_icon_upload_data_free(struct yahoo_buddy_icon_upload_data *d);
-#endif /* _YAHOO_PICTURE_H_ */
--- a/libpurple/protocols/yahoo/yahoo_profile.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1282 +0,0 @@
- * 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
- * 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
-#endif /* PHOTO_SUPPORT */
-#include "yahoo_friend.h"
-typedef enum profile_lang_id {
- ES_AR, ES_ES, ES_MX, ES_US,
- IT, JA, KO, NO, PT, SV,
- ZH_CN, ZH_HK, ZH_TW, ZH_US, PT_BR
-typedef struct profile_lang_node {
- profile_lang_id_t lang;
- char *last_updated_string;
-typedef struct profile_strings_node {
- profile_lang_id_t lang;
- char *lang_string; /* Only to make debugging output saner */
- char *no_answer_string;
- char *maritalstatus_string;
- char *occupation_string;
- char *latest_news_string;
- char *favorite_quote_string;
- char *no_home_page_specified_string;
- char *home_page_string;
- char *no_cool_link_specified_string;
- char *cool_link_1_string;
- char *cool_link_2_string;
- char *cool_link_3_string;
-} profile_strings_node_t;
-typedef enum profile_state {
- PROFILE_STATE_NOT_FOUND,
- PROFILE_STATE_UNKNOWN_LANGUAGE
- YahooGetInfoData *info_data;
- PurpleNotifyUserInfo *user_info;
- char *profile_url_text;
- const profile_strings_node_t *strings;
- const char *last_updated_string;
- profile_state_t profile_state;
-} YahooGetInfoStepTwoData;
-/* Strings to determine the profile "language" (more accurately "locale").
- * Strings in this list must be in the original charset in the profile.
- * The "Last Updated" string is used, but sometimes is not sufficient to
- * distinguish 2 locales with this (e.g., ES_ES from ES_US, or FR_CA from
- * FR_FR, or EL from EN_GB), in which case a second string is added and
- * such special cases must be placed before the more general case.
-static const profile_lang_node_t profile_langs[] = {
- { DA, "Opdateret sidste gang ", NULL },
- { DE, "Letzter Update ", NULL },
- { EL, "Last Updated:", "http://gr.profiles.yahoo.com" },
- { EN_GB, "Last Update ", "Favourite Quote" },
- { EN, "Last Update:", NULL },
- { EN, "Last Update ", NULL },
- { ES_AR, "\332ltima actualizaci\363n ", NULL },
- { ES_ES, "Actualizada el ", "http://es.profiles.yahoo.com" },
- { ES_MX, "Actualizada el ", "http://mx.profiles.yahoo.com" },
- { ES_US, "Actualizada el ", NULL },
- { FR_CA, "Derni\xe8re mise \xe0 jour", "http://cf.profiles.yahoo.com" },
- { FR_FR, "Derni\xe8re mise \xe0 jour", NULL },
- { IT, "Ultimo aggiornamento:", NULL },
- { JA, "\xba\xc7\xbd\xaa\xb9\xb9\xbf\xb7\xc6\xfc\xa1\xa7", NULL },
- { KO, "\xb0\xbb\xbd\xc5\x20\xb3\xaf\xc2\xa5 ", NULL },
- { NO, "Sist oppdatert ", NULL },
- { PT, "\332ltima atualiza\347\343o ", NULL },
- { PT_BR, "\332ltima atualiza\347\343o:", NULL },
- { SV, "Senast uppdaterad ", NULL },
- { ZH_CN, "\xd7\xee\xba\xf3\xd0\xde\xb8\xc4\xc8\xd5\xc6\xda", NULL },
- { ZH_HK, "\xb3\xcc\xaa\xf1\xa7\xf3\xb7\x73\xae\xc9\xb6\xa1", NULL },
- { ZH_US, "\xb3\xcc\xab\xe1\xad\xd7\xa7\xef\xa4\xe9\xb4\xc1", "http://chinese.profiles.yahoo.com" },
- { ZH_TW, "\xb3\xcc\xab\xe1\xad\xd7\xa7\xef\xa4\xe9\xb4\xc1", NULL },
-/* Strings in this list must be in UTF-8; 's should be specified as spaces. */
-static const profile_strings_node_t profile_strings[] = {
- { DA, "da", "ISO-8859-1",
- "Ægteskabelig status:",
- "Ingen hjemmeside specificeret",
- "Intet cool link specificeret",
- { DE, "de", "ISO-8859-1",
- "Mein Lieblingsspruch",
- "Keine Homepage angegeben",
- "Keinen coolen Link angegeben",
- { EL, "el", "ISO-8859-7", /* EL is identical to EN, except no_answer_string */
- "No home page specified",
- "No cool link specified",
- { EN, "en", "ISO-8859-1",
- "No home page specified",
- "No cool link specified",
- { EN_GB, "en_GB", "ISO-8859-1", /* Same as EN except spelling of "Favourite" */
- "No home page specified",
- "No cool link specified",
- { ES_AR, "es_AR", "ISO-8859-1",
- "No introdujiste una respuesta",
- "Mi dirección de correo electrónico",
- "Ninguna página de inicio especificada",
- "Ningún enlace preferido",
- { ES_ES, "es_ES", "ISO-8859-1",
- "Ninguna página personal especificada",
- "Ningún enlace preferido",
- "Enlaces Preferidos 1:",
- "Enlaces Preferidos 2:",
- "Enlaces Preferidos 3:",
- { ES_MX, "es_MX", "ISO-8859-1",
- "Mi Dirección de correo-e",
- "Ninguna Página predefinida",
- "Ningún Enlace preferido",
- "Enlaces Preferidos 1:",
- "Enlaces Preferidos 2:",
- "Enlaces Preferidos 3:",
- { ES_US, "es_US", "ISO-8859-1",
- "No introdujo una respuesta",
- "Mi Dirección de correo-e",
- "Ninguna Página de inicio predefinida",
- "Ningún Enlace preferido",
- "Enlaces Preferidos 1:",
- "Enlaces Preferidos 2:",
- "Enlaces Preferidos 3:",
- { FR_CA, "fr_CA", "ISO-8859-1",
- "Pas de mention d'une page personnelle",
- "Pas de mention d'un lien favori",
- { FR_FR, "fr_FR", "ISO-8859-1",
- "Situation de famille:",
- "Pas de mention d'une page perso",
- "Pas de mention d'un lien favori",
- { IT, "it", "ISO-8859-1",
- "Nessuna home page specificata",
- "Nessun link specificato",
- "自己PR", /* "Self description" comes before "Links" for yahoo.co.jp */
- { NO, "no", "ISO-8859-1",
- "Ingen hjemmeside angitt",
- "No cool link specified",
- { PT, "pt", "ISO-8859-1",
- "Nenhuma página pessoal especificada",
- "Nenhum site legal especificado",
- { PT_BR, "pt_br", "ISO-8859-1",
- "Nenhuma home page especificada",
- "Nenhum site legal especificado",
- { SV, "sv", "ISO-8859-1",
- "Ingen hemsida specificerad",
- "Ingen cool länk specificerad",
- { ZH_CN, "zh_CN", "GB2312",
- { ZH_HK, "zh_HK", "Big5",
- "最喜愛的股票叫價", /* [sic] Yahoo!'s translators don't check context */
- "沒有注明個人網頁", /* [sic] */
- "沒有注明 Cool 連結", /* [sic] */
- "Cool 連結 1:", /* TODO */
- "Cool 連結 2:", /* TODO */
- "Cool 連結 3:", /* TODO */
- { ZH_TW, "zh_TW", "Big5",
- { ZH_US, "zh_US", "Big5", /* ZH_US is like ZH_TW, but also a bit like ZH_HK */
- "推薦網站連結 1:", /* TODO */
- "推薦網站連結 2:", /* TODO */
- "推薦網站連結 3:", /* TODO */
-static char *yahoo_info_date_reformat(const char *field, size_t len)
- char *tmp = g_strndup(field, len);
- time_t t = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
- return g_strdup(purple_date_format_short(localtime(&t)));
-static char *yahoo_remove_nonbreaking_spaces(char *str)
- while ((p = strstr(str, " ")) != NULL) {
- *p = ' '; /* Turn 's into ordinary blanks */
- memmove(p, p + 5, strlen(p + 5));
- str[strlen(str) - 5] = '\0';
-static void yahoo_extract_user_info_text(PurpleNotifyUserInfo *user_info, YahooGetInfoData *info_data) {
- b = purple_find_buddy(purple_connection_get_account(info_data->gc),
- const char *balias = purple_buddy_get_local_buddy_alias(b);
- if(balias && balias[0]) {
- purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias);
- char *idletime = purple_str_seconds_to_string(time(NULL) - b->idle);
- purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), idletime);
- /* Add the normal tooltip pairs */
- yahoo_tooltip_text(b, user_info, TRUE);
- if ((f = yahoo_friend_find(info_data->gc, purple_buddy_get_name(b)))) {
- if ((ip = yahoo_friend_get_ip(f)))
- purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), ip);
-static char *yahoo_get_photo_url(const char *url_text, const char *name) {
- GString *s = g_string_sized_new(strlen(name) + 8);
- /*g_string_printf(s, " alt=\"%s\">", name);*/
- g_string_printf(s, " alt=%s>", name);
- p = strstr(url_text, s->str);
- /* Search backwards for "http://". This is stupid, but it works. */
- for (; !it && p > url_text; p -= 1) {
- /*if (strncmp(p, "\"http://", 8) == 0) {*/
- if (strncmp(p, "=http://", 8) == 0) {
- p += 1; /* skip only the ' ' */
- it = g_strndup(p, q - p);
- g_string_free(s, TRUE);
-yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
- const gchar *url_text, size_t len, const gchar *error_message);
-#endif /* PHOTO_SUPPORT */
-static void yahoo_got_info(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *url_text, size_t len, const gchar *error_message)
- YahooGetInfoData *info_data = (YahooGetInfoData *)user_data;
- PurpleNotifyUserInfo *user_info;
- YahooGetInfoStepTwoData *info2_data;
- char *photo_url_text = NULL;
- gboolean found = FALSE;
- char *last_updated_utf8_string = NULL;
-#endif /* !PHOTO_SUPPORT */
- const char *last_updated_string = NULL;
- char *profile_url_text = NULL;
- const profile_strings_node_t *strings = NULL;
- profile_state_t profile_state = PROFILE_STATE_DEFAULT;
- purple_debug_info("yahoo", "In yahoo_got_info\n");
- yd = info_data->gc->proto_data;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- user_info = purple_notify_user_info_new();
- title = yd->jp ? _("Yahoo! Japan Profile") :
- /* Get the tooltip info string */
- yahoo_extract_user_info_text(user_info, info_data);
- /* We failed to grab the profile URL. This is not expected to actually
- * happen except under unusual error conditions, as Yahoo is observed
- * to send back HTML, with a 200 status code.
- if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) {
- purple_notify_user_info_add_pair(user_info, _("Error retrieving profile"), NULL);
- purple_notify_userinfo(info_data->gc, info_data->name,
- user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- g_free(profile_url_text);
- g_free(info_data->name);
- /* Construct the correct profile URL */
- s = g_string_sized_new(80); /* wild guess */
- g_string_printf(s, "%s%s", (yd->jp? YAHOOJP_PROFILE_URL: YAHOO_PROFILE_URL),
- profile_url_text = g_string_free(s, FALSE);
- /* We don't yet support the multiple link level of the warning page for
- * 'adult' profiles, not to mention the fact that yahoo wants you to be
- * logged in (on the website) to be able to view an 'adult' profile. For
- * now, just tell them that we can't help them, and provide a link to the
- * profile if they want to do the web browser thing.
- p = strstr(url_text, "Adult Profiles Warning Message");
- p = strstr(url_text, "Adult Content Warning"); /* TITLE element */
- tmp = g_strdup_printf("<b>%s</b><br><br>"
- "%s<br><a href=\"%s\">%s</a>",
- _("Sorry, profiles marked as containing adult content "
- "are not supported at this time."),
- _("If you wish to view this profile, "
- "you will need to visit this link in your web browser:"),
- profile_url_text, profile_url_text);
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
- purple_notify_userinfo(info_data->gc, info_data->name,
- user_info, NULL, NULL);
- g_free(profile_url_text);
- purple_notify_user_info_destroy(user_info);
- g_free(info_data->name);
- /* Check whether the profile is written in a supported language */
- for (lang = 0;; lang += 1) {
- last_updated_string = profile_langs[lang].last_updated_string;
- if (!last_updated_string)
- p = strstr(url_text, last_updated_string);
- if (profile_langs[lang].det && !strstr(url_text, profile_langs[lang].det))
- for (strid = 0; profile_strings[strid].lang != XX; strid += 1) {
- if (profile_strings[strid].lang == profile_langs[lang].lang) break;
- strings = profile_strings + strid;
- purple_debug_info("yahoo", "detected profile lang = %s (%d)\n", profile_strings[strid].lang_string, lang);
- /* Every user may choose his/her own profile language, and this language
- * has nothing to do with the preferences of the user which looks at the
- * profile. We try to support all languages, but nothing is guaranteed.
- * If we cannot determine the language, it means either (1) the profile
- * is written in an unsupported language, (2) our language support is
- * out of date, or (3) the user is not found, or (4) Y! have changed their
- if (!p || strings->lang == XX) {
- if (!strstr(url_text, "Yahoo! Member Directory - User not found")
- && !strstr(url_text, "was not found on this server.")
- && !strstr(url_text, "\xb8\xf8\xb3\xab\xa5\xd7\xa5\xed\xa5\xd5\xa5\xa3\xa1\xbc\xa5\xeb\xa4\xac\xb8\xab\xa4\xc4\xa4\xab\xa4\xea\xa4\xde\xa4\xbb\xa4\xf3")) {
- profile_state = PROFILE_STATE_UNKNOWN_LANGUAGE;
- profile_state = PROFILE_STATE_NOT_FOUND;
- photo_url_text = yahoo_get_photo_url(url_text, info_data->name);
-#endif /* PHOTO_SUPPORT */
- url_buffer = g_strdup(url_text);
- * purple_markup_strip_html() doesn't strip out character entities like
- yahoo_remove_nonbreaking_spaces(url_buffer);
- while ((p = strstr(url_buffer, "·")) != NULL) {
- memmove(p, p + 6, strlen(p + 6));
- url_buffer[strlen(url_buffer) - 6] = '\0';
- /* nuke the nasty \r's */
- purple_str_strip_char(url_buffer, '\r');
- /* Marshall the existing state */
- info2_data = g_malloc(sizeof(YahooGetInfoStepTwoData));
- info2_data->info_data = info_data;
- info2_data->url_buffer = url_buffer;
- info2_data->photo_url_text = photo_url_text;
- info2_data->profile_url_text = profile_url_text;
- info2_data->strings = strings;
- info2_data->last_updated_string = last_updated_string;
- info2_data->title = title;
- info2_data->profile_state = profile_state;
- info2_data->user_info = user_info;
- /* Try to put the photo in there too, if there's one */
- PurpleUtilFetchUrlData *url_data;
- /* use whole URL if using HTTP Proxy */
- gboolean use_whole_url = yahoo_account_use_http_proxy(info_data->gc);
- /* User-uploaded photos use a different server that requires the Host
- * header, but Yahoo Japan will use the "chunked" content encoding if
- * we specify HTTP 1.1. So we have to specify 1.0 & fix purple_util_fetch_url
- url_data = purple_util_fetch_url(photo_url_text, use_whole_url, NULL,
- FALSE, yahoo_got_photo, info2_data);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
- /* Emulate a callback */
- yahoo_got_photo(NULL, info2_data, NULL, 0, NULL);
-yahoo_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
- const gchar *url_text, size_t len, const gchar *error_message)
- YahooGetInfoStepTwoData *info2_data = (YahooGetInfoStepTwoData *)data;
- gboolean found = FALSE;
- /* Temporary variables */
- char *last_updated_utf8_string = NULL;
- /* Unmarshall the saved state */
- YahooGetInfoData *info_data = info2_data->info_data;
- char *url_buffer = info2_data->url_buffer;
- PurpleNotifyUserInfo *user_info = info2_data->user_info;
- char *photo_url_text = info2_data->photo_url_text;
- char *profile_url_text = info2_data->profile_url_text;
- const profile_strings_node_t *strings = info2_data->strings;
- const char *last_updated_string = info2_data->last_updated_string;
- profile_state_t profile_state = info2_data->profile_state;
- /* We continue here from yahoo_got_info, as if nothing has happened */
-#endif /* PHOTO_SUPPORT */
- /* Jun 29 05 Bleeter: Y! changed their profile pages. Terminators now seem to be */
- /* </dd> and not \n. The prpl's need to be audited before it can be moved */
- /* in to purple_markup_strip_html*/
- yd = info_data->gc->proto_data;
- yd->url_datas = g_slist_remove(yd->url_datas, url_data);
- fudged_buffer = purple_strcasereplace(url_buffer, "</dd>", "</dd><br>");
- /* nuke the html, it's easier than trying to parse the horrid stuff */
- stripped = purple_markup_strip_html(fudged_buffer);
- stripped_len = strlen(stripped);
- purple_debug_misc("yahoo", "stripped = %p\n", stripped);
- purple_debug_misc("yahoo", "url_buffer = %p\n", url_buffer);
- if (strings && strings->charset) {
- p = g_convert(stripped, -1, "utf-8", strings->charset,
- p = g_locale_to_utf8(stripped, -1, NULL, NULL, NULL);
- p = g_convert(stripped, -1, "utf-8", "windows-1252",
- stripped = purple_utf8_ncr_decode(p);
- stripped_len = strlen(stripped);
- /* "Last updated" should also be converted to utf8 and with killed */
- if (strings && strings->charset) {
- last_updated_utf8_string = g_convert(last_updated_string, -1, "utf-8",
- strings->charset, NULL, NULL, NULL);
- yahoo_remove_nonbreaking_spaces(last_updated_utf8_string);
- purple_debug_misc("yahoo", "after utf8 conversion: stripped = (%s)\n", stripped);
- if (strings && profile_state == PROFILE_STATE_DEFAULT) {
- /* extract their Yahoo! ID and put it in. Don't bother marking has_info as
- * true, since the Yahoo! ID will always be there */
- if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->yahoo_id_string, (yd->jp ? 2 : 10), "\n", 0,
- NULL, _("Yahoo! ID"), 0, NULL, NULL))
- /* Try to put the photo in there too, if there's one and is readable */
- if (url_text && len != 0) {
- if (strstr(url_text, "400 Bad Request")
- || strstr(url_text, "403 Forbidden")
- || strstr(url_text, "404 Not Found")) {
- purple_debug_info("yahoo", "Error getting %s: %s\n",
- photo_url_text, url_text);
- 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);
- tmp = g_strdup_printf("<img id=\"%d\"><br>", id);
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
-#endif /* PHOTO_SUPPORT */
- /* extract their Email address and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->my_email_string, (yd->jp ? 4 : 1), " ", 0,
- strings->private_string, _("Email"), 0, NULL, NULL);
- /* extract the Nickname if it exists */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- "Nickname:", 1, "\n", '\n',
- NULL, _("Nickname"), 0, NULL, NULL);
- /* extract their RealName and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->realname_string, (yd->jp ? 3 : 1), "\n", '\n',
- NULL, _("Real Name"), 0, NULL, NULL);
- /* extract their Location and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->location_string, (yd->jp ? 4 : 2), "\n", '\n',
- NULL, _("Location"), 0, NULL, NULL);
- /* extract their Age and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->age_string, (yd->jp ? 2 : 3), "\n", '\n',
- NULL, _("Age"), 0, NULL, NULL);
- /* extract their MaritalStatus and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->maritalstatus_string, (yd->jp ? 2 : 3), "\n", '\n',
- strings->no_answer_string, _("Marital Status"), 0, NULL, NULL);
- /* extract their Gender and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->gender_string, (yd->jp ? 2 : 3), "\n", '\n',
- strings->no_answer_string, _("Gender"), 0, NULL, NULL);
- /* extract their Occupation and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->occupation_string, 2, "\n", '\n',
- NULL, _("Occupation"), 0, NULL, NULL);
- /* Hobbies, Latest News, and Favorite Quote are a bit different, since
- * the values can contain embedded newlines... but any or all of them
- * can also not appear. The way we delimit them is to successively
- * look for the next one that _could_ appear, and if all else fails,
- * we end the section by looking for the 'Links' heading, which is the
- * next thing to follow this bunch. (For Yahoo Japan, we check for
- * the "Description" ("Self PR") heading instead of "Links".)
- if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->hobbies_string, (yd->jp ? 3 : 1), strings->latest_news_string,
- '\n', "\n", _("Hobbies"), 0, NULL, NULL))
- if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->hobbies_string, 1, strings->favorite_quote_string,
- '\n', "\n", _("Hobbies"), 0, NULL, NULL))
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->hobbies_string, 1, strings->links_string,
- '\n', "\n", _("Hobbies"), 0, NULL, NULL);
- if (!purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->latest_news_string, 1, strings->favorite_quote_string,
- '\n', "\n", _("Latest News"), 0, NULL, NULL))
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->latest_news_string, (yd->jp ? 2 : 1), strings->links_string,
- '\n', "\n", _("Latest News"), 0, NULL, NULL);
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->favorite_quote_string, 1, strings->links_string,
- '\n', "\n", _("Favorite Quote"), 0, NULL, NULL);
- /* Home Page will either be "No home page specified",
- * or "Home Page: " and a link.
- * For Yahoo! Japan, if there is no home page specified,
- * neither "No home page specified" nor "Home Page:" is shown.
- if (strings->home_page_string) {
- p = !strings->no_home_page_specified_string? NULL:
- strstr(stripped, strings->no_home_page_specified_string);
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->home_page_string, 1, "\n", 0, NULL,
- _("Home Page"), 1, NULL, NULL);
- /* Cool Link {1,2,3} is also different. If "No cool link specified"
- * exists, then we have none. If we have one however, we'll need to
- * check and see if we have a second one. If we have a second one,
- * we have to check to see if we have a third one.
- p = !strings->no_cool_link_specified_string? NULL:
- strstr(stripped,strings->no_cool_link_specified_string);
- if (purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->cool_link_1_string, 1, "\n", 0, NULL,
- _("Cool Link 1"), 1, NULL, NULL))
- if (purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->cool_link_2_string, 1, "\n", 0, NULL,
- _("Cool Link 2"), 1, NULL, NULL))
- purple_markup_extract_info_field(stripped, stripped_len, user_info,
- strings->cool_link_3_string, 1, "\n", 0, NULL,
- _("Cool Link 3"), 1, NULL, NULL);
- if (last_updated_utf8_string != NULL) {
- /* see if Member Since is there, and if so, extract it. */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- "Member Since:", 1, last_updated_utf8_string,
- '\n', NULL, _("Member Since"), 0, NULL, yahoo_info_date_reformat);
- /* extract the Last Updated date and put it in */
- found |= purple_markup_extract_info_field(stripped, stripped_len, user_info,
- last_updated_utf8_string, (yd->jp ? 2 : 1), (yd->jp ? "\n" : " "), (yd->jp ? 0 : '\n'), NULL,
- _("Last Update"), 0, NULL, (yd->jp ? NULL : yahoo_info_date_reformat));
- } /* if (profile_state == PROFILE_STATE_DEFAULT) */
- purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_pair(user_info,
- _("Error retrieving profile"), NULL);
- if (profile_state == PROFILE_STATE_UNKNOWN_LANGUAGE) {
- str = _("This profile is in a language "
- "or format that is not supported at this time.");
- } else if (profile_state == PROFILE_STATE_NOT_FOUND) {
- PurpleBuddy *b = purple_find_buddy
- (purple_connection_get_account(info_data->gc),
- /* Someone on the buddy list can be "not on server list",
- * in which case the user may or may not actually exist.
- * Hence this extra step.
- PurpleAccount *account = purple_buddy_get_account(b);
- f = yahoo_friend_find(purple_account_get_connection(account),
- purple_buddy_get_name(b));
- str = f ? _("Could not retrieve the user's profile. "
- "This most likely is a temporary server-side problem. "
- "Please try again later.") :
- _("Could not retrieve the user's profile. "
- "This most likely means that the user does not exist; "
- "however, Yahoo! sometimes does fail to find a user's "
- "profile. If you know that the user exists, "
- "please try again later.");
- str = _("The user's profile is empty.");
- purple_notify_user_info_add_pair(user_info, NULL, str);
- /* put a link to the actual profile URL */
- purple_notify_user_info_add_section_break(user_info);
- tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
- profile_url_text, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
- /* show it to the user */
- purple_notify_userinfo(info_data->gc, info_data->name,
- user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- g_free(last_updated_utf8_string);
- g_free(profile_url_text);
- g_free(info_data->name);
- g_free(photo_url_text);
- purple_imgstore_unref_by_id(id);
-#endif /* PHOTO_SUPPORT */
-void yahoo_get_info(PurpleConnection *gc, const char *name)
- YahooData *yd = gc->proto_data;
- YahooGetInfoData *data;
- PurpleUtilFetchUrlData *url_data;
- data = g_new0(YahooGetInfoData, 1);
- data->name = g_strdup(name);
- url = g_strdup_printf("%s%s",
- (yd->jp ? YAHOOJP_PROFILE_URL : YAHOO_PROFILE_URL), name);
- url_data = purple_util_fetch_url(url, TRUE, NULL, FALSE, yahoo_got_info, data);
- yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
--- a/libpurple/protocols/yahoo/yahoochat.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1684 +0,0 @@
- * 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
- * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com>
- * (marv on irc.freenode.net)
- * Some code borrowed from libyahoo2, copyright (C) 2002, Philip
- * S Tellis <philip . tellis AT gmx . 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
-#endif /* HAVE_CONFIG_H */
-#include "conversation.h"
-#include "yahoo_packet.h"
-#define YAHOO_CHAT_ID (1)
-static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout);
-/* special function to log us on to the yahoo chat service */
-static void yahoo_chat_online(PurpleConnection *gc)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- ycht_connection_open(gc);
- rll = purple_account_get_string(purple_connection_get_account(gc),
- "room_list_locale", YAHOO_ROOMLIST_LOCALE);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssss",
- 109, purple_connection_get_display_name(gc),
- 1, purple_connection_get_display_name(gc),
- /* I'm not sure this is the correct way to set this. */
- 135, yd->jp ? YAHOO_CLIENT_VERSION : YAHOOJP_CLIENT_VERSION);
- yahoo_packet_send_and_free(pkt, yd);
-/* this is slow, and different from the purple_* version in that it (hopefully) won't add a user twice */
-void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers)
- for (i = newusers; i; i = i->next) {
- if (purple_conv_chat_find_user(chat, i->data))
- purple_conv_chat_add_user(chat, i->data, NULL, PURPLE_CBFLAGS_NONE, TRUE);
-void yahoo_chat_add_user(PurpleConvChat *chat, const char *user, const char *reason)
- if (purple_conv_chat_find_user(chat, user))
- purple_conv_chat_add_user(chat, user, reason, PURPLE_CBFLAGS_NONE, TRUE);
-static PurpleConversation *yahoo_find_conference(PurpleConnection *gc, const char *name)
- for (l = yd->confs; l; l = l->next) {
- PurpleConversation *c = l->data;
- if (!purple_utf8_strcasecmp(purple_conversation_get_name(c), name))
-void yahoo_process_conference_invite(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account;
- GString *members = NULL;
- GHashTable *components;
- if ( (pkt->status == 2) || (pkt->status == 11) )
- return; /* Status is 11 when we are being notified about invitation being sent to someone else */
- account = purple_connection_get_account(gc);
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (yahoo_find_conference(gc, room) != NULL)
- /* Looks like we got invited to an already open conference. */
- /* Laters: Should we accept this conference rather than ignoring the invitation ? */
- purple_debug_info("yahoo","Ignoring invitation for an already existing chat, room:%s\n",room);
- members = g_string_sized_new(512);
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- case 1: /* us, but we already know who we are */
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- g_string_append_printf(members, "%s\n", who);
- purple_debug_warning("yahoo", "yahoo_process_conference_invite "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 51: /* This user is being invited to the conference. Comes with status = 11, so we wont reach here */
- case 52: /* Invited users. Assuming us invited, since we got this packet */
- break; /* break needed, or else we add the users to the conference before they accept the invitation */
- case 53: /* members who have already joined the conference */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- g_string_append_printf(members, "%s\n", pair->value);
- purple_debug_warning("yahoo", "yahoo_process_conference_invite "
- "got non-UTF-8 string for key %d\n", pair->key);
- msg = yahoo_string_decode(gc, pair->value, FALSE);
- g_string_free(members, TRUE);
- if (!purple_privacy_check(account, who) ||
- (purple_account_get_bool(account, "ignore_invites", FALSE)))
- purple_debug_info("yahoo",
- "Invite to conference %s from %s has been dropped.\n", room, who);
- g_string_free(members, TRUE);
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_replace(components, g_strdup("room"), room);
- g_hash_table_replace(components, g_strdup("topic"), msg);
- g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
- g_hash_table_replace(components, g_strdup("members"), g_string_free(members, FALSE));
- serv_got_chat_invite(gc, room, who, msg, components);
-void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleConversation *c = NULL;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_conference_decline "
- "got non-UTF-8 string for key %d\n", pair->key);
- msg = yahoo_string_decode(gc, pair->value, FALSE);
- utf8 = strtol(pair->value, NULL, 10);
- if (!purple_privacy_check(purple_connection_get_account(gc), who))
- /* make sure we're in the room before we process a decline message for it */
- if((c = yahoo_find_conference(gc, room))) {
- char *tmp = NULL, *msg_tmp = NULL;
- msg_tmp = yahoo_string_decode(gc, msg, utf8);
- msg = yahoo_codes_to_html(msg_tmp);
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
- tmp = g_strdup_printf(_("%s has declined to join."), who);
- purple_conversation_write(c, NULL, tmp, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LINKIFY, time(NULL));
-void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *pkt)
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_conference_logon "
- "got non-UTF-8 string for key %d\n", pair->key);
- c = yahoo_find_conference(gc, room);
- { /* Prevent duplicate users in the chat */
- if( !purple_conv_chat_find_user(PURPLE_CONV_CHAT(c), who) )
- yahoo_chat_add_user(PURPLE_CONV_CHAT(c), who, NULL);
-void yahoo_process_conference_logoff(PurpleConnection *gc, struct yahoo_packet *pkt)
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_conference_logoff "
- "got non-UTF-8 string for key %d\n", pair->key);
- c = yahoo_find_conference(gc, room);
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
-void yahoo_process_conference_message(PurpleConnection *gc, struct yahoo_packet *pkt)
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_conference_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- utf8 = strtol(pair->value, NULL, 10);
- if (room && who && msg) {
- c = yahoo_find_conference(gc, room);
- msg2 = yahoo_string_decode(gc, msg, utf8);
- msg = yahoo_codes_to_html(msg2);
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
-static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic, const char *id)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- g_return_if_fail(yd->ycht != NULL);
- ycht_chat_join(yd->ycht, room);
- /* apparently room names are always utf8, or else always not utf8,
- * so we don't have to actually pass the flag in the packet. Or something. */
- room2 = yahoo_string_encode(gc, room, &utf8);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "ssss",
- 1, purple_connection_get_display_name(gc),
- yahoo_packet_send_and_free(pkt, yd);
-/* this is a confirmation of yahoo_chat_online(); */
-void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt)
- YahooData *yd = (YahooData *) gc->proto_data;
- if (pkt->status == 1) {
- yd->chat_online = TRUE;
- /* We need to goto a user in chat */
- if (yd->pending_chat_goto) {
- struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss",
- 109, yd->pending_chat_goto,
- 1, purple_connection_get_display_name(gc),
- yahoo_packet_send_and_free(pkt, yd);
- } else if (yd->pending_chat_room) {
- yahoo_chat_join(gc, purple_connection_get_display_name(gc), yd->pending_chat_room,
- yd->pending_chat_topic, yd->pending_chat_id);
- g_free(yd->pending_chat_room);
- yd->pending_chat_room = NULL;
- g_free(yd->pending_chat_id);
- yd->pending_chat_id = NULL;
- g_free(yd->pending_chat_topic);
- yd->pending_chat_topic = NULL;
- g_free(yd->pending_chat_goto);
- yd->pending_chat_goto = NULL;
-/* this is basicly the opposite of chat_online */
-void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt)
- YahooData *yd = (YahooData *) gc->proto_data;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (g_ascii_strcasecmp(pair->value,
- purple_connection_get_display_name(gc)))
- if (pkt->status == 1) {
- yd->chat_online = FALSE;
- g_free(yd->pending_chat_room);
- yd->pending_chat_room = NULL;
- g_free(yd->pending_chat_id);
- yd->pending_chat_id = NULL;
- g_free(yd->pending_chat_topic);
- yd->pending_chat_topic = NULL;
- g_free(yd->pending_chat_goto);
- yd->pending_chat_goto = NULL;
- yahoo_c_leave(gc, YAHOO_CHAT_ID);
-void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account = purple_connection_get_account(gc);
- YahooData *yd = (YahooData *) gc->proto_data;
- PurpleConversation *c = NULL;
- if (pkt->status == -1) {
- struct yahoo_pair *pair = pkt->hash->data;
- gchar const *failed_to_join = _("Failed to join chat");
- switch (atoi(pair->value)) {
- case 0xFFFFFFFA: /* -6 */
- purple_notify_error(gc, NULL, failed_to_join, _("Unknown room"));
- case 0xFFFFFFF1: /* -15 */
- purple_notify_error(gc, NULL, failed_to_join, _("Maybe the room is full"));
- case 0xFFFFFFDD: /* -35 */
- purple_notify_error(gc, NULL, failed_to_join, _("Not available"));
- purple_notify_error(gc, NULL, failed_to_join,
- _("Unknown error. You may need to logout and wait five minutes before being able to rejoin a chatroom"));
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, TRUE);
- topic = yahoo_string_decode(gc, pair->value, TRUE);
- case 128: /* some id */
- case 108: /* number of joiners */
- case 129: /* some other id */
- case 130: /* some base64 or hash or something */
- case 126: /* some negative number */
- case 13: /* this is 1. maybe its the type of room? (normal, user created, private, etc?) */
- case 61: /*this looks similar to 130 */
- /* the previous section was just room info. this next section is
- info about individual room members, (including us) */
- case 109: /* the yahoo id */
- if (g_utf8_validate(pair->value, -1, NULL)) {
- members = g_list_append(members, pair->value);
- purple_debug_warning("yahoo", "yahoo_process_chat_join "
- "got non-UTF-8 string for key %d\n", pair->key);
- case 141: /* nickname */
- case 142: /* location */
- case 113: /* bitmask */
- if (room && yd->chat_name && purple_utf8_strcasecmp(room, yd->chat_name))
- yahoo_chat_leave(gc, room,
- purple_connection_get_display_name(gc), FALSE);
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
- if (room && (!c || purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) &&
- members && (members->next ||
- !g_ascii_strcasecmp(members->data, purple_connection_get_display_name(gc)))) {
- for (l = members; l; l = l->next)
- flags = g_list_prepend(flags, GINT_TO_POINTER(PURPLE_CBFLAGS_NONE));
- if (c && purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) {
- /* this might be a hack, but oh well, it should nicely */
- purple_conversation_set_name(c, room);
- c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
- /* Also print the topic to the backlog so that the captcha link is clickable */
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
- yd->chat_name = g_strdup(room);
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
- tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room);
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", tmpmsg, PURPLE_MESSAGE_SYSTEM, time(NULL));
- c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
- /* Also print the topic to the backlog so that the captcha link is clickable */
- purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
- yd->chat_name = g_strdup(room);
- purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
- const char *cur_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(c));
- if (cur_topic == NULL || strcmp(cur_topic, topic) != 0)
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
- yahoo_chat_add_users(PURPLE_CONV_CHAT(c), members);
- if (account->deny && c) {
- PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(c);
- for (l = account->deny; l != NULL; l = l->next) {
- for (roomies = members; roomies; roomies = roomies->next) {
- if (!purple_utf8_strcasecmp((char *)l->data, roomies->data)) {
- purple_debug_info("yahoo", "Ignoring room member %s in room %s\n" , (char *)roomies->data, room ? room : "");
- purple_conv_chat_ignore(PURPLE_CONV_CHAT(c),roomies->data);
- ops->chat_update_user(c, roomies->data);
-void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt)
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- if (pair->key == 104) {
- room = yahoo_string_decode(gc, pair->value, TRUE);
- if (pair->key == 109) {
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_chat_exit "
- "got non-UTF-8 string for key %d\n", pair->key);
- PurpleConversation *c = purple_find_chat(gc, YAHOO_CHAT_ID);
- if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room))
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
-void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt)
- char *room = NULL, *who = NULL, *msg = NULL, *msg2;
- int msgtype = 1, utf8 = 1; /* default to utf8 */
- PurpleConversation *c = NULL;
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- utf8 = strtol(pair->value, NULL, 10);
- room = yahoo_string_decode(gc, pair->value, TRUE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_chat_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_chat_message "
- "got non-UTF-8 string for key %d\n", pair->key);
- msgtype = strtol(pair->value, NULL, 10);
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
- /* we still get messages after we part, funny that */
- purple_debug_misc("yahoo", "Got a message packet with no message.\nThis probably means something important, but we're ignoring it.\n");
- msg2 = yahoo_string_decode(gc, msg, utf8);
- msg = yahoo_codes_to_html(msg2);
- if (msgtype == 2 || msgtype == 3) {
- tmp = g_strdup_printf("/me %s", msg);
- serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, msg, time(NULL));
-void yahoo_process_chat_addinvite(PurpleConnection *gc, struct yahoo_packet *pkt)
- PurpleAccount *account;
- account = purple_connection_get_account(gc);
- for (l = pkt->hash; l; l = l->next) {
- struct yahoo_pair *pair = l->data;
- room = yahoo_string_decode(gc, pair->value, TRUE);
- case 129: /* room id? */
- msg = yahoo_string_decode(gc, pair->value, FALSE);
- if (g_utf8_validate(pair->value, -1, NULL)) {
- purple_debug_warning("yahoo", "yahoo_process_chat_addinvite "
- "got non-UTF-8 string for key %d\n", pair->key);
- GHashTable *components;
- if (!purple_privacy_check(account, who) ||
- (purple_account_get_bool(account, "ignore_invites", FALSE)))
- purple_debug_info("yahoo", "Invite to room %s from %s has been dropped.\n", room, who);
- components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- g_hash_table_replace(components, g_strdup("room"), g_strdup(room));
- serv_got_chat_invite(gc, room, who, msg, components);
-void yahoo_process_chat_goto(PurpleConnection *gc, struct yahoo_packet *pkt)
- purple_notify_error(gc, NULL, _("Failed to join buddy in chat"),
- _("Maybe they're not in a chat?"));
- * Functions dealing with conferences
- * I think conference names are always ascii.
-void yahoo_conf_leave(YahooData *yd, const char *room, const char *dn, GList *who)
- struct yahoo_packet *pkt;
- purple_debug_misc("yahoo", "leaving conference %s\n", room);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, dn);
- for (w = who; w; w = w->next) {
- const char *name = purple_conv_chat_cb_get_name(w->data);
- yahoo_packet_hash_str(pkt, 3, name);
- yahoo_packet_hash_str(pkt, 57, room);
- yahoo_packet_send_and_free(pkt, yd);
-static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *room,
- GList *members, const char *what)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- msg = yahoo_html_to_codes(what);
- msg2 = yahoo_string_encode(gc, msg, &utf8);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, dn);
- for (who = members; who; who = who->next) {
- const char *name = purple_conv_chat_cb_get_name(who->data);
- yahoo_packet_hash_str(pkt, 53, name);
- yahoo_packet_hash(pkt, "ss", 57, room, 14, msg2);
- yahoo_packet_hash_str(pkt, 97, "1"); /* utf-8 */
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_conf_join(YahooData *yd, PurpleConversation *c, const char *dn, const char *room,
- const char *topic, const char *members)
- struct yahoo_packet *pkt;
- memarr = g_strsplit(members, "\n", 0);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 1, dn, 3, dn, 57, room);
- for(i = 0 ; memarr[i]; i++) {
- if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn))
- yahoo_packet_hash_str(pkt, 3, memarr[i]);
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), memarr[i], NULL, PURPLE_CBFLAGS_NONE, TRUE);
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c,
- const char *dn, const char *buddy, const char *room, const char *msg)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- msg2 = yahoo_string_encode(gc, msg, NULL);
- members = purple_conv_chat_get_users(PURPLE_CONV_CHAT(c));
- pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssss", 1, dn, 51, buddy, 57, room, 58, msg?msg2:"", 13, "0");
- for(; members; members = members->next) {
- const char *name = purple_conv_chat_cb_get_name(members->data);
- yahoo_packet_hash(pkt, "ss", 52, name, 53, name);
- yahoo_packet_send_and_free(pkt, yd);
- * Functions dealing with chats
-static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- g_return_if_fail(yd->ycht != NULL);
- ycht_chat_leave(yd->ycht, room, logout);
- eroom = yahoo_string_encode(gc, room, &utf8);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 104, eroom, 109, dn, 108, "1");
- yahoo_packet_hash_str(pkt, 112, "0"); /* what does this one mean? */
- yahoo_packet_send_and_free(pkt, yd);
- if (purple_find_chat(gc, YAHOO_CHAT_ID) != NULL)
- serv_got_chat_left(gc, YAHOO_CHAT_ID);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT,
- YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash_str(pkt, 1, dn);
- yahoo_packet_send_and_free(pkt, yd);
- yd->chat_online = FALSE;
- g_free(yd->pending_chat_room);
- yd->pending_chat_room = NULL;
- g_free(yd->pending_chat_id);
- yd->pending_chat_id = NULL;
- g_free(yd->pending_chat_topic);
- yd->pending_chat_topic = NULL;
- g_free(yd->pending_chat_goto);
- yd->pending_chat_goto = NULL;
-static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- char *msg1, *msg2, *room2;
- g_return_val_if_fail(yd->ycht != NULL, 1);
- return ycht_chat_send(yd->ycht, room, what);
- if (purple_message_meify(msg1, -1))
- msg2 = yahoo_html_to_codes(msg1);
- msg1 = yahoo_string_encode(gc, msg2, &utf8);
- room2 = yahoo_string_encode(gc, room, NULL);
- pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 1, dn, 104, room2, 117, msg1);
- yahoo_packet_hash_str(pkt, 124, "2");
- yahoo_packet_hash_str(pkt, 124, "1");
- /* fixme: what about /think? (124=3) */
- yahoo_packet_hash_str(pkt, 97, "1");
- yahoo_packet_send_and_free(pkt, yd);
-static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy,
- const char *room, const char *msg)
- YahooData *yd = gc->proto_data;
- struct yahoo_packet *pkt;
- char *room2, *msg2 = NULL;
- g_return_if_fail(yd->ycht != NULL);
- ycht_chat_send_invite(yd->ycht, room, buddy, msg);
- room2 = yahoo_string_encode(gc, room, &utf8);
- msg2 = yahoo_string_encode(gc, msg, NULL);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sssss", 1, dn, 118, buddy, 104, room2, 117, (msg2?msg2:""), 129, "0");
- yahoo_packet_send_and_free(pkt, yd);
-void yahoo_chat_goto(PurpleConnection *gc, const char *name)
- struct yahoo_packet *pkt;
- g_return_if_fail(yd->ycht != NULL);
- ycht_chat_goto_user(yd->ycht, name);
- if (!yd->chat_online) {
- g_free(yd->pending_chat_room);
- yd->pending_chat_room = NULL;
- g_free(yd->pending_chat_id);
- yd->pending_chat_id = NULL;
- g_free(yd->pending_chat_topic);
- yd->pending_chat_topic = NULL;
- g_free(yd->pending_chat_goto);
- yd->pending_chat_goto = g_strdup(name);
- pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, yd->session_id);
- yahoo_packet_hash(pkt, "sss", 109, name, 1, purple_connection_get_display_name(gc), 62, "2");
- yahoo_packet_send_and_free(pkt, yd);
- * These are the functions registered with the core
- * which get called for both chats and conferences.
-void yahoo_c_leave(PurpleConnection *gc, int id)
- YahooData *yd = (YahooData *) gc->proto_data;
- c = purple_find_chat(gc, id);
- if (id != YAHOO_CHAT_ID) {
- yahoo_conf_leave(yd, purple_conversation_get_name(c),
- purple_connection_get_display_name(gc), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)));
- yd->confs = g_slist_remove(yd->confs, c);
- yahoo_chat_leave(gc, purple_conversation_get_name(c), purple_connection_get_display_name(gc), TRUE);
- serv_got_chat_left(gc, id);
-int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags)
- yd = (YahooData *) gc->proto_data;
- c = purple_find_chat(gc, id);
- if (id != YAHOO_CHAT_ID) {
- ret = yahoo_conf_send(gc, purple_connection_get_display_name(gc),
- purple_conversation_get_name(c), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)), what);
- ret = yahoo_chat_send(gc, purple_connection_get_display_name(gc),
- purple_conversation_get_name(c), what, flags);
- serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)),
- purple_connection_get_display_name(gc), flags, what, time(NULL));
-GList *yahoo_c_info(PurpleConnection *gc)
- struct proto_chat_entry *pce;
- pce = g_new0(struct proto_chat_entry, 1);
- pce->label = _("_Room:");
- pce->identifier = "room";
- m = g_list_append(m, pce);
-GHashTable *yahoo_c_info_defaults(PurpleConnection *gc, const char *chat_name)
- defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
- g_hash_table_insert(defaults, "room", g_strdup(chat_name));
-char *yahoo_get_chat_name(GHashTable *data)
- return g_strdup(g_hash_table_lookup(data, "room"));
-void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
- char *room, *topic, *type;
- yd = (YahooData *) gc->proto_data;
- room = g_hash_table_lookup(data, "room");
- topic = g_hash_table_lookup(data, "topic");
- if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) {
- const char *members = g_hash_table_lookup(data, "members");
- c = serv_got_joined_chat(gc, id, room);
- yd->confs = g_slist_prepend(yd->confs, c);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), purple_connection_get_display_name(gc), topic);
- yahoo_conf_join(yd, c, purple_connection_get_display_name(gc), room, topic, members);
- yahoo_chat_leave(gc, room,
- purple_connection_get_display_name(gc),
- id = g_hash_table_lookup(data, "id");
- if (!yd->chat_online) {
- g_free(yd->pending_chat_room);
- yd->pending_chat_room = g_strdup(room);
- g_free(yd->pending_chat_id);
- yd->pending_chat_id = g_strdup(id);
- g_free(yd->pending_chat_topic);
- yd->pending_chat_topic = g_strdup(topic);
- g_free(yd->pending_chat_goto);
- yd->pending_chat_goto = NULL;
- yahoo_chat_join(gc, purple_connection_get_display_name(gc), room, topic, id);
-void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name)
- c = purple_find_chat(gc, id);
- if (id != YAHOO_CHAT_ID) {
- yahoo_conf_invite(gc, c, purple_connection_get_display_name(gc), name,
- purple_conversation_get_name(c), msg);
- yahoo_chat_invite(gc, purple_connection_get_display_name(gc), name,
- purple_conversation_get_name(c), msg);
- PurpleRoomlistRoom *cat;
- PurpleRoomlistRoom *ucat;
- GMarkupParseContext *parse;
-static void yahoo_roomlist_destroy(struct yahoo_roomlist *yrl)
- purple_input_remove(yrl->inpa);
- g_markup_parse_context_free(yrl->parse);
-struct yahoo_chatxml_state {
- struct yahoo_roomlist *yrl;
- enum yahoo_room_type type;
- int users, voices, webcams;
- int count, users, voices, webcams;
-static struct yahoo_chatxml_state *yahoo_chatxml_state_new(PurpleRoomlist *list, struct yahoo_roomlist *yrl)
- struct yahoo_chatxml_state *s;
- s = g_new0(struct yahoo_chatxml_state, 1);
-static void yahoo_chatxml_state_destroy(struct yahoo_chatxml_state *s)
-static void yahoo_chatlist_start_element(GMarkupParseContext *context,
- const gchar *ename, const gchar **anames,
- const gchar **avalues, gpointer user_data,
- struct yahoo_chatxml_state *s = user_data;
- PurpleRoomlist *list = s->list;
- PurpleRoomlistRoom *parent;
- if (!strcmp(ename, "category")) {
- const gchar *name = NULL, *id = NULL;
- for (i = 0; anames[i]; i++) {
- if (!strcmp(anames[i], "id"))
- if (!strcmp(anames[i], "name"))
- parent = g_queue_peek_head(s->q);
- r = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, name, parent);
- purple_roomlist_room_add_field(list, r, (gpointer)name);
- purple_roomlist_room_add_field(list, r, (gpointer)id);
- purple_roomlist_room_add(list, r);
- g_queue_push_head(s->q, r);
- } else if (!strcmp(ename, "room")) {
- s->room.users = s->room.voices = s->room.webcams = 0;
- for (i = 0; anames[i]; i++) {
- if (!strcmp(anames[i], "id")) {
- s->room.id = g_strdup(avalues[i]);
- } else if (!strcmp(anames[i], "name")) {
- s->room.name = g_strdup(avalues[i]);
- } else if (!strcmp(anames[i], "topic")) {
- s->room.topic = g_strdup(avalues[i]);
- } else if (!strcmp(anames[i], "type")) {
- if (!strcmp("yahoo", avalues[i]))
- s->room.type = yrt_yahoo;
- s->room.type = yrt_user;
- } else if (!strcmp(ename, "lobby")) {
- struct yahoo_lobby *lob = g_new0(struct yahoo_lobby, 1);
- for (i = 0; anames[i]; i++) {
- if (!strcmp(anames[i], "count")) {
- lob->count = strtol(avalues[i], NULL, 10);
- } else if (!strcmp(anames[i], "users")) {
- s->room.users += lob->users = strtol(avalues[i], NULL, 10);
- } else if (!strcmp(anames[i], "voices")) {
- s->room.voices += lob->voices = strtol(avalues[i], NULL, 10);
- } else if (!strcmp(anames[i], "webcams")) {
- s->room.webcams += lob->webcams = strtol(avalues[i], NULL, 10);
- g_queue_push_head(s->q, lob);
-static void yahoo_chatlist_end_element(GMarkupParseContext *context, const gchar *ename,
- gpointer user_data, GError **error)
- struct yahoo_chatxml_state *s = user_data;
- if (!strcmp(ename, "category")) {
- g_queue_pop_head(s->q);
- } else if (!strcmp(ename, "room")) {
- struct yahoo_lobby *lob;
- PurpleRoomlistRoom *r, *l;
- if (s->room.type == yrt_yahoo)
- r = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY|PURPLE_ROOMLIST_ROOMTYPE_ROOM,
- s->room.name, s->yrl->cat);
- r = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY|PURPLE_ROOMLIST_ROOMTYPE_ROOM,
- s->room.name, s->yrl->ucat);
- purple_roomlist_room_add_field(s->list, r, s->room.name);
- purple_roomlist_room_add_field(s->list, r, s->room.id);
- purple_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.users));
- purple_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.voices));
- purple_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.webcams));
- purple_roomlist_room_add_field(s->list, r, s->room.topic);
- purple_roomlist_room_add(s->list, r);
- while ((lob = g_queue_pop_head(s->q))) {
- char *name = g_strdup_printf("%s:%d", s->room.name, lob->count);
- l = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, r);
- purple_roomlist_room_add_field(s->list, l, name);
- purple_roomlist_room_add_field(s->list, l, s->room.id);
- purple_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->users));
- purple_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->voices));
- purple_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->webcams));
- purple_roomlist_room_add_field(s->list, l, s->room.topic);
- purple_roomlist_room_add(s->list, l);
-static GMarkupParser parser = {
- yahoo_chatlist_start_element,
- yahoo_chatlist_end_element,
-static void yahoo_roomlist_cleanup(PurpleRoomlist *list, struct yahoo_roomlist *yrl)
- purple_roomlist_set_in_progress(list, FALSE);
- list->proto_data = g_list_remove(list->proto_data, yrl);
- yahoo_roomlist_destroy(yrl);
- purple_roomlist_unref(list);
-static void yahoo_roomlist_pending(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_roomlist *yrl = data;
- PurpleRoomlist *list = yrl->list;
- struct yahoo_chatxml_state *s;
- len = read(yrl->fd, buf, sizeof(buf));
- if (len < 0 && errno == EAGAIN)
- g_markup_parse_context_end_parse(yrl->parse, NULL);
- yahoo_roomlist_cleanup(list, yrl);
- yrl->rxqueue = g_realloc(yrl->rxqueue, len + yrl->rxlen);
- memcpy(yrl->rxqueue + yrl->rxlen, buf, len);
- start = (guchar *)g_strstr_len((char *)yrl->rxqueue, yrl->rxlen, "\r\n\r\n");
- if (!start || (start - yrl->rxqueue + 4) >= yrl->rxlen)
- if (yrl->parse == NULL) {
- s = yahoo_chatxml_state_new(list, yrl);
- yrl->parse = g_markup_parse_context_new(&parser, 0, s,
- (GDestroyNotify)yahoo_chatxml_state_destroy);
- if (!g_markup_parse_context_parse(yrl->parse, (char *)start, (yrl->rxlen - (start - yrl->rxqueue)), NULL)) {
- yahoo_roomlist_cleanup(list, yrl);
-static void yahoo_roomlist_send_cb(gpointer data, gint source, PurpleInputCondition cond)
- struct yahoo_roomlist *yrl;
- int written, remaining;
- remaining = strlen(yrl->txbuf) - yrl->tx_written;
- written = write(yrl->fd, yrl->txbuf + yrl->tx_written, remaining);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- purple_input_remove(yrl->inpa);
- purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
- yahoo_roomlist_cleanup(list, yrl);
- if (written < remaining) {
- yrl->tx_written += written;
- purple_input_remove(yrl->inpa);
- yrl->inpa = purple_input_add(yrl->fd, PURPLE_INPUT_READ,
- yahoo_roomlist_pending, yrl);
-static void yahoo_roomlist_got_connected(gpointer data, gint source, const gchar *error_message)
- struct yahoo_roomlist *yrl = data;
- PurpleRoomlist *list = yrl->list;
- YahooData *yd = purple_account_get_connection(list->account)->proto_data;
- purple_notify_error(purple_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));
- yahoo_roomlist_cleanup(list, yrl);
- yrl->txbuf = g_strdup_printf(
- "GET http://%s/%s HTTP/1.0\r\n"
- "Cookie: Y=%s; T=%s\r\n\r\n",
- yrl->host, yrl->path, yrl->host, yd->cookie_y,
- yrl->inpa = purple_input_add(yrl->fd, PURPLE_INPUT_WRITE,
- yahoo_roomlist_send_cb, yrl);
- yahoo_roomlist_send_cb(yrl, yrl->fd, PURPLE_INPUT_WRITE);
-PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc)
- PurpleAccount *account;
- PurpleRoomlistField *f;
- struct yahoo_roomlist *yrl;
- const char *rll, *rlurl;
- account = purple_connection_get_account(gc);
- /* for Yahoo Japan, it appears there is only one valid URL and locale */
- if(purple_account_get_bool(account, "yahoojp", FALSE)) {
- rll = YAHOOJP_ROOMLIST_LOCALE;
- rlurl = YAHOOJP_ROOMLIST_URL;
- else { /* but for the rest of the world that isn't the case */
- rll = purple_account_get_string(account, "room_list_locale", YAHOO_ROOMLIST_LOCALE);
- rlurl = purple_account_get_string(account, "room_list", YAHOO_ROOMLIST_URL);
- url = g_strdup_printf("%s?chatcat=0&intl=%s", rlurl, rll);
- yrl = g_new0(struct yahoo_roomlist, 1);
- rl = purple_roomlist_new(account);
- purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "room", TRUE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "id", TRUE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, _("Voices"), "voices", FALSE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, _("Webcams"), "webcams", FALSE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE);
- fields = g_list_append(fields, f);
- purple_roomlist_set_fields(rl, fields);
- if (purple_proxy_connect(gc, account, yrl->host, 80,
- yahoo_roomlist_got_connected, yrl) == NULL)
- purple_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list."));
- yahoo_roomlist_cleanup(rl, yrl);
- rl->proto_data = g_list_append(rl->proto_data, yrl);
- purple_roomlist_set_in_progress(rl, TRUE);
-void yahoo_roomlist_cancel(PurpleRoomlist *list)
- k = l = list->proto_data;
- list->proto_data = NULL;
- purple_roomlist_set_in_progress(list, FALSE);
- for (; l; l = l->next) {
- yahoo_roomlist_destroy(l->data);
- purple_roomlist_unref(list);
-void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category)
- struct yahoo_roomlist *yrl;
- if (category->type != PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
- if (!(id = g_list_nth_data(category->fields, 1))) {
- purple_roomlist_set_in_progress(list, FALSE);
- rll = purple_account_get_string(list->account, "room_list_locale",
- YAHOO_ROOMLIST_LOCALE);
- if (rll != NULL && *rll != '\0') {
- url = g_strdup_printf("%s?chatroom_%s=0&intl=%s",
- purple_account_get_string(list->account,"room_list",
- YAHOO_ROOMLIST_URL), id, rll);
- url = g_strdup_printf("%s?chatroom_%s=0",
- purple_account_get_string(list->account,"room_list",
- YAHOO_ROOMLIST_URL), id);
- yrl = g_new0(struct yahoo_roomlist, 1);
- list->proto_data = g_list_append(list->proto_data, yrl);
- purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);
- yrl->ucat = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat);
- purple_roomlist_room_add(list, yrl->ucat);
- if (purple_proxy_connect(purple_account_get_connection(list->account),
- list->account, yrl->host, 80,
- yahoo_roomlist_got_connected, yrl) == NULL)
- purple_notify_error(purple_account_get_connection(list->account),
- NULL, _("Connection problem"), _("Unable to fetch room list."));
- purple_roomlist_ref(list);
- yahoo_roomlist_cleanup(list, yrl);
- purple_roomlist_set_in_progress(list, TRUE);
- purple_roomlist_ref(list);
--- a/libpurple/protocols/yahoo/yahoochat.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
- * @file yahoochat.h The Yahoo! protocol plugin, chat and conference stuff
- * 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
- * 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 "yahoo_packet.h"
-void yahoo_process_conference_invite(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_conference_logoff(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_conference_message(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_join(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_addinvite(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_process_chat_goto(PurpleConnection *gc, struct yahoo_packet *pkt);
-void yahoo_c_leave(PurpleConnection *gc, int id);
-int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags);
-GList *yahoo_c_info(PurpleConnection *gc);
-GHashTable *yahoo_c_info_defaults(PurpleConnection *gc, const char *chat_name);
-void yahoo_c_join(PurpleConnection *gc, GHashTable *data);
-char *yahoo_get_chat_name(GHashTable *data);
-void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name);
-void yahoo_conf_leave(YahooData *yd, const char *room, const char *dn, GList *who);
-void yahoo_chat_goto(PurpleConnection *gc, const char *name);
-/* room listing functions */
-PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc);
-void yahoo_roomlist_cancel(PurpleRoomlist *list);
-void yahoo_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category);
-void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers);
-void yahoo_chat_add_user(PurpleConvChat *chat, const char *user, const char *reason);
-#endif /* _YAHOO_CHAT_H_ */
--- a/libpurple/protocols/yahoo/ycht.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,658 +0,0 @@
- * @file ycht.c The Yahoo! protocol plugin, YCHT protocol stuff.
- * Copyright (C) 2004 Timothy Ringenbach <omarvo@hotmail.com>
- * Liberal amounts of code borrowed from the rest of the Yahoo! prpl.
- * 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
- * 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 "conversation.h"
-#include "yahoo_packet.h"
-#define YAHOO_CHAT_ID (1)
-/************************************************************************************
- * Functions to process various kinds of packets.
- ************************************************************************************/
-static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt)
- PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
- yd->chat_online = TRUE;
- ycht->logged_in = TRUE;
- ycht_chat_join(ycht, ycht->room);
-static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt)
- PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
- yd->chat_online = FALSE;
- ycht->logged_in = FALSE;
-static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt)
- PurpleConnection *gc = ycht->gc;
- PurpleConversation *c = NULL;
- gboolean new_room = FALSE;
- room = g_list_nth_data(pkt->data, 0);
- topic = g_list_nth_data(pkt->data, 1);
- if (!g_list_nth_data(pkt->data, 4))
- members = g_strsplit(g_list_nth_data(pkt->data, 4), "\001", 0);
- for (i = 0; members[i]; i++) {
- char *tmp = strchr(members[i], '\002');
- if (g_list_length(pkt->data) > 5)
- if (new_room && ycht->changing_rooms) {
- serv_got_chat_left(gc, YAHOO_CHAT_ID);
- ycht->changing_rooms = FALSE;
- c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
- purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
- for (i = 0; members[i]; i++) {
- /*if (!strcmp(members[i], purple_connection_get_display_name(ycht->gc)))
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL, PURPLE_CBFLAGS_NONE, TRUE);
- yahoo_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL);
-static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt)
- room = g_list_nth_data(pkt->data, 0);
- who = g_list_nth_data(pkt->data, 1);
- PurpleConversation *c = purple_find_chat(ycht->gc, YAHOO_CHAT_ID);
- if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room))
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
-static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt)
- char *who, *what, *msg;
- PurpleConnection *gc = ycht->gc;
- who = g_list_nth_data(pkt->data, 1);
- what = g_list_nth_data(pkt->data, 2);
- c = purple_find_chat(gc, YAHOO_CHAT_ID);
- msg = yahoo_string_decode(gc, what, 1);
- what = yahoo_codes_to_html(msg);
- if (pkt->service == YCHT_SERVICE_CHATMSG_EMOTE) {
- char *tmp = g_strdup_printf("/me %s", what);
- serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, what, time(NULL));
-static void ycht_progress_online_friends(YchtConn *ycht, YchtPkt *pkt)
- PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
- yd->chat_online = TRUE;
- ycht->logged_in = TRUE;
- ycht_chat_join(ycht, ycht->room);
-/*****************************************************************************
- * Functions dealing with YCHT packets and their contents directly.
- *****************************************************************************/
-static void ycht_packet_dump(const guchar *data, int len)
- purple_debug_misc("yahoo", "");
- for (i = 0; i + 1 < len; i += 2) {
- if ((i % 16 == 0) && i) {
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- purple_debug_misc(NULL, "%02hhx%02hhx ", data[i], data[i + 1]);
- purple_debug_misc(NULL, "%02hhx", data[i]);
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- for (i = 0; i < len; i++) {
- if ((i % 16 == 0) && i) {
- purple_debug_misc(NULL, "\n");
- purple_debug_misc("yahoo", "");
- if (g_ascii_isprint(data[i]))
- purple_debug_misc(NULL, "%c ", data[i]);
- purple_debug_misc(NULL, ". ");
- purple_debug_misc(NULL, "\n");
-#endif /* YAHOO_YCHT_DEBUG */
-static YchtPkt *ycht_packet_new(guint version, guint service, int status)
- ret = g_new0(YchtPkt, 1);
- ret->version = version;
- ret->service = service;
-static void ycht_packet_append(YchtPkt *pkt, const char *str)
- g_return_if_fail(pkt != NULL);
- g_return_if_fail(str != NULL);
- pkt->data = g_list_append(pkt->data, g_strdup(str));
-static int ycht_packet_length(YchtPkt *pkt)
- for (l = pkt->data; l; l = l->next) {
- ret += strlen(l->data);
- ret += strlen(YCHT_SEP);
-static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCondition cond)
- writelen = purple_circ_buffer_get_max_read(ycht->txbuf);
- purple_input_remove(ycht->tx_handler);
- ret = write(ycht->fd, ycht->txbuf->outptr, writelen);
- if (ret < 0 && errno == EAGAIN)
- /* TODO: error handling */
- gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
- purple_connection_error_reason(purple_account_get_connection(irc->account),
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- purple_circ_buffer_mark_read(ycht->txbuf, ret);
-static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt)
- g_return_if_fail(ycht != NULL);
- g_return_if_fail(pkt != NULL);
- g_return_if_fail(ycht->fd != -1);
- len = ycht_packet_length(pkt);
- memcpy(buf + pos, "YCHT", 4); pos += 4;
- pos += yahoo_put32(buf + pos, pkt->version);
- pos += yahoo_put32(buf + pos, pkt->service);
- pos += yahoo_put16(buf + pos, pkt->status);
- pos += yahoo_put16(buf + pos, len - YCHT_HEADER_LEN);
- for (l = pkt->data; l; l = l->next) {
- int slen = strlen(l->data);
- memcpy(buf + pos, l->data, slen); pos += slen;
- memcpy(buf + pos, YCHT_SEP, strlen(YCHT_SEP));
- pos += strlen(YCHT_SEP);
- written = write(ycht->fd, buf, len);
- if (written < 0 && errno == EAGAIN)
- else if (written <= 0) {
- /* TODO: Error handling (was none before NBIO changes) */
- ycht->tx_handler = purple_input_add(ycht->fd,
- PURPLE_INPUT_WRITE, ycht_packet_send_write_cb,
- purple_circ_buffer_append(ycht->txbuf, buf + written,
-static void ycht_packet_read(YchtPkt *pkt, const char *buf, int len)
- while (len > 0 && (needle = g_strstr_len(pos, len, YCHT_SEP))) {
- tmp = g_strndup(pos, needle - pos);
- pkt->data = g_list_append(pkt->data, tmp);
- len -= needle - pos + strlen(YCHT_SEP);
- pos = needle + strlen(YCHT_SEP);
- tmp2 = g_strescape(tmp, NULL);
- purple_debug_misc("yahoo", "Data[%d]:\t%s\n", i++, tmp2);
- tmp = g_strndup(pos, len);
- pkt->data = g_list_append(pkt->data, tmp);
- tmp2 = g_strescape(tmp, NULL);
- purple_debug_misc("yahoo", "Data[%d]:\t%s\n", i, tmp2);
- purple_debug_misc("yahoo", "--==End of incoming YCHT packet==--\n");
-static void ycht_packet_process(YchtConn *ycht, YchtPkt *pkt)
- if (pkt->data && !strncmp(pkt->data->data, "*** Danger Will Robinson!!!", strlen("*** Danger Will Robinson!!!")))
- switch (pkt->service) {
- case YCHT_SERVICE_LOGIN:
- ycht_process_login(ycht, pkt);
- case YCHT_SERVICE_LOGOUT:
- ycht_process_logout(ycht, pkt);
- case YCHT_SERVICE_CHATJOIN:
- ycht_process_chatjoin(ycht, pkt);
- case YCHT_SERVICE_CHATPART:
- ycht_process_chatpart(ycht, pkt);
- case YCHT_SERVICE_CHATMSG:
- case YCHT_SERVICE_CHATMSG_EMOTE:
- ycht_progress_chatmsg(ycht, pkt);
- case YCHT_SERVICE_ONLINE_FRIENDS:
- ycht_progress_online_friends(ycht, pkt);
- purple_debug_warning("yahoo", "YCHT: warning, unhandled service 0x%02x\n", pkt->service);
-static void ycht_packet_free(YchtPkt *pkt)
- g_return_if_fail(pkt != NULL);
- for (l = pkt->data; l; l = l->next)
- g_list_free(pkt->data);
-/************************************************************************************
- * Functions dealing with connecting and disconnecting and reading data into YchtPkt
- * structs, and all that stuff.
- ************************************************************************************/
-void ycht_connection_close(YchtConn *ycht)
- YahooData *yd = ycht->gc->proto_data;
- yd->chat_online = FALSE;
- purple_input_remove(ycht->inpa);
- purple_input_remove(ycht->tx_handler);
- purple_circ_buffer_destroy(ycht->txbuf);
-static void ycht_connection_error(YchtConn *ycht, const gchar *error)
- purple_notify_info(ycht->gc, NULL, _("Connection problem with the YCHT server"), error);
- ycht_connection_close(ycht);
-static void ycht_pending(gpointer data, gint source, PurpleInputCondition cond)
- len = read(ycht->fd, buf, sizeof(buf));
- tmp = g_strdup_printf(_("Lost connection with server: %s"),
- ycht_connection_error(ycht, tmp);
- ycht_connection_error(ycht, _("Server closed the connection"));
- ycht->rxqueue = g_realloc(ycht->rxqueue, len + ycht->rxlen);
- memcpy(ycht->rxqueue + ycht->rxlen, buf, len);
- if (ycht->rxlen < YCHT_HEADER_LEN)
- if (strncmp("YCHT", (char *)ycht->rxqueue, 4) != 0)
- purple_debug_error("yahoo", "YCHT: protocol error.\n");
- version = yahoo_get32(ycht->rxqueue + pos); pos += 4;
- service = yahoo_get32(ycht->rxqueue + pos); pos += 4;
- status = yahoo_get16(ycht->rxqueue + pos); pos += 2;
- pktlen = yahoo_get16(ycht->rxqueue + pos); pos += 2;
- purple_debug_misc("yahoo", "ycht: %d bytes to read, rxlen is %d\n",
- if (ycht->rxlen < (YCHT_HEADER_LEN + pktlen))
- purple_debug_misc("yahoo", "--==Incoming YCHT packet==--\n");
- purple_debug_misc("yahoo", "YCHT Service: 0x%02x Version: 0x%02x Status: 0x%02x\n",
- service, version, status);
- ycht_packet_dump(ycht->rxqueue, YCHT_HEADER_LEN + pktlen);
- pkt = ycht_packet_new(version, service, status);
- ycht_packet_read(pkt, (char *)ycht->rxqueue + pos, pktlen);
- ycht->rxlen -= YCHT_HEADER_LEN + pktlen;
- guchar *tmp = g_memdup(ycht->rxqueue + YCHT_HEADER_LEN + pktlen, ycht->rxlen);
- ycht_packet_process(ycht, pkt);
-static void ycht_got_connected(gpointer data, gint source, const gchar *error_message)
- PurpleConnection *gc = ycht->gc;
- YahooData *yd = gc->proto_data;
- ycht_connection_error(ycht, _("Unable to connect"));
- pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_LOGIN, 0);
- buf = g_strdup_printf("%s\001Y=%s; T=%s", purple_connection_get_display_name(gc), yd->cookie_y, yd->cookie_t);
- ycht_packet_append(pkt, buf);
- ycht_packet_send(ycht, pkt);
- ycht->inpa = purple_input_add(ycht->fd, PURPLE_INPUT_READ, ycht_pending, ycht);
-void ycht_connection_open(PurpleConnection *gc)
- YahooData *yd = gc->proto_data;
- PurpleAccount *account = purple_connection_get_account(gc);
- ycht = g_new0(YchtConn, 1);
- if (purple_proxy_connect(gc, account,
- purple_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST),
- purple_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT),
- ycht_got_connected, ycht) == NULL)
- ycht_connection_error(ycht, _("Unable to connect"));
-/*******************************************************************************************
- * These are functions called because the user did something.
- *******************************************************************************************/
-void ycht_chat_join(YchtConn *ycht, const char *room)
- ycht->changing_rooms = TRUE;
- pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATJOIN, 0);
- ycht_packet_append(pkt, ycht->room);
- ycht_packet_send(ycht, pkt);
-int ycht_chat_send(YchtConn *ycht, const char *room, const char *what)
- char *msg1, *msg2, *buf;
- if (strcmp(room, ycht->room))
- purple_debug_warning("yahoo", "uhoh, sending to the wrong room!\n");
- pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_CHATMSG, 0);
- msg1 = yahoo_html_to_codes(what);
- msg2 = yahoo_string_encode(ycht->gc, msg1, NULL);
- buf = g_strdup_printf("%s\001%s", ycht->room, msg2);
- ycht_packet_append(pkt, buf);
- ycht_packet_send(ycht, pkt);
-void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout)
- ycht_connection_close(ycht);
-void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg)
-void ycht_chat_goto_user(YchtConn *ycht, const char *name)
-void ycht_chat_send_keepalive(YchtConn *ycht)
- pkt = ycht_packet_new(YCHT_VERSION, YCHT_SERVICE_PING, 0);
- ycht_packet_send(ycht, pkt);
--- a/libpurple/protocols/yahoo/ycht.h Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
- * @file ycht.h The Yahoo! protocol plugin, YCHT protocol stuff.
- * Copyright (C) 2004 Timothy Ringenbach <omarvo@hotmail.com>
- * 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
- * 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
-/* #define YAHOO_YCHT_DEBUG */
-#define YAHOO_YCHT_HOST "jcs3.chat.dcn.yahoo.com"
-#define YAHOO_YCHT_PORT 8002
-#define YCHT_VERSION (0xae)
-#define YCHT_HEADER_LEN (0x10)
- YCHT_SERVICE_LOGIN = 0x01,
- YCHT_SERVICE_LOGOUT = 0x02,
- YCHT_SERVICE_CHATJOIN = 0x11,
- YCHT_SERVICE_CHATPART = 0x12,
- YCHT_SERVICE_CHATMSG = 0x41,
- YCHT_SERVICE_CHATMSG_EMOTE = 0x43,
- YCHT_SERVICE_PING = 0x62,
- YCHT_SERVICE_ONLINE_FRIENDS = 0x68
-yahoo: YCHT Service: 0x11 Version: 0x100
-yahoo: Data[0]: Linux, FreeBSD, Solaris:1
-yahoo: Data[1]: Questions, problems and discussions about all flavors of Unix.
-yahoo: Data[4]: sgooki888\0020\002 \0022769036\00258936\002
-yahoo: --==End of incoming YCHT packet==--
-yahoo: --==Incoming YCHT packet==--
-yahoo: YCHT Service: 0x12 Version: 0x100
-yahoo: Data[0]: Linux, FreeBSD, Solaris:1
-yahoo: Data[1]: cccc4cccc
-yahoo: --==End of incoming YCHT packet==--
-#define YCHT_SEP "\xc0\x80"
-typedef struct _YchtConn {
- gboolean changing_rooms;
- PurpleCircBuffer *txbuf;
-void ycht_connection_open(PurpleConnection *gc);
-void ycht_connection_close(YchtConn *ycht);
-void ycht_chat_join(YchtConn *ycht, const char *room);
-int ycht_chat_send(YchtConn *ycht, const char *room, const char *what);
-void ycht_chat_leave(YchtConn *ycht, const char *room, gboolean logout);
-void ycht_chat_send_invite(YchtConn *ycht, const char *room, const char *buddy, const char *msg);
-void ycht_chat_goto_user(YchtConn *ycht, const char *name);
-void ycht_chat_send_keepalive(YchtConn *ycht);
-#endif /* _PURPLE_YCHT_H_ */
--- a/libpurple/prpl.h Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/prpl.h Wed Oct 05 15:10:29 2016 -0500
@@ -162,7 +162,7 @@
- * Yahoo notifies you when you have new mail.
+ * If a protocol notifies you when you have new mail. OPT_PROTO_MAIL_CHECK = 0x00000020,
@@ -921,8 +921,8 @@
* @param gc The connection to send the message on.
* @param who Whose attention to request.
* @param type_code An index into the prpl's attention_types list determining the type
- * of the attention request command to send. 0 if prpl only defines one
- * (for example, Yahoo), but protocols are allowed to define more.
+ * of the attention request command to send. 0 if prpl only defines one, + * but protocols are allowed to define more. * Note that you can't send arbitrary PurpleAttentionType's, because there is
* only a fixed set of attention commands.
--- a/libpurple/purple-url-handler Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/purple-url-handler Wed Oct 05 15:10:29 2016 -0500
@@ -300,31 +300,6 @@
# XXX V&V prompt to establish call
- protocol = "prpl-yahoo"
- match = re.match(r"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri)
- print("Invalid ymsgr URI: %s" % uri)
- command = unquote_plus(match.group(1))
- screenname = unquote_plus(match.group(3))
- paramstring = match.group(5)
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = unquote_plus(value)
- account = findaccount(protocol)
- if command.lower() == "sendim":
- goim(account, screenname, params.get("m"))
- elif command.lower() == "chat":
- gochat(account, {"room": screenname})
- elif command.lower() == "addfriend":
- addbuddy(account, screenname)
if len(argv) != 2 or argv[1] == "--help" or argv[1] == "-h":
@@ -354,8 +329,6 @@
print("Unknown protocol: %s" % type)
except dbus.DBusException as e:
--- a/libpurple/server.h Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/server.h Wed Oct 05 15:10:29 2016 -0500
@@ -68,8 +68,8 @@
* @param gc The connection to send the message on.
* @param who Whose attention to request.
* @param type_code An index into the prpl's attention_types list determining the type
- * of the attention request command to send. 0 if prpl only defines one
- * (for example, Yahoo), but protocols are allowed to define more.
+ * of the attention request command to send. 0 if prpl only defines one, + * but protocols are allowed to define more. * Note that you can't send arbitrary PurpleAttentionType's, because there is
* only a fixed set of attention commands.
--- a/libpurple/tests/Makefile.am Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/tests/Makefile.am Wed Oct 05 15:10:29 2016 -0500
@@ -15,7 +15,6 @@
$(top_builddir)/libpurple/util.h
@@ -32,7 +31,6 @@
$(top_builddir)/libpurple/protocols/jabber/libjabber.la \
$(top_builddir)/libpurple/protocols/oscar/liboscar.la \
- $(top_builddir)/libpurple/protocols/yahoo/libymsg.la \
$(top_builddir)/libpurple/libpurple.la \
--- a/libpurple/tests/check_libpurple.c Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/tests/check_libpurple.c Wed Oct 05 15:10:29 2016 -0500
@@ -92,7 +92,6 @@
srunner_add_suite(sr, jabber_jutil_suite());
srunner_add_suite(sr, jabber_scram_suite());
srunner_add_suite(sr, oscar_util_suite());
- srunner_add_suite(sr, yahoo_util_suite());
srunner_add_suite(sr, util_suite());
srunner_add_suite(sr, xmlnode_suite());
--- a/libpurple/tests/test_yahoo_util.c Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,214 +0,0 @@
-#include "../protocols/yahoo/libymsg.h"
-static void setup_codes_to_html(void)
-static void teardown_codes_to_html(void)
-START_TEST(test_codes_to_html)
- assert_string_equal_free("",
- yahoo_codes_to_html(""));
- assert_string_equal_free("",
- yahoo_codes_to_html("\x1B[12345m"));
- assert_string_equal_free("plain",
- yahoo_codes_to_html("plain"));
- assert_string_equal_free("unknown ansi code",
- yahoo_codes_to_html("unknown \x1B[12345m ansi code"));
- assert_string_equal_free("plain <peanut>",
- yahoo_codes_to_html("plain <peanut>"));
- assert_string_equal_free("plain <peanut",
- yahoo_codes_to_html("plain <peanut"));
- assert_string_equal_free("plain> peanut",
- yahoo_codes_to_html("plain> peanut"));
- assert_string_equal_free("<font face='inva>lid'>test</font>",
- yahoo_codes_to_html("<font face='inva>lid'>test"));
- assert_string_equal_free("<font face='inva>lid",
- yahoo_codes_to_html("<font face='inva>lid"));
- /* bold/italic/underline */
- assert_string_equal_free("<b>bold</b>",
- yahoo_codes_to_html("\x1B[1mbold"));
- assert_string_equal_free("<i>italic</i>",
- yahoo_codes_to_html("\x1B[2mitalic"));
- assert_string_equal_free("<u>underline</u>",
- yahoo_codes_to_html("\x1B[4munderline"));
- assert_string_equal_free("no markup",
- yahoo_codes_to_html("no\x1B[x4m markup"));
- assert_string_equal_free("<b>bold</b> <i>italic</i> <u>underline</u>",
- yahoo_codes_to_html("\x1B[1mbold\x1B[x1m \x1B[2mitalic\x1B[x2m \x1B[4munderline"));
- assert_string_equal_free("<b>bold <i>bolditalic</i></b><i> italic</i>",
- yahoo_codes_to_html("\x1B[1mbold \x1B[2mbolditalic\x1B[x1m italic"));
- assert_string_equal_free("<b>bold <i>bolditalic</i></b><i> <u>italicunderline</u></i>",
- yahoo_codes_to_html("\x1B[1mbold \x1B[2mbolditalic\x1B[x1m \x1B[4mitalicunderline"));
- assert_string_equal_free("<b>bold <i>bolditalic <u>bolditalicunderline</u></i><u> boldunderline</u></b>",
- yahoo_codes_to_html("\x1B[1mbold \x1B[2mbolditalic \x1B[4mbolditalicunderline\x1B[x2m boldunderline"));
- assert_string_equal_free("<b>bold <i>bolditalic <u>bolditalicunderline</u></i></b><i><u> italicunderline</u></i>",
- yahoo_codes_to_html("\x1B[1mbold \x1B[2mbolditalic \x1B[4mbolditalicunderline\x1B[x1m italicunderline"));
- assert_string_equal_free("http://pidgin.im/",
- yahoo_codes_to_html("\x1B[lmhttp://pidgin.im/\x1B[xlm"));
-#ifdef USE_CSS_FORMATTING
- assert_string_equal_free("<span style='color: #0000FF'>blue</span>",
- yahoo_codes_to_html("\x1B[31mblue"));
- assert_string_equal_free("<span style='color: #70ea15'>custom color</span>",
- yahoo_codes_to_html("\x1B[#70ea15mcustom color"));
- assert_string_equal_free("<font face='Georgia'>test</font>",
- yahoo_codes_to_html("<font face='Georgia'>test</font>"));
- assert_string_equal_free("<font><span style='font-size: 15pt'>test</span></font>",
- yahoo_codes_to_html("<font size='15'>test"));
- assert_string_equal_free("<font><span style='font-size: 32pt'>size 32</span></font>",
- yahoo_codes_to_html("<font size='32'>size 32"));
- assert_string_equal_free("<font face='Georgia'><span style='font-size: 32pt'>test</span></font>",
- yahoo_codes_to_html("<font face='Georgia' size='32'>test"));
- assert_string_equal_free("<span style='color: #FF0080'><font><span style='font-size: 15pt'>test</span></font></span>",
- yahoo_codes_to_html("\x1B[35m<font size='15'>test"));
- assert_string_equal_free("<font color='#0000FF'>blue</font>",
- yahoo_codes_to_html("\x1B[31mblue"));
- assert_string_equal_free("<font color='#70ea15'>custom color</font>",
- yahoo_codes_to_html("\x1B[#70ea15mcustom color"));
- assert_string_equal_free("test",
- yahoo_codes_to_html("<ALT #ff0000,#00ff00,#0000ff>test</ALT>"));
- assert_string_equal_free("<font face='Georgia'>test</font>",
- yahoo_codes_to_html("<font face='Georgia'>test"));
- assert_string_equal_free("<font size='4' absz='15'>test</font>",
- yahoo_codes_to_html("<font size='15'>test"));
- assert_string_equal_free("<font size='6' absz='32'>size 32</font>",
- yahoo_codes_to_html("<font size='32'>size 32"));
- assert_string_equal_free("<font face='Georgia' size='6' absz='32'>test</font>",
- yahoo_codes_to_html("<font face='Georgia' size='32'>test"));
- assert_string_equal_free("<font color='#FF0080'><font size='4' absz='15'>test</font></font>",
- yahoo_codes_to_html("\x1B[35m<font size='15'>test"));
- assert_string_equal_free(":<",
- yahoo_codes_to_html("<FADE #ff0000,#00ff00,#0000ff>:<</FADE>"));
-#endif /* !USE_CSS_FORMATTING */
-START_TEST(test_html_to_codes)
- assert_string_equal_free("plain",
- yahoo_html_to_codes("plain"));
- assert_string_equal_free("plain <peanut>",
- yahoo_html_to_codes("plain <peanut>"));
- assert_string_equal_free("plain <peanut",
- yahoo_html_to_codes("plain <peanut"));
- assert_string_equal_free("plain> peanut",
- yahoo_html_to_codes("plain> peanut"));
- assert_string_equal_free("plain >",
- yahoo_html_to_codes("plain >"));
- assert_string_equal_free("plain > ",
- yahoo_html_to_codes("plain > "));
- assert_string_equal_free("plain <",
- yahoo_html_to_codes("plain <"));
- assert_string_equal_free("plain < ",
- yahoo_html_to_codes("plain < "));
- assert_string_equal_free("plain <",
- yahoo_html_to_codes("plain <"));
- assert_string_equal_free("plain &",
- yahoo_html_to_codes("plain &"));
- /* bold/italic/underline */
- assert_string_equal_free("\x1B[1mbold\x1B[x1m",
- yahoo_html_to_codes("<b>bold</b>"));
- assert_string_equal_free("\x1B[2mitalic\x1B[x2m",
- yahoo_html_to_codes("<i>italic</i>"));
- assert_string_equal_free("\x1B[4munderline\x1B[x4m",
- yahoo_html_to_codes("<u>underline</u>"));
- assert_string_equal_free("no markup",
- yahoo_html_to_codes("no</u> markup"));
- assert_string_equal_free("\x1B[1mbold\x1B[x1m \x1B[2mitalic\x1B[x2m \x1B[4munderline\x1B[x4m",
- yahoo_html_to_codes("<b>bold</b> <i>italic</i> <u>underline</u>"));
- assert_string_equal_free("\x1B[1mbold \x1B[2mbolditalic\x1B[x2m\x1B[x1m\x1B[2m italic\x1B[x2m",
- yahoo_html_to_codes("<b>bold <i>bolditalic</i></b><i> italic</i>"));
- assert_string_equal_free("\x1B[1mbold \x1B[2mbolditalic\x1B[x2m\x1B[x1m\x1B[2m \x1B[4mitalicunderline\x1B[x4m\x1B[x2m",
- yahoo_html_to_codes("<b>bold <i>bolditalic</i></b><i> <u>italicunderline</u></i>"));
- assert_string_equal_free("http://pidgin.im/",
- yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">http://pidgin.im/</A>"));
- assert_string_equal_free("mark@example.com",
- yahoo_html_to_codes("<A HREF=\"mailto:mark@example.com\">mark@example.com</A>"));
- assert_string_equal_free("Pidgin (http://pidgin.im/)",
- yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">Pidgin</A>"));
- assert_string_equal_free("nothing",
- yahoo_html_to_codes("<font>nothing</font>"));
- assert_string_equal_free("\x1B[#E71414mred\x1B[#000000m",
- yahoo_html_to_codes("<font color=\"#E71414\">red</font>"));
- assert_string_equal_free("\x1B[#FF0000mred\x1B[#000000m \x1B[#0000FFmblue\x1B[#000000m black",
- yahoo_html_to_codes("<font color=\"#FF0000\">red</font> <font color=\"#0000FF\">blue</font> black"));
- assert_string_equal_free("<font size=\"10\">test</font>",
- yahoo_html_to_codes("<font size=\"2\">test</font>"));
- assert_string_equal_free("<font size=\"30\">test</font>",
- yahoo_html_to_codes("<font size=\"6\">test</font>"));
- assert_string_equal_free("\x1B[#FF0000m<font size=\"8\">redsmall</font> rednormal\x1B[#000000m",
- yahoo_html_to_codes("<font color=\"#FF0000\"><font size=\"1\">redsmall</font> rednormal</font>"));
- assert_string_equal_free("\x1B[#FF0000m<font size=\"8\">redsmall</font> \x1B[#00FF00mgreennormal\x1B[#FF0000m rednormal\x1B[#000000m",
- yahoo_html_to_codes("<font color=\"#FF0000\"><font size=\"1\">redsmall</font> <font color=\"#00FF00\">greennormal</font> rednormal</font>"));
- assert_string_equal_free("\x1B[1mbold \x1B[#FF0000mred <font face=\"Comic Sans MS\" size=\"20\">larger \x1B[#000000mbacktoblack <font size=\"12\">normalsize</font>\x1B[#FF0000m</font>\x1B[#000000m\x1B[x1m",
- yahoo_html_to_codes("<b>bold <font color=\"#FF0000\">red <font face=\"Comic Sans MS\" size=\"5\">larger <font color=\"#000000\">backtoblack <font size=\"3\">normalsize</font></font></font></font></b>"));
- /* buzz/unknown tags */
- assert_string_equal_free("<ding>",
- yahoo_html_to_codes("<ding>"));
- assert_string_equal_free("Unknown <tags>",
- yahoo_html_to_codes("Unknown <tags>"));
- s = suite_create("Yahoo Utility Functions");
- tc = tcase_create("Convert IM from network format to HTML");
- tcase_add_unchecked_fixture(tc, setup_codes_to_html, teardown_codes_to_html);
- tcase_add_test(tc, test_codes_to_html);
- suite_add_tcase(s, tc);
- tc = tcase_create("Convert IM from HTML to network format");
- tcase_add_test(tc, test_html_to_codes);
- suite_add_tcase(s, tc);
--- a/libpurple/tests/tests.h Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/tests/tests.h Wed Oct 05 15:10:29 2016 -0500
@@ -14,7 +14,6 @@
Suite * jabber_jutil_suite(void);
Suite * jabber_scram_suite(void);
Suite * oscar_util_suite(void);
-Suite * yahoo_util_suite(void);
Suite * util_suite(void);
Suite * xmlnode_suite(void);
--- a/libpurple/util.h Wed Oct 05 21:14:58 2016 +0200
+++ b/libpurple/util.h Wed Oct 05 15:10:29 2016 -0500
@@ -456,8 +456,8 @@
* Extracts a field of data from HTML.
- * This is a scary function. See protocols/yahoo/yahoo_profile.c
+ * This is a scary function. It used to be used for MSN and Yahoo prpls, + * but since those prpls have been removed, this is now deprecated. * @param str The string to parse.
* @param len The size of str.
--- a/pidgin.apspec.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin.apspec.in Wed Oct 05 15:10:29 2016 -0500
@@ -14,7 +14,7 @@
Pidgin allows you to talk to anyone using a variety of messaging protocols,
-including AIM (Oscar and TOC), ICQ, IRC, Yahoo!, XMPP,
+including AIM (Oscar and TOC), ICQ, IRC, XMPP, Gadu-Gadu, and Zephyr. These protocols are implemented using a
modular, easy to use design. To use a protocol, just add an account using the
@@ -23,7 +23,7 @@
features, such as perl scripting, TCL scripting and C plugins.
Pidgin is NOT affiliated with or endorsed by America Online, Inc., Microsoft
-Corporation, Yahoo! Inc., or ICQ Inc.
+Corporation, or ICQ Inc. APBUILD_STATIC="Xss startup-notification-1" prepareBuild --enable-nss --enable-gnutls --enable-binreloc --disable-perl --disable-tcl --disable-gtktest --disable-glibtest --disable-vv --disable-fortify
--- a/pidgin.spec.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin.spec.in Wed Oct 05 15:10:29 2016 -0500
@@ -161,7 +161,7 @@
Pidgin allows you to talk to anyone using a variety of messaging
-protocols including AIM, Yahoo!, XMPP, Bonjour, Gadu-Gadu,
+protocols including AIM, XMPP, Bonjour, Gadu-Gadu, ICQ, IRC, Novell Groupwise, QQ, Lotus Sametime, SILC, Simple and
Zephyr. These protocols are implemented using a modular, easy to
use design. To use a protocol, just add an account using the
@@ -171,7 +171,7 @@
unique features, such as perl scripting, TCL scripting and C plugins.
Pidgin is not affiliated with or endorsed by America Online, Inc.,
-Microsoft Corporation, Yahoo! Inc., or ICQ Inc.
+Microsoft Corporation, or ICQ Inc. The pidgin-devel package contains the header files, developer
@@ -183,7 +183,7 @@
libpurple supports a variety of messaging protocols including AIM,
-Yahoo!, XMPP, Bonjour, Gadu-Gadu, ICQ, IRC, Novell Groupwise, QQ,
+XMPP, Bonjour, Gadu-Gadu, ICQ, IRC, Novell Groupwise, QQ, Lotus Sametime, SILC, Simple and Zephyr.
%description -n libpurple-devel
--- a/pidgin/data/pidgin.appdata.xml.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/data/pidgin.appdata.xml.in Wed Oct 05 15:10:29 2016 -0500
@@ -14,7 +14,7 @@
This means that you can be chatting with friends on AIM, talking to a
- friend on Google Talk, and sitting in a Yahoo chat room all at the same
+ friend on Google Talk, and sitting in an IRC chat room all at the same --- a/pidgin/data/pidgin.desktop.in.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/data/pidgin.desktop.in.in Wed Oct 05 15:10:29 2016 -0500
@@ -1,7 +1,7 @@
_Name=Pidgin Internet Messenger
_GenericName=Internet Messenger
-_Comment=Chat over IM. Supports AIM, Google Talk, Jabber/XMPP, Yahoo and more
+_Comment=Chat over IM. Supports AIM, Google Talk, Jabber/XMPP, and more --- a/pidgin/gtkblist.c Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/gtkblist.c Wed Oct 05 15:10:29 2016 -0500
@@ -2130,7 +2130,6 @@
s = temp_vcard = g_strdup(vcard);
@@ -2170,7 +2169,6 @@
if (!strcmp(field, "FN"))
else if (!strcmp(field, "X-AIM") || !strcmp(field, "X-ICQ") ||
- !strcmp(field, "X-YAHOO") ||
!strcmp(field, "X-JABBER"))
char **values = g_strsplit(value, ":", 0);
@@ -2182,8 +2180,6 @@
aims = g_list_append(aims, g_strdup(*im));
else if (!strcmp(field, "X-ICQ"))
icqs = g_list_append(icqs, g_strdup(*im));
- else if (!strcmp(field, "X-YAHOO"))
- yahoos = g_list_append(yahoos, g_strdup(*im));
else if (!strcmp(field, "X-JABBER"))
jabbers = g_list_append(jabbers, g_strdup(*im));
@@ -2194,7 +2190,7 @@
- if (aims == NULL && icqs == NULL && yahoos == NULL && jabbers == NULL)
+ if (aims == NULL && icqs == NULL && jabbers == NULL) @@ -2203,7 +2199,6 @@
add_buddies_from_vcard("prpl-aim", group, aims, alias);
add_buddies_from_vcard("prpl-icq", group, icqs, alias);
- add_buddies_from_vcard("prpl-yahoo", group, yahoos, alias);
add_buddies_from_vcard("prpl-jabber", group, jabbers, alias);
--- a/pidgin/gtkwhiteboard.h Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/gtkwhiteboard.h Wed Oct 05 15:10:29 2016 -0500
@@ -37,8 +37,6 @@
#define BRUSH_STATE_DOWN 1
#define BRUSH_STATE_MOTION 2
-/* XXX: This seems duplicated with the Yahoo! Doodle prpl code.
- * XXX: How should they work together? */
#define PALETTE_NUM_COLORS 7
--- a/pidgin/pixmaps/Makefile.am Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/pixmaps/Makefile.am Wed Oct 05 15:10:29 2016 -0500
@@ -211,7 +211,6 @@
protocols/16/scalable/meanwhile.svg \
protocols/16/scalable/silc.svg \
protocols/16/scalable/simple.svg \
- protocols/16/scalable/yahoo.svg \
protocols/16/scalable/zephyr.svg
@@ -227,7 +226,6 @@
protocols/16/meanwhile.png \
protocols/16/simple.png \
- protocols/16/yahoo.png \
@@ -262,7 +260,6 @@
protocols/22/scalable/meanwhile.svg \
protocols/22/scalable/silc.svg \
protocols/22/scalable/simple.svg \
- protocols/22/scalable/yahoo.svg \
protocols/22/scalable/zephyr.svg
@@ -278,7 +275,6 @@
protocols/22/meanwhile.png \
protocols/22/simple.png \
- protocols/22/yahoo.png \
@@ -293,7 +289,6 @@
protocols/48/meanwhile.png \
protocols/48/simple.png \
- protocols/48/yahoo.png \
@@ -308,7 +303,6 @@
protocols/scalable/meanwhile.svg \
protocols/scalable/silc.svg \
protocols/scalable/simple.svg \
- protocols/scalable/yahoo.svg \
protocols/scalable/zephyr.svg
--- a/pidgin/pixmaps/emotes/default/24/default.theme.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/pixmaps/emotes/default/24/default.theme.in Wed Oct 05 15:10:29 2016 -0500
@@ -237,191 +237,6 @@
-# Following Yahoo! Messenger 8.1
-shocked.png :-O :O :-o :o
-angel.png O:-) o:-) 0:-)
-amorous.png :x :-x :X :-X
-glasses-nerdy.png :-B :-b
-excited.png :D :-D :d :-d
-tongue.png :-P :P :-p :p
-glasses-cool.png B-) b-)
-sleeping.png I-) i-) |-)
-nervous.png :-SS :-Ss :-sS :-ss
-! skywalker.png C:-) c:-) C:) c:)
-! monkey.png :-(|) :(|) 8-|)
-# Only available after activating the Yahoo! Fighter IMVironment
-male-fighter1.png o-> O->
-male-fighter2.png o=> O=>
-female-fighter.png o-+ O-+
-# Following Yahoo! Messenger 8.1
-shocked.png :-O :O :-o :o
-angel.png O:-) o:-) 0:-)
-amorous.png :x :-x :X :-X
-glasses-nerdy.png :-B :-b
-excited.png :D :-D :d :-d
-tongue.png :-P :P :-p :p
-glasses-cool.png B-) b-)
-sleeping.png I-) i-) |-)
-nervous.png :-SS :-Ss :-sS :-ss
-! skywalker.png C:-) c:-) C:) c:)
-# Only available after activating the Yahoo! Fighter IMVironment
-male-fighter1.png o-> O->
-male-fighter2.png o=> O=>
-female-fighter.png o-+ O-+
# MXit standard emoticons
--- a/pidgin/pixmaps/emotes/small/16/small.theme.in Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/pixmaps/emotes/small/16/small.theme.in Wed Oct 05 15:10:29 2016 -0500
@@ -135,84 +135,6 @@
-# Following Yahoo! Messenger 8.1
-shocked.png :-O :O :-o :o
-angel.png O:-) o:-) 0:-)
-amorous.png :x :-x :X :-X
-excited.png :D :-D :d :-d
-tongue.png :-P :P :-p :p
-glasses-cool.png B-) b-)
-sleeping.png I-) i-) |-)
-nervous.png :-SS :-Ss :-sS :-ss
-# Following Yahoo! Messenger 8.1
-shocked.png :-O :O :-o :o
-angel.png O:-) o:-) 0:-)
-amorous.png :x :-x :X :-X
-excited.png :D :-D :d :-d
-tongue.png :-P :P :-p :p
-glasses-cool.png B-) b-)
-sleeping.png I-) i-) |-)
# MXit standard emoticons
--- a/pidgin/pixmaps/protocols/16/scalable/yahoo.svg Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- sodipodi:version="0.32"
- inkscape:version="0.46"
- sodipodi:docbase="/home/hbons/GUI/Tango/Gaim Refresh/protocols/16/scalable"
- sodipodi:docname="yahoo.svg"
- inkscape:export-filename="/home/hbons/Bureaublad/yahoo.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:output_extension="org.inkscape.output.svg.inkscape">
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 8 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="16 : 8 : 1"
- inkscape:persp3d-origin="8 : 5.3333333 : 1"
- id="linearGradient4123"
- inkscape:collect="always">
- style="stop-color:#ff0000;stop-opacity:1;" />
- style="stop-color:#ff0000;stop-opacity:0;" />
- inkscape:collect="always"
- xlink:href="#linearGradient4123"
- id="linearGradient6737"
- gradientUnits="userSpaceOnUse"
- inkscape:collect="always"
- xlink:href="#linearGradient4123"
- id="linearGradient6739"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.676847,0,0,0.662872,0.3362294,0.7829564)" />
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="36.060436"
- inkscape:cx="15.360711"
- inkscape:cy="8.3801083"
- inkscape:current-layer="layer1"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1440"
- inkscape:window-height="847"
- inkscape:grid-points="false"
- inkscape:guide-points="false"
- inkscape:object-points="false"
- inkscape:object-nodes="false"
- inkscape:snap-bbox="true"
- inkscape:snap-nodes="false">
- <dc:format>image/svg+xml</dc:format>
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- inkscape:label="Layer 1"
- inkscape:groupmode="layer">
- style="fill:white;fill-opacity:1;stroke:none;stroke-width:1.49293232;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 0.24196135,4.148819 L 0.24910211,7.1529832 L 3.5563617,7.147764 L 7.6406917,12.763032 L 7.642012,14.664616 L 4.6774169,14.67713 L 4.6586789,17.695272 L 13.533193,17.684579 L 13.569765,14.669366 L 10.619662,14.679398 L 10.629019,12.755768 L 14.593143,8.6330885 L 16.51876,8.6465912 L 16.509766,5.6235735 L 12.050243,5.6188666 L 12.072495,7.7727612 L 10.847264,10.121315 L 8.9433829,10.071394 L 7.9521191,7.1118568 L 9.0229281,7.1259776 L 9.0246268,4.0988967 L 0.24196135,4.148819 z "
- sodipodi:nodetypes="cccccccccccccccccccccc"
- transform="matrix(0.676847,0,0,0.662872,0.331396,0.782369)" />
- style="opacity:0;fill:none;fill-opacity:1;stroke:#a40000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- transform="translate(-1.463597e-2,-4.995136)" />
- style="fill:url(#linearGradient6739);fill-opacity:1;stroke:#a40000;stroke-width:1.00000047999999997;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 6.5 3.5 L 0.5 3.53125 L 0.5 5.53125 L 2.75 5.53125 L 5.5 9.25 L 5.5 10.5 L 4.28125 10.5 C 3.3577546 10.5 3.5 11.5 3.5 11.5 L 3.5 12.5 L 6.5 12.5 L 9.5 12.5 L 9.5 11.21875 C 9.4999997 11.21875 9.4638896 10.5 8.71875 10.5 L 7.53125 10.5 L 7.53125 9.6875 L 10.21875 6.5 L 11.53125 6.5 L 11.5 4.5 L 8.5 4.5 L 8.5 5.8125 L 7.09375 7.5 L 6.65625 7.5 L 5.1875 5.5 L 6.5 5.5 L 6.5 3.5 z M 13.5 3.5 L 13.53125 9.9375 L 15.71875 3.5 L 13.5 3.5 z M 12.5 10.5 C 11.948 10.5 11.5 10.948002 11.5 11.5 C 11.5 12.051998 11.948 12.5 12.5 12.5 C 13.052 12.5 13.5 12.051998 13.5 11.5 C 13.5 10.948002 13.052001 10.5 12.5 10.5 z "
- style="fill:white;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- transform="matrix(0.672571,0,0,0.662714,0.148779,0.239809)" />
Binary file pidgin/pixmaps/protocols/16/yahoo.png has changed
--- a/pidgin/pixmaps/protocols/22/scalable/yahoo.svg Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- sodipodi:version="0.32"
- inkscape:version="0.46"
- sodipodi:docbase="/home/hbons/GUI/Tango/Gaim Refresh/protocols/22/scalable"
- sodipodi:docname="yahoo.svg"
- inkscape:export-filename="/home/hbons/GUI/Tango/Gaim Refresh/protocols/22/yahoo.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:output_extension="org.inkscape.output.svg.inkscape">
- inkscape:collect="always"
- id="linearGradient3150">
- style="stop-color:#2e3436;stop-opacity:1;"
- style="stop-color:#2e3436;stop-opacity:0;"
- inkscape:collect="always"
- xlink:href="#linearGradient3150"
- id="radialGradient3156"
- gradientTransform="matrix(-0.842757,5.698892e-16,-4.565819e-9,-0.35721,19.80716,14.19321)"
- gradientUnits="userSpaceOnUse" />
- inkscape:collect="always"
- id="linearGradient4123">
- style="stop-color:#ff0000;stop-opacity:1;"
- style="stop-color:#ff0000;stop-opacity:0;"
- inkscape:collect="always"
- xlink:href="#linearGradient4123"
- id="linearGradient4129"
- gradientUnits="userSpaceOnUse" />
- inkscape:collect="always"
- xlink:href="#linearGradient4123"
- id="linearGradient4131"
- gradientUnits="userSpaceOnUse" />
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="29.290175"
- inkscape:cx="18.292625"
- inkscape:cy="12.739723"
- inkscape:current-layer="layer1"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:guide-bbox="true"
- inkscape:window-width="1268"
- inkscape:window-height="971"
- inkscape:window-y="25" />
- <dc:format>image/svg+xml</dc:format>
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- inkscape:label="Layer 1"
- inkscape:groupmode="layer">
- style="opacity:0;fill:none;fill-opacity:1;stroke:#a40000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- style="opacity:0.6;fill:url(#radialGradient3156);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- sodipodi:cx="10.748654"
- sodipodi:cy="10.457643"
- sodipodi:rx="6.6449099"
- sodipodi:ry="2.3675451"
- d="M 17.393564 10.457643 A 6.6449099 2.3675451 0 1 1 4.1037445,10.457643 A 6.6449099 2.3675451 0 1 1 17.393564 10.457643 z"
- transform="matrix(1.730648,0,0,1.300982,-7.102139,4.474929)" />
- style="opacity:1;fill:url(#linearGradient4131);fill-opacity:1.0;stroke:#a40000;stroke-width:0.99999958;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 0.49908419,5.4951356 L 0.49908419,7.5376225 L 3.3376273,7.5964463 L 8.515629,12.953307 L 8.515629,15.459996 L 5.4587364,15.459996 L 5.4587364,17.502482 L 13.56886,17.502482 L 13.56886,15.459996 L 10.463631,15.459996 L 10.463631,12.891414 L 14.972535,8.5279191 L 16.532174,8.5279191 L 16.532174,6.5473259 L 11.478943,6.5473259 L 11.478943,8.5279191 L 12.040413,8.5279191 L 9.8296564,10.446619 L 9.1979396,10.446619 L 5.9890137,7.5376225 L 9.5449908,7.5376225 L 9.5449908,5.4951356 L 0.49908419,5.4951356 z "
- sodipodi:nodetypes="ccccccccccccccccccccccc" />
- style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.97808969;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- sodipodi:cx="16.860584"
- sodipodi:cy="16.429377"
- sodipodi:rx="1.3865612"
- sodipodi:ry="1.5252173"
- d="M 18.247145 16.429377 A 1.3865612 1.5252173 0 1 1 15.474023,16.429377 A 1.3865612 1.5252173 0 1 1 18.247145 16.429377 z"
- transform="matrix(1.06013,0,0,0.986015,-0.904476,0.796501)" />
- style="fill:url(#linearGradient4129);fill-opacity:1.0;stroke:#a40000;stroke-width:0.99999994;stroke-miterlimit:4;stroke-opacity:1"
- d="M 18.485372,6.4981503 L 22.514636,6.4981503 L 18.576821,12.500953 L 18.485372,6.4981503 z "
- sodipodi:nodetypes="cccc" />
Binary file pidgin/pixmaps/protocols/22/yahoo.png has changed
Binary file pidgin/pixmaps/protocols/48/yahoo.png has changed
--- a/pidgin/pixmaps/protocols/scalable/yahoo.svg Wed Oct 05 21:14:58 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- sodipodi:version="0.32"
- inkscape:version="0.46"
- sodipodi:docbase="/home/hbons/Desktop/Gaim Refresh/protocols/48"
- sodipodi:docname="yahoo.svg"
- inkscape:export-filename="/home/hbons/Desktop/Gaim Refresh/protocols/48/yahoo.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:output_extension="org.inkscape.output.svg.inkscape">
- inkscape:collect="always"
- id="linearGradient2211">
- style="stop-color:#ffffff;stop-opacity:1;"
- style="stop-color:#ffffff;stop-opacity:0;"
- inkscape:collect="always"
- id="linearGradient3150">
- style="stop-color:#2e3436;stop-opacity:1;"
- style="stop-color:#2e3436;stop-opacity:0;"
- inkscape:collect="always"
- xlink:href="#linearGradient3150"
- id="radialGradient3156"
- gradientTransform="matrix(-0.842757,5.698892e-16,-4.565819e-9,-0.35721,19.80716,14.19321)"
- gradientUnits="userSpaceOnUse" />
- inkscape:collect="always"
- id="linearGradient4123">
- style="stop-color:#ff0000;stop-opacity:1;"
- style="stop-color:#ff0000;stop-opacity:0;"
- inkscape:collect="always"
- xlink:href="#linearGradient4123"
- id="linearGradient2206"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.871443,0,0,1.871443,1.990827,1.339082)"
- inkscape:collect="always"
- xlink:href="#linearGradient2211"
- id="linearGradient2217"
- gradientUnits="userSpaceOnUse" />
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="11.098901"
- inkscape:cy="29.700698"
- inkscape:current-layer="layer1"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:guide-bbox="true"
- inkscape:window-width="1268"
- inkscape:window-height="971"
- inkscape:window-y="21" />
- <dc:format>image/svg+xml</dc:format>
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- inkscape:label="Layer 1"
- inkscape:groupmode="layer">
- style="opacity:0;fill:none;fill-opacity:1;stroke:#a40000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- style="opacity:0.6;fill:url(#radialGradient3156);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- sodipodi:cx="10.748654"
- sodipodi:cy="10.457643"
- sodipodi:rx="6.6449099"
- sodipodi:ry="2.3675451"
- d="M 17.393564 10.457643 A 6.6449099 2.3675451 0 1 1 4.1037445,10.457643 A 6.6449099 2.3675451 0 1 1 17.393564 10.457643 z"
- transform="matrix(3.163562,0,0,2.111892,-10.02562,12.91459)" />
- style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 36.593752,13.5 L 36.750002,24.71875 L 44.125002,13.5 L 36.593752,13.5 z M 33.406252,30.34375 C 32.052922,30.519922 31.000003,31.724054 31.000002,33.15625 C 31.000002,34.70982 32.231505,35.96875 33.750002,35.96875 C 35.268499,35.96875 36.500002,34.70982 36.500002,33.15625 C 36.500002,31.60268 35.268499,30.343751 33.750002,30.34375 C 33.631369,30.34375 33.520941,30.32882 33.406252,30.34375 z "
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.0402364"
- inkscape:original="M 36.59375 13.5 L 36.75 24.71875 L 44.125 13.5 L 36.59375 13.5 z M 33.40625 30.34375 C 32.052918 30.519922 31.000001 31.724054 31 33.15625 C 31 34.70982 32.231503 35.96875 33.75 35.96875 C 35.268495 35.96875 36.5 34.70982 36.5 33.15625 C 36.499998 31.60268 35.268497 30.343751 33.75 30.34375 C 33.631365 30.34375 33.520939 30.32882 33.40625 30.34375 z "
- style="opacity:0.35;fill:url(#linearGradient2217);fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- inkscape:href="#path4110"
- d="M 37.625,15.0625 L 37.71875,21.875 L 42.1875,15.0625 L 37.625,15.0625 z M 33.53125,31.90625 C 32.711111,32.013013 32.031251,32.765143 32.03125,33.6875 C 32.031249,34.691344 32.806451,35.46875 33.75,35.46875 C 34.693551,35.46875 35.46875,34.691346 35.46875,33.6875 C 35.468751,32.683656 34.69355,31.906251 33.75,31.90625 C 33.544091,31.90625 33.473148,31.913814 33.53125,31.90625 z " />
- style="opacity:1;fill:url(#linearGradient2206);fill-opacity:1;stroke:#a40000;stroke-width:0.99999976;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 2.6545432,11.532816 L 4.353345,15.445312 L 7.741467,15.555398 L 17.47685,25.310159 L 17.4318,31.506326 L 12.428056,31.384739 L 11.665952,34.499424 L 27.339128,34.54589 L 26.551973,31.519888 L 21.572919,31.603085 L 21.572919,25.191498 L 28.209096,17.523843 L 31.468823,17.433744 L 32.573193,13.532585 L 23.168883,13.473142 L 21.694773,17.410562 L 23.776066,17.4644 L 19.977012,20.889333 L 13.198929,15.445312 L 17.758833,15.445312 L 20.124034,11.577865 L 2.6545432,11.532816 z "
- sodipodi:nodetypes="cccccccccccccccccccccc" />
- sodipodi:type="inkscape:offset"
- inkscape:radius="-0.98856229"
- inkscape:original="M 2.65625 11.53125 L 4.34375 15.4375 L 7.75 15.5625 L 17.46875 25.3125 L 17.4375 31.5 L 12.4375 31.375 L 11.65625 34.5 L 27.34375 34.53125 L 26.5625 31.53125 L 21.5625 31.59375 L 21.5625 25.1875 L 28.21875 17.53125 L 31.46875 17.4375 L 32.5625 13.53125 L 23.15625 13.46875 L 21.6875 17.40625 L 23.78125 17.46875 L 19.96875 20.875 L 13.1875 15.4375 L 17.75 15.4375 L 20.125 11.5625 L 2.65625 11.53125 z "
- style="opacity:0.35;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.99999976;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- inkscape:href="#rect3219"
- d="M 4.15625,13.0625 L 5,15 L 7.78125,15.09375 C 8.0317447,15.110809 8.266366,15.222533 8.4375,15.40625 L 18.15625,25.15625 C 18.347286,25.335037 18.45966,25.58226 18.46875,25.84375 L 18.4375,32.03125 C 18.44087,32.30297 18.33225,32.564099 18.137167,32.75327 C 17.942084,32.942442 17.677738,33.042977 17.40625,33.03125 L 13.21875,32.9375 L 12.9375,34.03125 L 26.0625,34.0625 L 25.78125,33.0625 L 21.5625,33.125 C 21.296354,33.12807 21.040212,33.0237 20.852006,32.835494 C 20.6638,32.647288 20.55943,32.391146 20.5625,32.125 L 20.5625,25.71875 C 20.562717,25.476777 20.651667,25.243286 20.8125,25.0625 L 27.46875,17.40625 C 27.649517,17.19593 27.910308,17.071204 28.1875,17.0625 L 30.71875,17 L 31.28125,15.0625 L 23.84375,15 L 23.125,16.96875 L 23.8125,17 C 24.228223,17.002399 24.598033,17.264612 24.737859,17.656122 C 24.877684,18.047632 24.757648,18.48479 24.4375,18.75 L 20.625,22.15625 C 20.263408,22.479557 19.720674,22.492795 19.34375,22.1875 L 12.5625,16.75 C 12.215365,16.491727 12.076498,16.037735 12.219751,15.629463 C 12.363005,15.221191 12.755094,14.953499 13.1875,14.96875 L 17.1875,14.96875 L 18.34375,13.09375 L 4.15625,13.0625 z " />
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/plugins/gevolution/add_buddy_dialog.c Wed Oct 05 15:10:29 2016 -0500
@@ -288,18 +288,17 @@
EContact *contact = E_CONTACT(c->data);
- GList *aims, *jabbers, *yahoos, *icqs, *novells, *ggs;
+ GList *aims, *jabbers, *icqs, *novells, *ggs; name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
aims = e_contact_get(contact, E_CONTACT_IM_AIM);
jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
- yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
ggs = e_contact_get(contact, E_CONTACT_IM_GADUGADU);
- if (aims == NULL && jabbers == NULL && yahoos == NULL &&
+ if (aims == NULL && jabbers == NULL && icqs == NULL && novells == NULL && ggs == NULL)
@@ -315,7 +314,6 @@
add_ims(dialog, contact, name, aims, "prpl-aim");
add_ims(dialog, contact, name, jabbers, "prpl-jabber");
- add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
add_ims(dialog, contact, name, icqs, "prpl-icq");
add_ims(dialog, contact, name, novells, "prpl-novell");
add_ims(dialog, contact, name, ggs, "prpl-gg");
@@ -364,7 +362,7 @@
EContact *contact = E_CONTACT(l->data);
- GList *aims, *jabbers, *yahoos, *icqs, *novells, *ggs;
+ GList *aims, *jabbers, *icqs, *novells, *ggs; name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
@@ -376,12 +374,11 @@
aims = e_contact_get(contact, E_CONTACT_IM_AIM);
jabbers = e_contact_get(contact, E_CONTACT_IM_JABBER);
- yahoos = e_contact_get(contact, E_CONTACT_IM_YAHOO);
icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
ggs = e_contact_get(contact, E_CONTACT_IM_GADUGADU);
- if (aims == NULL && jabbers == NULL && yahoos == NULL &&
+ if (aims == NULL && jabbers == NULL && icqs == NULL && novells == NULL && ggs == NULL)
@@ -397,7 +394,6 @@
add_ims(dialog, contact, name, aims, "prpl-aim");
add_ims(dialog, contact, name, jabbers, "prpl-jabber");
- add_ims(dialog, contact, name, yahoos, "prpl-yahoo");
add_ims(dialog, contact, name, icqs, "prpl-icq");
add_ims(dialog, contact, name, novells, "prpl-novell");
add_ims(dialog, contact, name, ggs, "prpl-gg");
--- a/pidgin/plugins/gevolution/gevo-util.c Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/plugins/gevolution/gevo-util.c Wed Oct 05 15:10:29 2016 -0500
@@ -103,8 +103,6 @@
protocol_field = E_CONTACT_IM_AIM;
else if (!strcmp(protocol_id, "prpl-icq"))
protocol_field = E_CONTACT_IM_ICQ;
- else if (!strcmp(protocol_id, "prpl-yahoo"))
- protocol_field = E_CONTACT_IM_YAHOO;
else if (!strcmp(protocol_id, "prpl-jabber"))
protocol_field = E_CONTACT_IM_JABBER;
else if (!strcmp(protocol_id, "prpl-novell"))
@@ -163,18 +161,5 @@
- PurpleAccount *account = purple_buddy_get_account(buddy);
- const char *prpl_id = purple_account_get_protocol_id(account);
- if (!strcmp(prpl_id, "prpl-yahoo"))
- mail = g_strdup_printf("%s@yahoo.com",
- purple_normalize(account,
- purple_buddy_get_name(buddy)));
--- a/pidgin/plugins/gevolution/gevolution.c Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/plugins/gevolution/gevolution.c Wed Oct 05 15:10:29 2016 -0500
@@ -121,7 +121,6 @@
update_ims_from_contact(contact, name, "prpl-aim", E_CONTACT_IM_AIM);
update_ims_from_contact(contact, name, "prpl-jabber", E_CONTACT_IM_JABBER);
- update_ims_from_contact(contact, name, "prpl-yahoo", E_CONTACT_IM_YAHOO);
update_ims_from_contact(contact, name, "prpl-icq", E_CONTACT_IM_ICQ);
update_ims_from_contact(contact, name, "prpl-novell", E_CONTACT_IM_GROUPWISE);
update_ims_from_contact(contact, name, "prpl-gg", E_CONTACT_IM_GADUGADU);
--- a/pidgin/plugins/gevolution/new_person_dialog.c Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/plugins/gevolution/new_person_dialog.c Wed Oct 05 15:10:29 2016 -0500
@@ -145,8 +145,6 @@
field = E_CONTACT_IM_AIM;
else if (!strcmp(im_service, "prpl-icq"))
field = E_CONTACT_IM_ICQ;
- else if (!strcmp(im_service, "prpl-yahoo"))
- field = E_CONTACT_IM_YAHOO;
else if (!strcmp(im_service, "prpl-jabber"))
field = E_CONTACT_IM_JABBER;
else if (!strcmp(im_service, "prpl-novell"))
--- a/pidgin/win32/nsis/pidgin-installer.nsi Wed Oct 05 21:14:58 2016 +0200
+++ b/pidgin/win32/nsis/pidgin-installer.nsi Wed Oct 05 15:10:29 2016 -0500
@@ -388,7 +388,6 @@
SectionGroup /e $(URIHANDLERSSECTIONTITLE) SecURIHandlers
!insertmacro URI_SECTION "aim"
- !insertmacro URI_SECTION "ymsgr"
!insertmacro URI_SECTION "xmpp"
@@ -504,8 +503,6 @@
; I can't think of an easy way to maintain a list in a single place
Call un.UnregisterURIHandler
- Call un.UnregisterURIHandler
Call un.UnregisterURIHandler
@@ -564,8 +561,6 @@
Delete "$INSTDIR\plugins\libsilc.dll"
Delete "$INSTDIR\plugins\libsimple.dll"
Delete "$INSTDIR\plugins\libtoc.dll"
- Delete "$INSTDIR\plugins\libyahoo.dll"
- Delete "$INSTDIR\plugins\libyahoojp.dll"
Delete "$INSTDIR\plugins\libxmpp.dll"
Delete "$INSTDIR\plugins\log_reader.dll"
Delete "$INSTDIR\plugins\markerline.dll"
--- a/po/POTFILES.in Wed Oct 05 21:14:58 2016 +0200
+++ b/po/POTFILES.in Wed Oct 05 15:10:29 2016 -0500
@@ -144,16 +144,6 @@
libpurple/protocols/silc10/util.c
libpurple/protocols/silc10/wb.c
libpurple/protocols/simple/simple.c
-libpurple/protocols/yahoo/libyahoo.c
-libpurple/protocols/yahoo/libyahoojp.c
-libpurple/protocols/yahoo/libymsg.c
-libpurple/protocols/yahoo/yahoo_aliases.c
-libpurple/protocols/yahoo/yahoo_doodle.c
-libpurple/protocols/yahoo/yahoo_filexfer.c
-libpurple/protocols/yahoo/yahoo_packet.c
-libpurple/protocols/yahoo/yahoo_profile.c
-libpurple/protocols/yahoo/yahoochat.c
-libpurple/protocols/yahoo/ycht.c
libpurple/protocols/zephyr/zephyr.c