Fri, 01 Jun 2007 23:53:05 +0000
propagate from branch 'im.pidgin.pidgin' (head 45e375cfc6695c752631c5a2710c8bccf1db3e46)
to branch 'im.pidgin.soc.2007.certmgr' (head 9bdc2503513a3fc9c9479926dd4895c9bf6ec54b)
| pidgin/pixmaps/emotes/default/22/default.theme.in | file | annotate | diff | comparison | revisions | |
| pidgin/pixmaps/emotes/default/22/theme | file | annotate | diff | comparison | revisions | |
| pidgin/pixmaps/emotes/none/none.theme.in | file | annotate | diff | comparison | revisions | |
| pidgin/pixmaps/emotes/none/theme | file | annotate | diff | comparison | revisions |
--- a/.mtn-ignore Thu May 31 00:40:46 2007 +0000 +++ b/.mtn-ignore Fri Jun 01 23:53:05 2007 +0000 @@ -12,6 +12,7 @@ Doxyfile$ aclocal.m4 compile +config.cache config.guess config.h$ config.h.in @@ -32,6 +33,8 @@ pidgin-.*.tar.gz pidgin-.*.tar.bz2 pidgin/pidgin$ +pidgin/pixmaps/emotes/default/22/theme +pidgin/pixmaps/emotes/none/theme pidgin/plugins/musicmessaging/music-messaging-bindings.c pidgin/plugins/perl/common/Makefile.PL$ pidgin/win32/pidgin_dll_rc.rc$
--- a/COPYRIGHT Thu May 31 00:40:46 2007 +0000 +++ b/COPYRIGHT Fri Jun 01 23:53:05 2007 +0000 @@ -129,6 +129,7 @@ Decklin Foster Francesco Fracassi Adam Fritzler +Takao Fujiwara Max G. François Gagné Andrew Gaul @@ -149,6 +150,7 @@ Casey Harkins Andy Harrison Andrew Hart (arhart) +Rene Hausleitner G. Sumner Hayes Michael R. Head Nick Hebner @@ -333,8 +335,10 @@ Richard Stellingwerff Charlie Stockman David Stoddard +Oleg Sukhodolsky Sun Microsystems Mårten Svantesson (fursten) +Amir Szekely (kichik) Robert T. Greg Taeger Peter Tang
--- a/ChangeLog Thu May 31 00:40:46 2007 +0000 +++ b/ChangeLog Fri Jun 01 23:53:05 2007 +0000 @@ -1,6 +1,14 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 2.0.2 (??/??/????): + Pidgin: + * Added a custom conversation font option to preferences + + libpurple: + * Moving an ICQ buddy from one group to another no longer + re-requests authorization from that person (Rene Hausleitner) + * Added nullprpl, an example protocol plugin (Ryan Barrett) + * Fixed SOCKS5 bug which caused Jabber file receiving to fail Finch: * Auto account reconnecting
--- a/configure.ac Thu May 31 00:40:46 2007 +0000 +++ b/configure.ac Fri Jun 01 23:53:05 2007 +0000 @@ -2085,6 +2085,7 @@ libpurple/protocols/jabber/Makefile libpurple/protocols/msn/Makefile libpurple/protocols/novell/Makefile + libpurple/protocols/null/Makefile libpurple/protocols/oscar/Makefile libpurple/protocols/qq/Makefile libpurple/protocols/sametime/Makefile
--- a/finch/gntrequest.c Thu May 31 00:40:46 2007 +0000 +++ b/finch/gntrequest.c Fri Jun 01 23:53:05 2007 +0000 @@ -672,10 +672,13 @@ pt = purple_prefs_get_type(id); switch (pt) { case PURPLE_PREF_INT: + { + long int tmp; if (type == PURPLE_REQUEST_FIELD_LIST) /* Lists always return string */ - sscanf(val, "%ld", (long int *)&val); - purple_prefs_set_int(id, GPOINTER_TO_INT(val)); + sscanf(val, "%ld", &tmp); + purple_prefs_set_int(id, (gint)tmp); break; + } case PURPLE_PREF_BOOLEAN: purple_prefs_set_bool(id, GPOINTER_TO_INT(val)); break;
--- a/libpurple/connection.h Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/connection.h Fri Jun 01 23:53:05 2007 +0000 @@ -279,7 +279,7 @@ * TODO: Eventually this bad boy will be removed, because it is * a gross fix for a crashy problem. */ -#define PURPLE_CONNECTION_IS_VALID(gc) (g_list_find(purple_connections_get_all(), (gc))) +#define PURPLE_CONNECTION_IS_VALID(gc) (g_list_find(purple_connections_get_all(), (gc)) != NULL) /*@}*/
--- a/libpurple/dbus-analyze-functions.py Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/dbus-analyze-functions.py Fri Jun 01 23:53:05 2007 +0000 @@ -166,8 +166,11 @@ self.returncode = [] def flush(self): + paramslist = ", ".join(self.paramshdr) + if (paramslist == "") : + paramslist = "void" print "%s %s(%s)" % (self.functiontype, self.function.name, - ", ".join(self.paramshdr)), + paramslist), if self.headersonly: print ";"
--- a/libpurple/plugins/perl/perl-common.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/plugins/perl/perl-common.c Fri Jun 01 23:53:05 2007 +0000 @@ -205,7 +205,7 @@ purple_debug(PURPLE_DEBUG_ERROR, "perl", "Perl function %s exited abnormally: %s\n", function, SvPV(ERRSV, na)); - POPs; + (void)POPs; } else if (count != 1) { /* * This should NEVER happen. G_SCALAR ensures that we WILL
--- a/libpurple/plugins/tcl/tcl_signals.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/plugins/tcl/tcl_signals.c Fri Jun 01 23:53:05 2007 +0000 @@ -49,7 +49,9 @@ Tcl_DecrRefCount(handler->signal); if (handler->namespace) + { Tcl_DecrRefCount(handler->namespace); + } g_free(handler); }
--- a/libpurple/protocols/Makefile.am Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/Makefile.am Fri Jun 01 23:53:05 2007 +0000 @@ -1,5 +1,5 @@ -EXTRA_DIST = Makefile.mingw +EXTRA_DIST = Makefile.mingw null/ -DIST_SUBDIRS = bonjour gg irc jabber msn novell oscar qq sametime silc toc simple yahoo zephyr +DIST_SUBDIRS = bonjour gg irc jabber msn novell null oscar qq sametime silc toc simple yahoo zephyr SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS)
--- a/libpurple/protocols/Makefile.mingw Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/Makefile.mingw Fri Jun 01 23:53:05 2007 +0000 @@ -8,7 +8,7 @@ PIDGIN_TREE_TOP := ../.. include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak -SUBDIRS = gg irc jabber msn novell oscar qq sametime silc simple yahoo +SUBDIRS = gg irc jabber msn novell null oscar qq sametime silc simple yahoo .PHONY: all install clean
--- a/libpurple/protocols/gg/gg.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/gg/gg.c Fri Jun 01 23:53:05 2007 +0000 @@ -253,8 +253,8 @@ /* */ -/* static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, gchar *file) {{{ */ -static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, gchar *file) +/* static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, const char *file) {{{ */ +static void ggp_callback_buddylist_save_ok(PurpleConnection *gc, const char *file) { PurpleAccount *account = purple_connection_get_account(gc); @@ -277,7 +277,7 @@ purple_debug_error("gg", "Could not open file: %s\n", file); purple_notify_error(account, _("Couldn't open file"), msg, NULL); g_free(msg); - g_free(file); + g_free(buddylist); return; }
--- a/libpurple/protocols/msn/sync.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/msn/sync.c Fri Jun 01 23:53:05 2007 +0000 @@ -195,6 +195,8 @@ user = sync->last_user; + g_return_if_fail(user != NULL); + type = cmd->params[0]; value = cmd->params[1];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/null/Makefile.am Fri Jun 01 23:53:05 2007 +0000 @@ -0,0 +1,21 @@ +EXTRA_DIST = README Makefile.mingw + +pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION) + +NULLSOURCES = nullprpl.c + +AM_CFLAGS = $(st) + +libnull_la_LDFLAGS = -module -avoid-version + +# nullprpl isn't built by default. when it is built, it's dynamically linked. +st = +pkg_LTLIBRARIES = libnull.la +libnull_la_SOURCES = $(NULLSOURCES) +libnull_la_LIBADD = $(GLIB_LIBS) + +AM_CPPFLAGS = \ + -I$(top_srcdir)/libpurple \ + -I$(top_builddir)/libpurple \ + $(GLIB_CFLAGS) \ + $(DEBUG_CFLAGS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/null/Makefile.mingw Fri Jun 01 23:53:05 2007 +0000 @@ -0,0 +1,77 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libnull +# + +PIDGIN_TREE_TOP := ../../.. +include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak + +TARGET = libnull +TYPE = PLUGIN + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(PURPLE_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(PURPLE_INSTALL_PLUGINS_DIR) +endif +endif + +## +## INCLUDE PATHS +## +INCLUDE_PATHS += -I. \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(PURPLE_TOP) \ + -I$(PURPLE_TOP)/win32 \ + -I$(PIDGIN_TREE_TOP) + +LIB_PATHS += -L$(GTK_TOP)/lib \ + -L$(PURPLE_TOP) + +## +## SOURCES, OBJECTS +## +C_SRC = nullprpl.c + +OBJECTS = $(C_SRC:%.c=%.o) + +## +## LIBRARIES +## +LIBS = \ + -lglib-2.0 \ + -lintl \ + -lws2_32 \ + -lpurple + +include $(PIDGIN_COMMON_RULES) + +## +## TARGET DEFINITIONS +## +.PHONY: all install clean + +all: $(TARGET).dll + +install: all $(DLL_INSTALL_DIR) $(PURPLE_INSTALL_DIR) + cp $(TARGET).dll $(DLL_INSTALL_DIR) + +$(OBJECTS): $(PURPLE_CONFIG_H) + +$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS) + $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll + +## +## CLEAN RULES +## +clean: + rm -f $(OBJECTS) + rm -f $(TARGET).dll + +include $(PIDGIN_COMMON_TARGETS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/null/README Fri Jun 01 23:53:05 2007 +0000 @@ -0,0 +1,46 @@ +nullprpl + +-------- +OVERVIEW +-------- +Nullprpl is a mock protocol plugin for Pidgin and libpurple. You can create +accounts with it, sign on and off, add buddies, and send and receive IMs, all +without connecting to a server! + +Beyond that basic functionality, nullprpl supports presence and away/available +messages, offline messages, user info, typing notification, privacy +allow/block lists, chat rooms, whispering, room lists, and protocol icons and +emblems. Notable missing features are file transfer and account registration +and authentication. + +Nullprpl is intended as an example of how to write a libpurple protocol +plugin. It doesn't contain networking code or an event loop, but it does +demonstrate how to use the libpurple API to do pretty much everything a prpl +might need to do. + +Nullprpl is also a useful tool for hacking on Pidgin, Finch, and other +libpurple clients. It's a full-featured protocol plugin, but doesn't depend on +an external server, so it's a quick and easy way to exercise test new code. It +also allows you to work while you're disconnected. + +----------------------- +BUILDING AND INSTALLING +----------------------- + +To build, just run ./configure as usual in the root directory of the pidgin +source distribution. Then cd libpurple/protocols/null and type make. To +install, copy libnull.la and .libs/libnull.so into your ~/.purple/plugins +directory. Then run Pidgin. + +To build nullprpl on Windows (with Cygwin/MinGW), use Makefile.mingw. + +----- +USAGE +----- +To add a nullprpl account, go to the account editor window and click Add. +Select Nullprpl from the protocol drop-down list, and enter any username you +want. + +Now, use Pidgin like normal. You can add buddies, send IMs, set away messages, +etc. If you send IMs to your own username, they will be echoed back to you. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/null/nullprpl.c Fri Jun 01 23:53:05 2007 +0000 @@ -0,0 +1,1202 @@ +/** + * purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * Nullprpl is a mock protocol plugin for Pidgin and libpurple. You can create + * accounts with it, sign on and off, add buddies, and send and receive IMs, + * all without connecting to a server! + * + * Beyond that basic functionality, nullprpl supports presence and + * away/available messages, offline messages, user info, typing notification, + * privacy allow/block lists, chat rooms, whispering, room lists, and protocol + * icons and emblems. Notable missing features are file transfer and account + * registration and authentication. + * + * Nullprpl is intended as an example of how to write a libpurple protocol + * plugin. It doesn't contain networking code or an event loop, but it does + * demonstrate how to use the libpurple API to do pretty much everything a prpl + * might need to do. + * + * Nullprpl is also a useful tool for hacking on Pidgin, Finch, and other + * libpurple clients. It's a full-featured protocol plugin, but doesn't depend + * on an external server, so it's a quick and easy way to exercise test new + * code. It also allows you to work while you're disconnected. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> +#include <string.h> +#include <time.h> + +#include <glib.h> + +#include "internal.h" +#include "config.h" +#include "account.h" +#include "accountopt.h" +#include "blist.h" +#include "cmds.h" +#include "conversation.h" +#include "connection.h" +#include "debug.h" +#include "notify.h" +#include "privacy.h" +#include "prpl.h" +#include "roomlist.h" +#include "status.h" +#include "util.h" +#include "version.h" + + +#define NULLPRPL_ID "prpl-null" +static PurplePlugin *_null_protocol = NULL; + +#define NULL_STATUS_ONLINE "online" +#define NULL_STATUS_AWAY "away" +#define NULL_STATUS_OFFLINE "offline" + +typedef void (*GcFunc)(PurpleConnection *from, + PurpleConnection *to, + gpointer userdata); + +typedef struct { + GcFunc fn; + PurpleConnection *from; + gpointer userdata; +} GcFuncData; + +/* + * stores offline messages that haven't been delivered yet. maps username + * (char *) to GList * of GOfflineMessages. initialized in nullprpl_init. + */ +GHashTable* goffline_messages = NULL; + +typedef struct { + char *from; + char *message; + time_t mtime; + PurpleMessageFlags flags; +} GOfflineMessage; + +/* + * helpers + */ +static PurpleConnection *get_nullprpl_gc(const char *username) { + PurpleAccount *acct = purple_accounts_find(username, NULLPRPL_ID); + if (acct && purple_account_is_connected(acct)) + return acct->gc; + else + return NULL; +} + +static void call_if_nullprpl(gpointer data, gpointer userdata) { + PurpleConnection *gc = (PurpleConnection *)(data); + GcFuncData *gcfdata = (GcFuncData *)userdata; + + if (!strcmp(gc->account->protocol_id, NULLPRPL_ID)) + gcfdata->fn(gcfdata->from, gc, gcfdata->userdata); +} + +static void foreach_nullprpl_gc(GcFunc fn, PurpleConnection *from, + gpointer userdata) { + GcFuncData gcfdata = { fn, from, userdata }; + g_list_foreach(purple_connections_get_all(), call_if_nullprpl, + &gcfdata); +} + + +typedef void(*ChatFunc)(PurpleConvChat *from, PurpleConvChat *to, + int id, const char *room, gpointer userdata); + +typedef struct { + ChatFunc fn; + PurpleConvChat *from_chat; + gpointer userdata; +} ChatFuncData; + +static void call_chat_func(gpointer data, gpointer userdata) { + PurpleConnection *to = (PurpleConnection *)data; + ChatFuncData *cfdata = (ChatFuncData *)userdata; + + int id = cfdata->from_chat->id; + PurpleConversation *conv = purple_find_chat(to, id); + if (conv) { + PurpleConvChat *chat = purple_conversation_get_chat_data(conv); + cfdata->fn(cfdata->from_chat, chat, id, conv->name, cfdata->userdata); + } +} + +static void foreach_gc_in_chat(ChatFunc fn, PurpleConnection *from, + int id, gpointer userdata) { + PurpleConversation *conv = purple_find_chat(from, id); + ChatFuncData cfdata = { fn, + purple_conversation_get_chat_data(conv), + userdata }; + + g_list_foreach(purple_connections_get_all(), call_chat_func, + &cfdata); +} + + +static void discover_status(PurpleConnection *from, PurpleConnection *to, + gpointer userdata) { + char *from_username = from->account->username; + char *to_username = to->account->username; + + if (purple_find_buddy(from->account, to_username)) { + PurpleStatus *status = purple_account_get_active_status(to->account); + const char *status_id = purple_status_get_id(status); + const char *message = purple_status_get_attr_string(status, "message"); + + if (!strcmp(status_id, NULL_STATUS_ONLINE) || + !strcmp(status_id, NULL_STATUS_AWAY) || + !strcmp(status_id, NULL_STATUS_OFFLINE)) { + purple_debug_info("nullprpl", "%s sees that %s is %s: %s\n", + from_username, to_username, status_id, message); + purple_prpl_got_user_status(from->account, to_username, status_id, + (message) ? "message" : NULL, message, NULL); + } else { + purple_debug_error("nullprpl", + "%s's buddy %s has an unknown status: %s, %s", + from_username, to_username, status_id, message); + } + } +} + +static void report_status_change(PurpleConnection *from, PurpleConnection *to, + gpointer userdata) { + purple_debug_info("nullprpl", "notifying %s that %s changed status\n", + to->account->username, from->account->username); + discover_status(to, from, NULL); +} + + +/* + * UI callbacks + */ +static void nullprpl_input_user_info(PurplePluginAction *action) +{ + PurpleConnection *gc = (PurpleConnection *)action->context; + PurpleAccount *acct = purple_connection_get_account(gc); + purple_debug_info("nullprpl", "showing 'Set User Info' dialog for %s\n", + acct->username); + + purple_account_request_change_user_info(acct); +} + +/* this is set to the actions member of the PurplePluginInfo struct at the + * bottom. + */ +static GList *nullprpl_actions(PurplePlugin *plugin, gpointer context) +{ + PurplePluginAction *action = purple_plugin_action_new( + _("Set User Info..."), nullprpl_input_user_info); + return g_list_append(NULL, action); +} + + +/* + * prpl functions + */ +static const char *nullprpl_list_icon(PurpleAccount *acct, PurpleBuddy *buddy) +{ + /* shamelessly steal (er, borrow) the meanwhile protocol icon. it's cute! */ + return "meanwhile"; +} + +static const char *nullprpl_list_emblem(PurpleBuddy *buddy) +{ + const char* emblem; + + if (get_nullprpl_gc(buddy->name)) { + PurplePresence *presence = purple_buddy_get_presence(buddy); + PurpleStatus *status = purple_presence_get_active_status(presence); + emblem = purple_status_get_name(status); + } else { + emblem = "offline"; + } + + purple_debug_info("nullprpl", "using emblem %s for %s's buddy %s\n", + emblem, buddy->account->username, buddy->name); + return emblem; +} + +static char *nullprpl_status_text(PurpleBuddy *buddy) { + purple_debug_info("nullprpl", "getting %s's status text for %s\n", + buddy->name, buddy->account->username); + + if (purple_find_buddy(buddy->account, buddy->name)) { + PurplePresence *presence = purple_buddy_get_presence(buddy); + PurpleStatus *status = purple_presence_get_active_status(presence); + const char *name = purple_status_get_name(status); + const char *message = purple_status_get_attr_string(status, "message"); + + char *text; + if (message && strlen(message) > 0) + text = g_strdup_printf("%s: %s", name, message); + else + text = g_strdup(name); + + purple_debug_info("nullprpl", "%s's status text is %s\n", buddy->name, text); + return text; + + } else { + purple_debug_info("nullprpl", "...but %s is not logged in\n", buddy->name); + return "Not logged in"; + } +} + +static void nullprpl_tooltip_text(PurpleBuddy *buddy, + PurpleNotifyUserInfo *info, + gboolean full) { + PurpleConnection *gc = get_nullprpl_gc(buddy->name); + + if (gc) { + /* they're logged in */ + PurplePresence *presence = purple_buddy_get_presence(buddy); + PurpleStatus *status = purple_presence_get_active_status(presence); + const char *msg = nullprpl_status_text(buddy); + purple_notify_user_info_add_pair(info, purple_status_get_name(status), + msg); + + if (full) { + const char *user_info = purple_account_get_user_info(gc->account); + if (user_info) + purple_notify_user_info_add_pair(info, _("User info"), user_info); + } + + } else { + /* they're not logged in */ + purple_notify_user_info_add_pair(info, _("User info"), _("not logged in")); + } + + purple_debug_info("nullprpl", "showing %s tooltip for %s\n", + (full) ? "full" : "short", buddy->name); +} + +static GList *nullprpl_status_types(PurpleAccount *acct) +{ + GList *types = NULL; + PurpleStatusType *type; + + purple_debug_info("nullprpl", "returning status types for %s: %s, %s, %s\n", + acct->username, + NULL_STATUS_ONLINE, NULL_STATUS_AWAY, NULL_STATUS_OFFLINE); + + type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, NULL_STATUS_ONLINE, + NULL_STATUS_ONLINE, TRUE); + purple_status_type_add_attr(type, "message", _("Online"), + purple_value_new(PURPLE_TYPE_STRING)); + types = g_list_append(types, type); + + type = purple_status_type_new(PURPLE_STATUS_AWAY, NULL_STATUS_AWAY, + NULL_STATUS_AWAY, TRUE); + purple_status_type_add_attr(type, "message", _("Away"), + purple_value_new(PURPLE_TYPE_STRING)); + types = g_list_append(types, type); + + type = purple_status_type_new(PURPLE_STATUS_OFFLINE, NULL_STATUS_OFFLINE, + NULL_STATUS_OFFLINE, TRUE); + purple_status_type_add_attr(type, "message", _("Offline"), + purple_value_new(PURPLE_TYPE_STRING)); + types = g_list_append(types, type); + + return types; +} + +static void blist_example_menu_item(PurpleBlistNode *node, gpointer userdata) { + purple_debug_info("nullprpl", "example menu item clicked on user", + ((PurpleBuddy *)node)->name); + + purple_notify_info(NULL, /* plugin handle or PurpleConnection */ + _("Primary title"), + _("Secondary title"), + _("This is the callback for the nullprpl menu item.")); +} + +static GList *nullprpl_blist_node_menu(PurpleBlistNode *node) { + purple_debug_info("nullprpl", "providing buddy list context menu item\n"); + + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { + PurpleMenuAction *action = purple_menu_action_new( + _("Nullprpl example menu item"), + PURPLE_CALLBACK(blist_example_menu_item), + NULL, /* userdata passed to the callback */ + NULL); /* child menu items */ + return g_list_append(NULL, action); + } else { + return NULL; + } +} + +static GList *nullprpl_chat_info(PurpleConnection *gc) { + struct proto_chat_entry *pce; /* defined in prpl.h */ + + purple_debug_info("nullprpl", "returning chat setting 'room'\n"); + + pce = g_new0(struct proto_chat_entry, 1); + pce->label = _(_("Chat _room")); + pce->identifier = "room"; + pce->required = TRUE; + + return g_list_append(NULL, pce); +} + +static GHashTable *nullprpl_chat_info_defaults(PurpleConnection *gc, + const char *room) { + GHashTable *defaults; + + purple_debug_info("nullprpl", "returning chat default setting " + "'room' = 'default'\n"); + + defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); + g_hash_table_insert(defaults, "room", g_strdup("default")); + return defaults; +} + +static void nullprpl_login(PurpleAccount *acct) +{ + PurpleConnection *gc = purple_account_get_connection(acct); + GList *offline_messages; + + purple_debug_info("nullprpl", "logging in %s\n", acct->username); + + purple_connection_update_progress(gc, _("Connecting"), + 0, /* which connection step this is */ + 2); /* total number of steps */ + + purple_connection_update_progress(gc, _("Connected"), + 1, /* which connection step this is */ + 2); /* total number of steps */ + purple_connection_set_state(gc, PURPLE_CONNECTED); + + /* tell purple about everyone on our buddy list who's connected */ + foreach_nullprpl_gc(discover_status, gc, NULL); + + /* notify other nullprpl accounts */ + foreach_nullprpl_gc(report_status_change, gc, NULL); + + /* fetch stored offline messages */ + purple_debug_info("nullprpl", "checking for offline messages for %s\n", + acct->username); + offline_messages = g_hash_table_lookup(goffline_messages, acct->username); + while (offline_messages) { + GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; + purple_debug_info("nullprpl", "delivering offline message to %s: %s\n", + acct->username, message->message); + serv_got_im(gc, message->from, message->message, message->flags, + message->mtime); + offline_messages = g_list_next(offline_messages); + + g_free(message->from); + g_free(message->message); + g_free(message); + } + + g_list_free(offline_messages); + g_hash_table_remove(goffline_messages, &acct->username); +} + +static void nullprpl_close(PurpleConnection *gc) +{ + /* notify other nullprpl accounts */ + foreach_nullprpl_gc(report_status_change, gc, NULL); +} + +static int nullprpl_send_im(PurpleConnection *gc, const char *who, + const char *message, PurpleMessageFlags flags) +{ + const char *from_username = gc->account->username; + PurpleMessageFlags receive_flags = ((flags & ~PURPLE_MESSAGE_SEND) + | PURPLE_MESSAGE_RECV); + PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID); + PurpleConnection *to; + + purple_debug_info("nullprpl", "sending message from %s to %s: %s\n", + from_username, who, message); + + /* is the sender blocked by the recipient's privacy settings? */ + if (!purple_privacy_check(to_acct, gc->account->username)) { + char *msg = g_strdup_printf( + _("Your message was blocked by %s's privacy settings."), who); + purple_debug_info("nullprpl", + "discarding; %s is blocked by %s's privacy settings\n", + from_username, who); + purple_conv_present_error(who, gc->account, msg); + g_free(msg); + return 0; + } + + /* is the recipient online? */ + to = get_nullprpl_gc(who); + if (to) { /* yes, send */ + serv_got_im(to, from_username, message, receive_flags, time(NULL)); + + } else { /* nope, store as an offline message */ + GOfflineMessage *offline_message; + GList *messages; + + purple_debug_info("nullprpl", + "%s is offline, sending as offline message\n", who); + offline_message = g_new0(GOfflineMessage, 1); + offline_message->from = g_strdup(from_username); + offline_message->message = g_strdup(message); + offline_message->mtime = time(NULL); + offline_message->flags = receive_flags; + + messages = g_hash_table_lookup(goffline_messages, who); + messages = g_list_append(messages, offline_message); + g_hash_table_insert(goffline_messages, g_strdup(who), messages); + } + + return 1; +} + +static void nullprpl_set_info(PurpleConnection *gc, const char *info) { + purple_debug_info("nullprpl", "setting %s's user info to %s\n", + gc->account->username, info); +} + +static char *typing_state_to_string(PurpleTypingState typing) { + switch (typing) { + case PURPLE_NOT_TYPING: return "is not typing"; + case PURPLE_TYPING: return "is typing"; + case PURPLE_TYPED: return "stopped typing momentarily"; + default: return "unknown typing state"; + } +} + +static void notify_typing(PurpleConnection *from, PurpleConnection *to, + gpointer typing) { + char *from_username = from->account->username; + char *action = typing_state_to_string((PurpleTypingState)typing); + purple_debug_info("nullprpl", "notifying %s that %s %s\n", + to->account->username, from_username, action); + + serv_got_typing(to, + from_username, + 0, /* if non-zero, a timeout in seconds after which to + * reset the typing status to PURPLE_NOT_TYPING */ + (PurpleTypingState)typing); +} + +static unsigned int nullprpl_send_typing(PurpleConnection *gc, const char *name, + PurpleTypingState typing) { + purple_debug_info("nullprpl", "%s %s\n", gc->account->username, + typing_state_to_string(typing)); + foreach_nullprpl_gc(notify_typing, gc, (gpointer)typing); + return 0; +} + +static void nullprpl_get_info(PurpleConnection *gc, const char *username) { + const char *body; + PurpleNotifyUserInfo *info = purple_notify_user_info_new(); + PurpleAccount *acct; + + purple_debug_info("nullprpl", "Fetching %s's user info for %s\n", username, + gc->account->username); + + if (!get_nullprpl_gc(username)) { + char *msg = g_strdup_printf(_("%s is not logged in."), username); + purple_notify_error(gc, _("User Info"), _("User info not available. "), msg); + g_free(msg); + } + + acct = purple_accounts_find(username, NULLPRPL_ID); + if (acct) + body = purple_account_get_user_info(acct); + else + body = _("No user info."); + purple_notify_user_info_add_pair(info, "Info", body); + + /* show a buddy's user info in a nice dialog box */ + purple_notify_userinfo(gc, /* connection the buddy info came through */ + username, /* buddy's username */ + info, /* body */ + NULL, /* callback called when dialog closed */ + NULL); /* userdata for callback */ +} + +static void nullprpl_set_status(PurpleAccount *acct, PurpleStatus *status) { + const char *msg = purple_status_get_attr_string(status, "message"); + purple_debug_info("nullprpl", "setting %s's status to %s: %s\n", + acct->username, purple_status_get_name(status), msg); + + foreach_nullprpl_gc(report_status_change, get_nullprpl_gc(acct->username), + NULL); +} + +static void nullprpl_set_idle(PurpleConnection *gc, int idletime) { + purple_debug_info("nullprpl", + "purple reports that %s has been idle for %d seconds\n", + gc->account->username, idletime); +} + +static void nullprpl_change_passwd(PurpleConnection *gc, const char *old_pass, + const char *new_pass) { + purple_debug_info("nullprpl", "%s wants to change their password\n", + gc->account->username); +} + +static void nullprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, + PurpleGroup *group) +{ + char *username = gc->account->username; + PurpleConnection *buddy_gc = get_nullprpl_gc(buddy->name); + + purple_debug_info("nullprpl", "adding %s to %s's buddy list\n", buddy->name, + username); + + if (buddy_gc) { + PurpleAccount *buddy_acct = buddy_gc->account; + + discover_status(gc, buddy_gc, NULL); + + if (purple_find_buddy(buddy_acct, username)) { + purple_debug_info("nullprpl", "%s is already on %s's buddy list\n", + username, buddy->name); + } else { + purple_debug_info("nullprpl", "asking %s if they want to add %s\n", + buddy->name, username); + purple_account_request_add(buddy_acct, + username, + NULL, /* local account id (rarely used) */ + NULL, /* alias */ + NULL); /* message */ + } + } +} + +static void nullprpl_add_buddies(PurpleConnection *gc, GList *buddies, + GList *groups) { + GList *buddy = buddies; + GList *group = groups; + + purple_debug_info("nullprpl", "adding multiple buddies\n"); + + while (buddy && group) { + nullprpl_add_buddy(gc, (PurpleBuddy *)buddy->data, (PurpleGroup *)group->data); + buddy = g_list_next(buddy); + group = g_list_next(group); + } +} + +static void nullprpl_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, + PurpleGroup *group) +{ + purple_debug_info("nullprpl", "removing %s from %s's buddy list\n", + buddy->name, gc->account->username); +} + +static void nullprpl_remove_buddies(PurpleConnection *gc, GList *buddies, + GList *groups) { + GList *buddy = buddies; + GList *group = groups; + + purple_debug_info("nullprpl", "removing multiple buddies\n"); + + while (buddy && group) { + nullprpl_remove_buddy(gc, (PurpleBuddy *)buddy->data, + (PurpleGroup *)group->data); + buddy = g_list_next(buddy); + group = g_list_next(group); + } +} + +/* + * nullprpl uses purple's local whitelist and blacklist, stored in blist.xml, as + * its authoritative privacy settings, and uses purple's logic (specifically + * purple_privacy_check(), from privacy.h), to determine whether messages are + * allowed or blocked. + */ +static void nullprpl_add_permit(PurpleConnection *gc, const char *name) { + purple_debug_info("nullprpl", "%s adds %s to their allowed list\n", + gc->account->username, name); +} + +static void nullprpl_add_deny(PurpleConnection *gc, const char *name) { + purple_debug_info("nullprpl", "%s adds %s to their blocked list\n", + gc->account->username, name); +} + +static void nullprpl_rem_permit(PurpleConnection *gc, const char *name) { + purple_debug_info("nullprpl", "%s removes %s from their allowed list\n", + gc->account->username, name); +} + +static void nullprpl_rem_deny(PurpleConnection *gc, const char *name) { + purple_debug_info("nullprpl", "%s removes %s from their blocked list\n", + gc->account->username, name); +} + +static void nullprpl_set_permit_deny(PurpleConnection *gc) { + /* this is for synchronizing the local black/whitelist with the server. + * for nullprpl, it's a noop. + */ +} + +static void joined_chat(PurpleConvChat *from, PurpleConvChat *to, + int id, const char *room, gpointer userdata) { + /* tell their chat window that we joined */ + purple_debug_info("nullprpl", "%s sees that %s joined chat room %s\n", + to->nick, from->nick, room); + purple_conv_chat_add_user(to, + from->nick, + NULL, /* user-provided join message, IRC style */ + PURPLE_CBFLAGS_NONE, + TRUE); /* show a join message */ + + if (from != to) { + /* add them to our chat window */ + purple_debug_info("nullprpl", "%s sees that %s is in chat room %s\n", + from->nick, to->nick, room); + purple_conv_chat_add_user(from, + to->nick, + NULL, /* user-provided join message, IRC style */ + PURPLE_CBFLAGS_NONE, + FALSE); /* show a join message */ + } +} + +static void nullprpl_join_chat(PurpleConnection *gc, GHashTable *components) { + char *username = gc->account->username; + char *room = g_hash_table_lookup(components, "room"); + int chat_id = g_str_hash(room); + purple_debug_info("nullprpl", "%s is joining chat room %s\n", username, room); + + if (!purple_find_chat(gc, chat_id)) { + serv_got_joined_chat(gc, chat_id, room); + + /* tell everyone that we joined, and add them if they're already there */ + foreach_gc_in_chat(joined_chat, gc, chat_id, NULL); + } else { + purple_debug_info("nullprpl", "%s is already in chat room %s\n", username, + room); + purple_notify_info(gc, + _("Join chat"), + _("Join chat"), + g_strdup_printf("%s is already in chat room %s.", + username, room)); + } +} + +static void nullprpl_reject_chat(PurpleConnection *gc, GHashTable *components) { + char *invited_by = g_hash_table_lookup(components, "invited_by"); + char *room = g_hash_table_lookup(components, "room"); + char *username = gc->account->username; + PurpleConnection *invited_by_gc = get_nullprpl_gc(invited_by); + char *message = g_strdup_printf( + "%s %s %s.", + username, + _("has rejected your invitation to join the chat room"), + room); + + purple_debug_info("nullprpl", + "%s has rejected %s's invitation to join chat room %s\n", + username, invited_by, room); + + purple_notify_info(invited_by_gc, + _("Chat invitation rejected"), + _("Chat invitation rejected"), + message); +} + +static char *nullprpl_get_chat_name(GHashTable *components) { + char *room = g_hash_table_lookup(components, "room"); + purple_debug_info("nullprpl", "reporting chat room name '%s'\n", room); + return room; +} + +static void nullprpl_chat_invite(PurpleConnection *gc, int id, + const char *message, const char *who) { + char *username = gc->account->username; + PurpleConversation *conv = purple_find_chat(gc, id); + char *room = conv->name; + PurpleAccount *to_acct = purple_accounts_find(who, NULLPRPL_ID); + + purple_debug_info("nullprpl", "%s is inviting %s to join chat room %s\n", + username, who, room); + + if (to_acct) { + PurpleConversation *to_conv = purple_find_chat(to_acct->gc, id); + if (to_conv) { + purple_debug_info("nullprpl", + "%s is already in chat room %s; " + "ignoring invitation from %s\n", + who, room, username); + purple_notify_info(gc, + _("Chat invitation"), + _("Chat invitation"), + g_strdup_printf("%s is already in chat room %s.", + who, room)); + } else { + GHashTable *components; + components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free); + g_hash_table_replace(components, "room", g_strdup(room)); + g_hash_table_replace(components, "invited_by", g_strdup(username)); + serv_got_chat_invite(to_acct->gc, room, username, message, components); + } + } +} + +static void left_chat_room(PurpleConvChat *from, PurpleConvChat *to, + int id, const char *room, gpointer userdata) { + if (from != to) { + /* tell their chat window that we left */ + purple_debug_info("nullprpl", "%s sees that %s left chat room %s\n", + to->nick, from->nick, room); + purple_conv_chat_remove_user(to, + from->nick, + NULL); /* user-provided message, IRC style */ + } +} + +static void nullprpl_chat_leave(PurpleConnection *gc, int id) { + PurpleConversation *conv = purple_find_chat(gc, id); + purple_debug_info("nullprpl", "%s is leaving chat room %s\n", + gc->account->username, conv->name); + + /* tell everyone that we left */ + foreach_gc_in_chat(left_chat_room, gc, id, NULL); +} + +static PurpleCmdRet send_whisper(PurpleConversation *conv, const gchar *cmd, + gchar **args, gchar **error, void *userdata) { + const char *to_username; + const char *message; + const char *from_username; + PurpleConvChat *chat; + PurpleConvChatBuddy *chat_buddy; + PurpleConnection *to; + + /* parse args */ + to_username = args[0]; + message = args[1]; + + if (!to_username || strlen(to_username) == 0) { + *error = g_strdup(_("Whisper is missing recipient.")); + return PURPLE_CMD_RET_FAILED; + } else if (!message || strlen(message) == 0) { + *error = g_strdup(_("Whisper is missing message.")); + return PURPLE_CMD_RET_FAILED; + } + + from_username = conv->account->username; + purple_debug_info("nullprpl", "%s whispers to %s in chat room %s: %s\n", + from_username, to_username, conv->name, message); + + chat = purple_conversation_get_chat_data(conv); + chat_buddy = purple_conv_chat_cb_find(chat, to_username); + to = get_nullprpl_gc(to_username); + + if (!chat_buddy) { + /* this will be freed by the caller */ + *error = g_strdup_printf(_("%s is not logged in."), to_username); + return PURPLE_CMD_RET_FAILED; + } else if (!to) { + *error = g_strdup_printf(_("%s is not in this chat room."), to_username); + return PURPLE_CMD_RET_FAILED; + } else { + /* write the whisper in the sender's chat window */ + char *message_to = g_strdup_printf("%s (to %s)", message, to_username); + purple_conv_chat_write(chat, from_username, message_to, + PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_WHISPER, + time(NULL)); + g_free(message_to); + + /* send the whisper */ + serv_chat_whisper(to, chat->id, from_username, message); + + return PURPLE_CMD_RET_OK; + } +} + +static void nullprpl_chat_whisper(PurpleConnection *gc, int id, const char *who, + const char *message) { + char *username = gc->account->username; + PurpleConversation *conv = purple_find_chat(gc, id); + purple_debug_info("nullprpl", + "%s receives whisper from %s in chat room %s: %s\n", + username, who, conv->name, message); + + /* receive whisper on recipient's account */ + serv_got_chat_in(gc, id, who, PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_WHISPER, + message, time(NULL)); +} + +static void receive_chat_message(PurpleConvChat *from, PurpleConvChat *to, + int id, const char *room, gpointer userdata) { + const char *message = (const char *)userdata; + PurpleConnection *to_gc = get_nullprpl_gc(to->nick); + + purple_debug_info("nullprpl", + "%s receives message from %s in chat room %s: %s\n", + to->nick, from->nick, room, message); + serv_got_chat_in(to_gc, id, from->nick, PURPLE_MESSAGE_RECV, message, + time(NULL)); +} + +static int nullprpl_chat_send(PurpleConnection *gc, int id, const char *message, + PurpleMessageFlags flags) { + char *username = gc->account->username; + PurpleConversation *conv = purple_find_chat(gc, id); + + if (conv) { + purple_debug_info("nullprpl", + "%s is sending message to chat room %s: %s\n", username, + conv->name, message); + + /* send message to everyone in the chat room */ + foreach_gc_in_chat(receive_chat_message, gc, id, (gpointer)message); + return 0; + } else { + purple_debug_info("nullprpl", + "tried to send message from %s to chat room #%d: %s\n" + "but couldn't find chat room", + username, id, message); + return -1; + } +} + +static void nullprpl_register_user(PurpleAccount *acct) { + purple_debug_info("nullprpl", "registering account for %s\n", + acct->username); +} + +static void nullprpl_get_cb_info(PurpleConnection *gc, int id, const char *who) { + PurpleConversation *conv = purple_find_chat(gc, id); + purple_debug_info("nullprpl", + "retrieving %s's info for %s in chat room %s\n", who, + gc->account->username, conv->name); + + nullprpl_get_info(gc, who); +} + +static void nullprpl_alias_buddy(PurpleConnection *gc, const char *who, + const char *alias) { + purple_debug_info("nullprpl", "%s sets %'s alias to %s\n", + gc->account->username, who, alias); +} + +static void nullprpl_group_buddy(PurpleConnection *gc, const char *who, + const char *old_group, + const char *new_group) { + purple_debug_info("nullprpl", "%s has moved %s from group %s to group %s\n", + who, old_group, new_group); +} + +static void nullprpl_rename_group(PurpleConnection *gc, const char *old_name, + PurpleGroup *group, GList *moved_buddies) { + purple_debug_info("nullprpl", "%s has renamed group %s to %s\n", + gc->account->username, old_name, group->name); +} + +static void nullprpl_convo_closed(PurpleConnection *gc, const char *who) { + purple_debug_info("nullprpl", "%s's conversation with %s was closed\n", + gc->account->username, who); +} + +/* normalize a username (e.g. remove whitespace, add default domain, etc.) + * for nullprpl, this is a noop. + */ +static const char *nullprpl_normalize(const PurpleAccount *acct, + const char *input) { + return NULL; +} + +static void nullprpl_set_buddy_icon(PurpleConnection *gc, + PurpleStoredImage *img) { + purple_debug_info("nullprpl", "setting %s's buddy icon to %s\n", + gc->account->username, purple_imgstore_get_filename(img)); +} + +static void nullprpl_remove_group(PurpleConnection *gc, PurpleGroup *group) { + purple_debug_info("nullprpl", "%s has removed group %s\n", + gc->account->username, group->name); +} + + +static void set_chat_topic_fn(PurpleConvChat *from, PurpleConvChat *to, + int id, const char *room, gpointer userdata) { + const char *topic = (const char *)userdata; + const char *username = from->conv->account->username; + char *msg; + + purple_conv_chat_set_topic(to, username, topic); + + if (topic && strlen(topic) > 0) + msg = g_strdup_printf(_("%s sets topic to: %s"), username, topic); + else + msg = g_strdup_printf(_("%s clears topic"), username); + + purple_conv_chat_write(to, username, msg, + PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, + time(NULL)); + g_free(msg); +} + +static void nullprpl_set_chat_topic(PurpleConnection *gc, int id, + const char *topic) { + PurpleConversation *conv = purple_find_chat(gc, id); + PurpleConvChat *chat = purple_conversation_get_chat_data(conv); + const char *last_topic; + + if (!chat) + return; + + purple_debug_info("nullprpl", "%s sets topic of chat room '%s' to '%s'\n", + gc->account->username, conv->name, topic); + + last_topic = purple_conv_chat_get_topic(chat); + if ((!topic && !last_topic) || + (topic && last_topic && !strcmp(topic, last_topic))) + return; /* topic is unchanged, this is a noop */ + + foreach_gc_in_chat(set_chat_topic_fn, gc, id, (gpointer)topic); +} + +static gboolean nullprpl_finish_get_roomlist(gpointer roomlist) { + purple_roomlist_set_in_progress((PurpleRoomlist *)roomlist, FALSE); + return FALSE; +} + +static PurpleRoomlist *nullprpl_roomlist_get_list(PurpleConnection *gc) { + char *username = gc->account->username; + PurpleRoomlist *roomlist = purple_roomlist_new(gc->account); + GList *fields = NULL; + PurpleRoomlistField *field; + GList *chats; + GList *seen_ids = NULL; + + purple_debug_info("nullprpl", "%s asks for room list; returning:\n", username); + + /* set up the room list */ + field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "room", + "room", TRUE /* hidden */); + fields = g_list_append(fields, field); + + field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, "Id", "Id", FALSE); + fields = g_list_append(fields, field); + + purple_roomlist_set_fields(roomlist, fields); + + /* add each chat room. the chat ids are cached in seen_ids so that each room + * is only returned once, even if multiple users are in it. */ + for (chats = purple_get_chats(); chats; chats = g_list_next(chats)) { + PurpleConversation *conv = (PurpleConversation *)chats->data; + PurpleRoomlistRoom *room; + char *name = conv->name; + int id = purple_conversation_get_chat_data(conv)->id; + + /* have we already added this room? */ + if (g_list_find_custom(seen_ids, name, (GCompareFunc)strcmp)) + continue; /* yes! try the next one. */ + + seen_ids = g_list_append(seen_ids, name); /* no, it's new. */ + purple_debug_info("nullprpl", "%s (%d), ", name, id); + + room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); + purple_roomlist_room_add_field(roomlist, room, name); + purple_roomlist_room_add_field(roomlist, room, &id); + purple_roomlist_room_add(roomlist, room); + } + + purple_timeout_add(1 /* ms */, nullprpl_finish_get_roomlist, roomlist); + return roomlist; +} + +static void nullprpl_roomlist_cancel(PurpleRoomlist *list) { + purple_debug_info("nullprpl", "%s asked to cancel room list request\n", + list->account->username); +} + +static void nullprpl_roomlist_expand_category(PurpleRoomlist *list, + PurpleRoomlistRoom *category) { + purple_debug_info("nullprpl", "%s asked to expand room list category %s\n", + list->account->username, category->name); +} + +/* nullprpl doesn't support file transfer...yet... */ +static gboolean nullprpl_can_receive_file(PurpleConnection *gc, + const char *who) { + return FALSE; +} + +static gboolean nullprpl_offline_message(const PurpleBuddy *buddy) { + purple_debug_info("nullprpl", + "reporting that offline messages are supported for %s\n", + buddy->name); + return TRUE; +} + + +/* + * prpl stuff. see prpl.h for more information. + */ + +static PurplePluginProtocolInfo prpl_info = +{ + OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC, /* options */ + NULL, /* user_splits, initialized in nullprpl_init() */ + NULL, /* protocol_options, initialized in nullprpl_init() */ + { /* icon_spec, a PurpleBuddyIconSpec */ + "png,jpg,gif", /* format */ + 0, /* min_width */ + 0, /* min_height */ + 128, /* max_width */ + 128, /* max_height */ + 10000, /* max_filesize */ + PURPLE_ICON_SCALE_DISPLAY, /* scale_rules */ + }, + nullprpl_list_icon, /* list_icon */ + nullprpl_list_emblem, /* list_emblem */ + nullprpl_status_text, /* status_text */ + nullprpl_tooltip_text, /* tooltip_text */ + nullprpl_status_types, /* status_types */ + nullprpl_blist_node_menu, /* blist_node_menu */ + nullprpl_chat_info, /* chat_info */ + nullprpl_chat_info_defaults, /* chat_info_defaults */ + nullprpl_login, /* login */ + nullprpl_close, /* close */ + nullprpl_send_im, /* send_im */ + nullprpl_set_info, /* set_info */ + nullprpl_send_typing, /* send_typing */ + nullprpl_get_info, /* get_info */ + nullprpl_set_status, /* set_status */ + nullprpl_set_idle, /* set_idle */ + nullprpl_change_passwd, /* change_passwd */ + nullprpl_add_buddy, /* add_buddy */ + nullprpl_add_buddies, /* add_buddies */ + nullprpl_remove_buddy, /* remove_buddy */ + nullprpl_remove_buddies, /* remove_buddies */ + nullprpl_add_permit, /* add_permit */ + nullprpl_add_deny, /* add_deny */ + nullprpl_rem_permit, /* rem_permit */ + nullprpl_rem_deny, /* rem_deny */ + nullprpl_set_permit_deny, /* set_permit_deny */ + nullprpl_join_chat, /* join_chat */ + nullprpl_reject_chat, /* reject_chat */ + nullprpl_get_chat_name, /* get_chat_name */ + nullprpl_chat_invite, /* chat_invite */ + nullprpl_chat_leave, /* chat_leave */ + nullprpl_chat_whisper, /* chat_whisper */ + nullprpl_chat_send, /* chat_send */ + NULL, /* keepalive */ + nullprpl_register_user, /* register_user */ + nullprpl_get_cb_info, /* get_cb_info */ + NULL, /* get_cb_away */ + nullprpl_alias_buddy, /* alias_buddy */ + nullprpl_group_buddy, /* group_buddy */ + nullprpl_rename_group, /* rename_group */ + NULL, /* buddy_free */ + nullprpl_convo_closed, /* convo_closed */ + nullprpl_normalize, /* normalize */ + nullprpl_set_buddy_icon, /* set_buddy_icon */ + nullprpl_remove_group, /* remove_group */ + NULL, /* get_cb_real_name */ + nullprpl_set_chat_topic, /* set_chat_topic */ + NULL, /* find_blist_chat */ + nullprpl_roomlist_get_list, /* roomlist_get_list */ + nullprpl_roomlist_cancel, /* roomlist_cancel */ + nullprpl_roomlist_expand_category, /* roomlist_expand_category */ + nullprpl_can_receive_file, /* can_receive_file */ + NULL, /* send_file */ + NULL, /* new_xfer */ + nullprpl_offline_message, /* offline_message */ + NULL, /* whiteboard_prpl_ops */ + NULL, /* send_raw */ + NULL, /* roomlist_room_serialize */ + NULL, /* padding... */ + NULL, + NULL, + NULL, +}; + +static void nullprpl_init(PurplePlugin *plugin) +{ + /* see accountopt.h for information about user splits and protocol options */ + PurpleAccountUserSplit *split = purple_account_user_split_new( + _("Example user split (unused)"), /* text shown to user */ + "default", /* default value */ + '@'); /* field separator */ + PurpleAccountOption *option = purple_account_option_string_new( + _("Example option (unused)"), /* text shown to user */ + "example", /* pref name */ + "default"); /* default value */ + + purple_debug_info("nullprpl", "starting up\n"); + + prpl_info.user_splits = g_list_append(NULL, split); + prpl_info.protocol_options = g_list_append(NULL, option); + + /* register whisper chat command, /msg */ + purple_cmd_register("msg", + "ws", /* args: recipient and message */ + PURPLE_CMD_P_DEFAULT, /* priority */ + PURPLE_CMD_FLAG_CHAT, + "prpl-null", + send_whisper, + "msg <username> <message>: send a private message, aka a whisper", + NULL); /* userdata */ + + /* get ready to store offline messages */ + goffline_messages = g_hash_table_new_full(g_str_hash, /* hash fn */ + g_str_equal, /* key comparison fn */ + g_free, /* key free fn */ + NULL); /* value free fn */ + + _null_protocol = plugin; +} + +static void nullprpl_destroy(PurplePlugin *plugin) { + purple_debug_info("nullprpl", "shutting down\n"); +} + + +static PurplePluginInfo info = +{ + PURPLE_PLUGIN_MAGIC, /* magic */ + PURPLE_MAJOR_VERSION, /* major_version */ + PURPLE_MINOR_VERSION, /* minor_version */ + PURPLE_PLUGIN_PROTOCOL, /* type */ + NULL, /* ui_requirement */ + 0, /* flags */ + NULL, /* dependencies */ + PURPLE_PRIORITY_DEFAULT, /* priority */ + NULLPRPL_ID, /* id */ + "Nullprpl", /* name */ + "0.3", /* version */ + "Null Protocol Plugin", /* summary */ + "Null Protocol Plugin", /* description */ + "Ryan Barrett <nullprpl@ryanb.org>", /* author */ + "http://snarfed.org/space/pidgin+null+protocol+plugin", /* homepage */ + NULL, /* load */ + NULL, /* unload */ + nullprpl_destroy, /* destroy */ + NULL, /* ui_info */ + &prpl_info, /* extra_info */ + NULL, /* prefs_info */ + nullprpl_actions, /* actions */ + NULL, /* padding... */ + NULL, + NULL, + NULL, +}; + +PURPLE_INIT_PLUGIN(null, nullprpl_init, info);
--- a/libpurple/protocols/oscar/family_admin.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_admin.c Fri Jun 01 23:53:05 2007 +0000 @@ -125,17 +125,17 @@ { FlapFrame *fr; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; fr = flap_frame_new(od, 0x02, 10+2+2+strlen(newnick)); snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); - aim_tlvlist_add_str(&tl, 0x0001, newnick); + aim_tlvlist_add_str(&tlvlist, 0x0001, newnick); - aim_tlvlist_write(&fr->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, fr); @@ -151,7 +151,7 @@ aim_admin_changepasswd(OscarData *od, FlapConnection *conn, const char *newpw, const char *curpw) { FlapFrame *fr; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; aim_snacid_t snacid; fr = flap_frame_new(od, 0x02, 10+4+strlen(curpw)+4+strlen(newpw)); @@ -160,13 +160,13 @@ aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); /* new password TLV t(0002) */ - aim_tlvlist_add_str(&tl, 0x0002, newpw); + aim_tlvlist_add_str(&tlvlist, 0x0002, newpw); /* current password TLV t(0012) */ - aim_tlvlist_add_str(&tl, 0x0012, curpw); + aim_tlvlist_add_str(&tlvlist, 0x0012, curpw); - aim_tlvlist_write(&fr->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, fr); @@ -182,17 +182,17 @@ { FlapFrame *fr; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; fr = flap_frame_new(od, 0x02, 10+2+2+strlen(newemail)); snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); - aim_tlvlist_add_str(&tl, 0x0011, newemail); + aim_tlvlist_add_str(&tlvlist, 0x0011, newemail); - aim_tlvlist_write(&fr->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, fr); @@ -223,17 +223,17 @@ int ret = 0; aim_rxcallback_t userfunc; guint16 status; - /* aim_tlvlist_t *tl; */ + /* GSList *tlvlist; */ status = byte_stream_get16(bs); /* Status is 0x0013 if unable to confirm at this time */ - /* tl = aim_tlvlist_read(bs); */ + /* tlvlist = aim_tlvlist_read(bs); */ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, status); - /* aim_tlvlist_free(&tl); */ + /* aim_tlvlist_free(tlvlist); */ return ret; }
--- a/libpurple/protocols/oscar/family_alert.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_alert.c Fri Jun 01 23:53:05 2007 +0000 @@ -98,7 +98,7 @@ int ret = 0; aim_rxcallback_t userfunc; struct aim_emailinfo *new; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; guint8 *cookie8, *cookie16; int tmp, havenewmail = 0; /* Used to tell the client we have _new_ mail */ @@ -152,7 +152,7 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, new, havenewmail, alertitle, (alerturl ? alerturl + 2 : NULL)); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); g_free(alertitle); g_free(alerturl);
--- a/libpurple/protocols/oscar/family_auth.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_auth.c Fri Jun 01 23:53:05 2007 +0000 @@ -129,7 +129,7 @@ goddamnicq2(OscarData *od, FlapConnection *conn, const char *sn, const char *password, ClientInfo *ci) { FlapFrame *frame; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; int passwdlen; guint8 *password_encoded; @@ -143,24 +143,24 @@ aim_encode_password(password, password_encoded); byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */ - aim_tlvlist_add_str(&tl, 0x0001, sn); - aim_tlvlist_add_raw(&tl, 0x0002, passwdlen, password_encoded); + aim_tlvlist_add_str(&tlvlist, 0x0001, sn); + aim_tlvlist_add_raw(&tlvlist, 0x0002, passwdlen, password_encoded); if (ci->clientstring) - aim_tlvlist_add_str(&tl, 0x0003, ci->clientstring); - aim_tlvlist_add_16(&tl, 0x0016, (guint16)ci->clientid); - aim_tlvlist_add_16(&tl, 0x0017, (guint16)ci->major); - aim_tlvlist_add_16(&tl, 0x0018, (guint16)ci->minor); - aim_tlvlist_add_16(&tl, 0x0019, (guint16)ci->point); - aim_tlvlist_add_16(&tl, 0x001a, (guint16)ci->build); - aim_tlvlist_add_32(&tl, 0x0014, (guint32)ci->distrib); /* distribution chan */ - aim_tlvlist_add_str(&tl, 0x000f, ci->lang); - aim_tlvlist_add_str(&tl, 0x000e, ci->country); + aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring); + aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid); + aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major); + aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor); + aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point); + aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build); + aim_tlvlist_add_32(&tlvlist, 0x0014, (guint32)ci->distrib); /* distribution chan */ + aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang); + aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country); - aim_tlvlist_write(&frame->data, &tl); + aim_tlvlist_write(&frame->data, &tlvlist); g_free(password_encoded); - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -201,7 +201,7 @@ aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key) { FlapFrame *frame; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; guint8 digest[16]; aim_snacid_t snacid; size_t password_len; @@ -220,7 +220,7 @@ snacid = aim_cachesnac(od, 0x0017, 0x0002, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0017, 0x0002, 0x0000, snacid); - aim_tlvlist_add_str(&tl, 0x0001, sn); + aim_tlvlist_add_str(&tlvlist, 0x0001, sn); /* Truncate ICQ and AOL passwords, if necessary */ password_len = strlen(password); @@ -231,32 +231,32 @@ aim_encode_password_md5(password, password_len, key, digest); - aim_tlvlist_add_raw(&tl, 0x0025, 16, digest); + aim_tlvlist_add_raw(&tlvlist, 0x0025, 16, digest); #ifndef USE_OLD_MD5 - aim_tlvlist_add_noval(&tl, 0x004c); + aim_tlvlist_add_noval(&tlvlist, 0x004c); #endif if (ci->clientstring) - aim_tlvlist_add_str(&tl, 0x0003, ci->clientstring); - aim_tlvlist_add_16(&tl, 0x0016, (guint16)ci->clientid); - aim_tlvlist_add_16(&tl, 0x0017, (guint16)ci->major); - aim_tlvlist_add_16(&tl, 0x0018, (guint16)ci->minor); - aim_tlvlist_add_16(&tl, 0x0019, (guint16)ci->point); - aim_tlvlist_add_16(&tl, 0x001a, (guint16)ci->build); - aim_tlvlist_add_32(&tl, 0x0014, (guint32)ci->distrib); - aim_tlvlist_add_str(&tl, 0x000f, ci->lang); - aim_tlvlist_add_str(&tl, 0x000e, ci->country); + aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring); + aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid); + aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major); + aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor); + aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point); + aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build); + aim_tlvlist_add_32(&tlvlist, 0x0014, (guint32)ci->distrib); + aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang); + aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country); /* * If set, old-fashioned buddy lists will not work. You will need * to use SSI. */ - aim_tlvlist_add_8(&tl, 0x004a, 0x01); + aim_tlvlist_add_8(&tlvlist, 0x004a, 0x01); - aim_tlvlist_write(&frame->data, &tl); + aim_tlvlist_write(&frame->data, &tlvlist); - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -274,7 +274,7 @@ static int parse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_rxcallback_t userfunc; struct aim_authresp_info *info; int ret = 0; @@ -402,7 +402,7 @@ if ((userfunc = aim_callhandler(od, snac ? snac->family : 0x0017, snac ? snac->subtype : 0x0003))) ret = userfunc(od, conn, frame, info); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -471,7 +471,7 @@ { FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !conn || !sn) return -EINVAL; @@ -486,16 +486,16 @@ snacid = aim_cachesnac(od, 0x0017, 0x0006, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0017, 0x0006, 0x0000, snacid); - aim_tlvlist_add_str(&tl, 0x0001, sn); + aim_tlvlist_add_str(&tlvlist, 0x0001, sn); /* Tell the server we support SecurID logins. */ - aim_tlvlist_add_noval(&tl, 0x004b); + aim_tlvlist_add_noval(&tlvlist, 0x004b); /* Unknown. Sent in recent WinAIM clients.*/ - aim_tlvlist_add_noval(&tl, 0x005a); + aim_tlvlist_add_noval(&tlvlist, 0x005a); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -517,7 +517,7 @@ int keylen, ret = 1; aim_rxcallback_t userfunc; char *keystr; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; gboolean truncate_pass; keylen = byte_stream_get16(bs); @@ -539,7 +539,7 @@ ret = userfunc(od, conn, frame, keystr, (int)truncate_pass); g_free(keystr); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_bos.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_bos.c Fri Jun 01 23:53:05 2007 +0000 @@ -39,7 +39,7 @@ static int rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { aim_rxcallback_t userfunc; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; guint16 maxpermits = 0, maxdenies = 0; int ret = 0; @@ -63,7 +63,7 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, maxpermits, maxdenies); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_buddy.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Fri Jun 01 23:53:05 2007 +0000 @@ -47,7 +47,7 @@ rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { aim_rxcallback_t userfunc; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; guint16 maxbuddies = 0, maxwatchers = 0; int ret = 0; @@ -82,7 +82,7 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, maxbuddies, maxwatchers); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_chat.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_chat.c Fri Jun 01 23:53:05 2007 +0000 @@ -159,7 +159,7 @@ char *roomname; struct aim_chat_roominfo roominfo; guint16 tlvcount = 0; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_tlv_t *tlv; char *roomdesc; guint16 flags; @@ -309,7 +309,7 @@ g_free(userinfo); g_free(roomname); g_free(roomdesc); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -357,7 +357,7 @@ IcbmCookie *cookie; aim_snacid_t snacid; guint8 ckstr[8]; - aim_tlvlist_t *tlvlist = NULL, *inner_tlvlist = NULL; + GSList *tlvlist = NULL, *inner_tlvlist = NULL; if (!od || !conn || !msg || (msglen <= 0)) return 0; @@ -430,8 +430,8 @@ aim_tlvlist_write(&frame->data, &tlvlist); - aim_tlvlist_free(&inner_tlvlist); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -471,7 +471,7 @@ aim_userinfo_t userinfo; guint8 cookie[8]; guint16 channel; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; char *msg = NULL; int len = 0; char *encoding = NULL, *language = NULL; @@ -536,7 +536,7 @@ tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1); if (tlv != NULL) { - aim_tlvlist_t *inner_tlvlist; + GSList *inner_tlvlist; aim_tlv_t *inner_tlv; byte_stream_init(&tbs, tlv->value, tlv->length); @@ -562,7 +562,7 @@ */ language = aim_tlv_getstr(inner_tlvlist, 0x0003, 1); - aim_tlvlist_free(&inner_tlvlist); + aim_tlvlist_free(inner_tlvlist); } if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) @@ -572,7 +572,7 @@ g_free(msg); g_free(encoding); g_free(language); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_chatnav.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_chatnav.c Fri Jun 01 23:53:05 2007 +0000 @@ -50,7 +50,7 @@ static const char charset[] = {"us-ascii"}; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; frame = flap_frame_new(od, 0x02, 1152); @@ -85,15 +85,15 @@ /* detail level */ byte_stream_put8(&frame->data, 0x01); - aim_tlvlist_add_str(&tl, 0x00d3, name); - aim_tlvlist_add_str(&tl, 0x00d6, charset); - aim_tlvlist_add_str(&tl, 0x00d7, lang); + aim_tlvlist_add_str(&tlvlist, 0x00d3, name); + aim_tlvlist_add_str(&tlvlist, 0x00d6, charset); + aim_tlvlist_add_str(&tlvlist, 0x00d7, lang); /* tlvcount */ - byte_stream_put16(&frame->data, aim_tlvlist_count(&tl)); - aim_tlvlist_write(&frame->data, &tl); + byte_stream_put16(&frame->data, aim_tlvlist_count(tlvlist)); + aim_tlvlist_write(&frame->data, &tlvlist); - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -109,7 +109,7 @@ int curexchange; aim_tlv_t *exchangetlv; guint8 maxrooms = 0; - aim_tlvlist_t *tlvlist, *innerlist; + GSList *tlvlist, *innerlist; tlvlist = aim_tlvlist_read(bs); @@ -290,7 +290,7 @@ } #endif - aim_tlvlist_free(&innerlist); + aim_tlvlist_free(innerlist); } /* @@ -307,7 +307,7 @@ g_free(exchanges[curexchange].lang2); } g_free(exchanges); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -316,7 +316,7 @@ parseinfo_create(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs, aim_snac_t *snac2) { aim_rxcallback_t userfunc; - aim_tlvlist_t *tlvlist, *innerlist; + GSList *tlvlist, *innerlist; char *ck = NULL, *fqcn = NULL, *name = NULL; guint16 exchange = 0, instance = 0, unknown = 0, flags = 0, maxmsglen = 0, maxoccupancy = 0; guint32 createtime = 0; @@ -330,7 +330,7 @@ if (!(bigblock = aim_tlv_gettlv(tlvlist, 0x0004, 1))) { purple_debug_misc("oscar", "no bigblock in top tlv in create room response\n"); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return 0; } @@ -344,7 +344,7 @@ if (detaillevel != 0x02) { purple_debug_misc("oscar", "unknown detaillevel in create room response (0x%02x)\n", detaillevel); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); g_free(ck); return 0; } @@ -381,8 +381,8 @@ g_free(ck); g_free(name); g_free(fqcn); - aim_tlvlist_free(&innerlist); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(innerlist); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_feedbag.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Fri Jun 01 23:53:05 2007 +0000 @@ -110,7 +110,7 @@ * @param data The additional data for the new item. * @return A pointer to the newly created item. */ -static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, aim_tlvlist_t *data) +static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data) { gboolean exists; struct aim_ssi_item *cur, *new; @@ -214,7 +214,7 @@ /* Free the removed item */ g_free(del->name); - aim_tlvlist_free(&del->data); + aim_tlvlist_free(del->data); g_free(del); return 0; @@ -610,7 +610,7 @@ del = cur; cur = cur->next; g_free(del->name); - aim_tlvlist_free(&del->data); + aim_tlvlist_free(del->data); g_free(del); } @@ -619,7 +619,7 @@ del = cur; cur = cur->next; g_free(del->name); - aim_tlvlist_free(&del->data); + aim_tlvlist_free(del->data); g_free(del); } @@ -670,7 +670,7 @@ aim_ssi_deldeny(od, NULL); } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) { char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name); - aim_ssi_addbuddy(od, cur->name, "orphans", alias, NULL, NULL, 0); + aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE); aim_ssi_delbuddy(od, cur->name, NULL); g_free(alias); } @@ -721,15 +721,15 @@ * @param od The oscar odion. * @param name The name of the item. * @param group The group of the item. + * @param data A TLV list to use as the additional data for this item. * @param alias The alias/nickname of the item, or NULL. * @param comment The buddy comment for the item, or NULL. * @param smsnum The locally assigned SMS number, or NULL. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth) +int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *data, const char *alias, const char *comment, const char *smsnum, gboolean needauth) { struct aim_ssi_item *parent; - aim_tlvlist_t *data = NULL; if (!od || !name || !group) return -EINVAL; @@ -750,16 +750,16 @@ /* Create a TLV list for the new buddy */ if (needauth) aim_tlvlist_add_noval(&data, 0x0066); - if (alias) + if (alias != NULL) aim_tlvlist_add_str(&data, 0x0131, alias); - if (smsnum) + if (smsnum != NULL) aim_tlvlist_add_str(&data, 0x013a, smsnum); - if (comment) + if (comment != NULL) aim_tlvlist_add_str(&data, 0x013c, comment); /* Add that bad boy */ aim_ssi_itemlist_add(&od->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); - aim_tlvlist_free(&data); + aim_tlvlist_free(data); /* Modify the parent group */ aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); @@ -920,16 +920,22 @@ */ int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn) { - char *alias; - gboolean waitingforauth; + struct aim_ssi_item *buddy; + GSList *data; + + /* Find the buddy */ + buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, sn, AIM_SSI_TYPE_BUDDY); + if (buddy == NULL) + return -EINVAL; - alias = aim_ssi_getalias(od->ssi.local, oldgn, sn); - waitingforauth = aim_ssi_waitingforauth(od->ssi.local, oldgn, sn); + /* Make a copy of the buddy's TLV list */ + data = aim_tlvlist_copy(buddy->data); + /* Delete the old item */ aim_ssi_delbuddy(od, sn, oldgn); - aim_ssi_addbuddy(od, sn, newgn, alias, NULL, NULL, waitingforauth); - g_free(alias); + /* Add the new item using the EXACT SAME TLV list */ + aim_ssi_addbuddy(od, sn, newgn, data, NULL, NULL, NULL, FALSE); return 0; } @@ -1172,7 +1178,7 @@ { int ret = 0, i; aim_rxcallback_t userfunc; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_tlv_t *tlv; ByteStream bstream; guint16 *maxitems; @@ -1182,7 +1188,7 @@ /* TLV 0x0004 contains the maximum number of each item */ if (!(tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) { - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return 0; } @@ -1196,7 +1202,7 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, tlv->length/2, maxitems); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); g_free(maxitems); return ret; @@ -1267,7 +1273,7 @@ guint8 fmtver; /* guess */ guint16 namelen, gid, bid, type; char *name; - aim_tlvlist_t *data; + GSList *data; fmtver = byte_stream_get8(bs); /* Version of ssi data. Should be 0x00 */ od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */ @@ -1284,7 +1290,7 @@ data = aim_tlvlist_readlen(bs, byte_stream_get16(bs)); aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data); g_free(name); - aim_tlvlist_free(&data); + aim_tlvlist_free(data); } /* Read in the timestamp */ @@ -1352,7 +1358,7 @@ if (cur->item->name) snaclen += strlen(cur->item->name); if (cur->item->data) - snaclen += aim_tlvlist_size(&cur->item->data); + snaclen += aim_tlvlist_size(cur->item->data); } frame = flap_frame_new(od, 0x02, snaclen); @@ -1367,7 +1373,7 @@ byte_stream_put16(&frame->data, cur->item->gid); byte_stream_put16(&frame->data, cur->item->bid); byte_stream_put16(&frame->data, cur->item->type); - byte_stream_put16(&frame->data, cur->item->data ? aim_tlvlist_size(&cur->item->data) : 0); + byte_stream_put16(&frame->data, cur->item->data ? aim_tlvlist_size(cur->item->data) : 0); if (cur->item->data) aim_tlvlist_write(&frame->data, &cur->item->data); } @@ -1389,7 +1395,7 @@ aim_rxcallback_t userfunc; char *name; guint16 len, gid, bid, type; - aim_tlvlist_t *data; + GSList *data; while (byte_stream_empty(bs)) { if ((len = byte_stream_get16(bs))) @@ -1406,7 +1412,7 @@ aim_ssi_itemlist_add(&od->ssi.local, name, gid, bid, type, data); aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data); - aim_tlvlist_free(&data); + aim_tlvlist_free(data); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, type, name); @@ -1428,7 +1434,7 @@ aim_rxcallback_t userfunc; char *name; guint16 len, gid, bid, type; - aim_tlvlist_t *data; + GSList *data; struct aim_ssi_item *item; while (byte_stream_empty(bs)) { @@ -1453,7 +1459,7 @@ strcpy(item->name, name); } else item->name = NULL; - aim_tlvlist_free(&item->data); + aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } @@ -1465,7 +1471,7 @@ strcpy(item->name, name); } else item->name = NULL; - aim_tlvlist_free(&item->data); + aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } @@ -1473,7 +1479,7 @@ ret = userfunc(od, conn, frame); g_free(name); - aim_tlvlist_free(&data); + aim_tlvlist_free(data); } return ret; @@ -1561,7 +1567,7 @@ strcpy(cur->item->name, cur1->name); } else cur->item->name = NULL; - aim_tlvlist_free(&cur->item->data); + aim_tlvlist_free(cur->item->data); cur->item->data = aim_tlvlist_copy(cur1->data); } } else @@ -1595,7 +1601,7 @@ strcpy(cur1->name, cur->item->name); } else cur1->name = NULL; - aim_tlvlist_free(&cur1->data); + aim_tlvlist_free(cur1->data); cur1->data = aim_tlvlist_copy(cur->item->data); } } else
--- a/libpurple/protocols/oscar/family_icbm.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Fri Jun 01 23:53:05 2007 +0000 @@ -451,7 +451,7 @@ IcbmCookie *msgcookie; struct aim_invite_priv *priv; guchar cookie[8]; - aim_tlvlist_t *otl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) @@ -498,19 +498,19 @@ byte_stream_putraw(&hdrbs, cookie, sizeof(cookie)); /* I think... */ byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_CHAT); - aim_tlvlist_add_16(&itl, 0x000a, 0x0001); - aim_tlvlist_add_noval(&itl, 0x000f); - aim_tlvlist_add_str(&itl, 0x000c, msg); - aim_tlvlist_add_chatroom(&itl, 0x2711, exchange, roomname, instance); - aim_tlvlist_write(&hdrbs, &itl); - - aim_tlvlist_add_raw(&otl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, 0x0001); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); + aim_tlvlist_add_str(&inner_tlvlist, 0x000c, msg); + aim_tlvlist_add_chatroom(&inner_tlvlist, 0x2711, exchange, roomname, instance); + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &otl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&otl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); @@ -689,7 +689,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; od = peer_conn->od; @@ -705,7 +705,7 @@ /* ICBM header */ aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn); - aim_tlvlist_add_noval(&tl, 0x0003); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); byte_stream_new(&hdrbs, 64); @@ -714,16 +714,16 @@ byte_stream_putcaps(&hdrbs, peer_conn->type); /* This TLV means "cancel!" */ - aim_tlvlist_add_16(&itl, 0x000b, 0x0001); - aim_tlvlist_write(&hdrbs, &itl); - - aim_tlvlist_add_raw(&tl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_add_16(&inner_tlvlist, 0x000b, 0x0001); + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &tl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); } @@ -775,7 +775,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; conn = flap_connection_findbygroup(od, 0x0004); @@ -790,7 +790,7 @@ /* ICBM header */ aim_im_puticbm(&frame->data, cookie, 0x0002, sn); - aim_tlvlist_add_noval(&tl, 0x0003); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); byte_stream_new(&hdrbs, 128); @@ -798,20 +798,20 @@ byte_stream_putraw(&hdrbs, cookie, 8); byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_DIRECTIM); - aim_tlvlist_add_raw(&itl, 0x0002, 4, ip); - aim_tlvlist_add_raw(&itl, 0x0003, 4, ip); - aim_tlvlist_add_16(&itl, 0x0005, port); - aim_tlvlist_add_16(&itl, 0x000a, requestnumber); - aim_tlvlist_add_noval(&itl, 0x000f); - aim_tlvlist_write(&hdrbs, &itl); - - aim_tlvlist_add_raw(&tl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip); + aim_tlvlist_add_16(&inner_tlvlist, 0x0005, port); + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &tl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); } @@ -826,7 +826,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; guint8 ip_comp[4]; @@ -842,7 +842,7 @@ /* ICBM header */ aim_im_puticbm(&frame->data, cookie, 0x0002, sn); - aim_tlvlist_add_noval(&tl, 0x0003); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); byte_stream_new(&hdrbs, 128); @@ -850,30 +850,30 @@ byte_stream_putraw(&hdrbs, cookie, 8); byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_DIRECTIM); - aim_tlvlist_add_raw(&itl, 0x0002, 4, ip); - aim_tlvlist_add_raw(&itl, 0x0003, 4, ip); - aim_tlvlist_add_16(&itl, 0x0005, pin); - aim_tlvlist_add_16(&itl, 0x000a, requestnumber); - aim_tlvlist_add_noval(&itl, 0x000f); - aim_tlvlist_add_noval(&itl, 0x0010); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip); + aim_tlvlist_add_16(&inner_tlvlist, 0x0005, pin); + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); + aim_tlvlist_add_noval(&inner_tlvlist, 0x0010); /* Send the bitwise complement of the port and ip. As a check? */ ip_comp[0] = ~ip[0]; ip_comp[1] = ~ip[1]; ip_comp[2] = ~ip[2]; ip_comp[3] = ~ip[3]; - aim_tlvlist_add_raw(&itl, 0x0016, 4, ip_comp); - aim_tlvlist_add_16(&itl, 0x0017, ~pin); - - aim_tlvlist_write(&hdrbs, &itl); - - aim_tlvlist_add_raw(&tl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0016, 4, ip_comp); + aim_tlvlist_add_16(&inner_tlvlist, 0x0017, ~pin); + + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &tl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); } @@ -888,7 +888,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; conn = flap_connection_findbygroup(od, 0x0004); @@ -903,7 +903,7 @@ /* ICBM header */ aim_im_puticbm(&frame->data, cookie, 0x0002, sn); - aim_tlvlist_add_noval(&tl, 0x0003); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); byte_stream_new(&hdrbs, 512); @@ -911,11 +911,11 @@ byte_stream_putraw(&hdrbs, cookie, 8); byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_SENDFILE); - aim_tlvlist_add_raw(&itl, 0x0002, 4, ip); - aim_tlvlist_add_raw(&itl, 0x0003, 4, ip); - aim_tlvlist_add_16(&itl, 0x0005, port); - aim_tlvlist_add_16(&itl, 0x000a, requestnumber); - aim_tlvlist_add_noval(&itl, 0x000f); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip); + aim_tlvlist_add_16(&inner_tlvlist, 0x0005, port); + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); /* TODO: Send 0x0016 and 0x0017 */ #if 0 @@ -924,9 +924,9 @@ * redirect for a file receive (same conditions for * sending 0x000f above) */ - aim_tlvlist_add_raw(&itl, 0x000e, 2, "en"); - aim_tlvlist_add_raw(&itl, 0x000d, 8, "us-ascii"); - aim_tlvlist_add_raw(&itl, 0x000c, 24, "Please accept this file."); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en"); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii"); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file."); #endif if (filename != NULL) @@ -943,19 +943,19 @@ byte_stream_putstr(&bs, filename); byte_stream_put8(&bs, 0x00); - aim_tlvlist_add_raw(&itl, 0x2711, bs.len, bs.data); + aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data); g_free(bs.data); /* End TLV t(2711) */ } - aim_tlvlist_write(&hdrbs, &itl); - aim_tlvlist_add_raw(&tl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &tl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); } @@ -970,7 +970,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL, *itl = NULL; + GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; guint8 ip_comp[4]; @@ -986,7 +986,7 @@ /* ICBM header */ aim_im_puticbm(&frame->data, cookie, 0x0002, sn); - aim_tlvlist_add_noval(&tl, 0x0003); + aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); byte_stream_new(&hdrbs, 512); @@ -994,20 +994,20 @@ byte_stream_putraw(&hdrbs, cookie, 8); byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_SENDFILE); - aim_tlvlist_add_raw(&itl, 0x0002, 4, ip); - aim_tlvlist_add_raw(&itl, 0x0003, 4, ip); - aim_tlvlist_add_16(&itl, 0x0005, pin); - aim_tlvlist_add_16(&itl, 0x000a, requestnumber); - aim_tlvlist_add_noval(&itl, 0x000f); - aim_tlvlist_add_noval(&itl, 0x0010); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip); + aim_tlvlist_add_16(&inner_tlvlist, 0x0005, pin); + aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber); + aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); + aim_tlvlist_add_noval(&inner_tlvlist, 0x0010); /* Send the bitwise complement of the port and ip. As a check? */ ip_comp[0] = ~ip[0]; ip_comp[1] = ~ip[1]; ip_comp[2] = ~ip[2]; ip_comp[3] = ~ip[3]; - aim_tlvlist_add_raw(&itl, 0x0016, 4, ip_comp); - aim_tlvlist_add_16(&itl, 0x0017, ~pin); + aim_tlvlist_add_raw(&inner_tlvlist, 0x0016, 4, ip_comp); + aim_tlvlist_add_16(&inner_tlvlist, 0x0017, ~pin); #if 0 /* TODO: If the following is ever enabled, ensure that it is @@ -1015,9 +1015,9 @@ * redirect for a file receive (same conditions for * sending 0x000f above) */ - aim_tlvlist_add_raw(&itl, 0x000e, 2, "en"); - aim_tlvlist_add_raw(&itl, 0x000d, 8, "us-ascii"); - aim_tlvlist_add_raw(&itl, 0x000c, 24, "Please accept this file."); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en"); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii"); + aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file."); #endif if (filename != NULL) @@ -1034,20 +1034,20 @@ byte_stream_putstr(&bs, filename); byte_stream_put8(&bs, 0x00); - aim_tlvlist_add_raw(&itl, 0x2711, bs.len, bs.data); + aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data); g_free(bs.data); /* End TLV t(2711) */ } - aim_tlvlist_write(&hdrbs, &itl); - - aim_tlvlist_add_raw(&tl, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); + aim_tlvlist_write(&hdrbs, &inner_tlvlist); + + aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &tl); - - aim_tlvlist_free(&itl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &outer_tlvlist); + + aim_tlvlist_free(inner_tlvlist); + aim_tlvlist_free(outer_tlvlist); flap_connection_send(conn, frame); } @@ -1226,7 +1226,7 @@ aim_rxcallback_t userfunc; guchar cookie[8]; guint16 channel; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; char *sn; int snlen; guint16 icbmflags = 0; @@ -1281,7 +1281,7 @@ g_free(sn); g_free(msg); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -1874,11 +1874,11 @@ typedef void (*ch2_args_destructor_t)(OscarData *od, IcbmArgsCh2 *args); -static int incomingim_ch2(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) +static int incomingim_ch2(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, GSList *tlvlist, guint8 *cookie) { aim_rxcallback_t userfunc; aim_tlv_t *block1, *servdatatlv; - aim_tlvlist_t *list2; + GSList *list2; aim_tlv_t *tlv; IcbmArgsCh2 args; ByteStream bbs, sdbs, *sdbsptr = NULL; @@ -2078,12 +2078,12 @@ g_free((char *)args.encoding); g_free((char *)args.language); - aim_tlvlist_free(&list2); + aim_tlvlist_free(list2); return ret; } -static int incomingim_ch4(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, guint8 *cookie) +static int incomingim_ch4(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, GSList *tlvlist, guint8 *cookie) { ByteStream meat; aim_rxcallback_t userfunc; @@ -2186,7 +2186,7 @@ ret = incomingim_ch1(od, conn, mod, frame, snac, channel, &userinfo, bs, cookie); } else if (channel == 2) { - aim_tlvlist_t *tlvlist; + GSList *tlvlist; /* * Read block of TLVs (not including the userinfo data). All @@ -2196,14 +2196,14 @@ ret = incomingim_ch2(od, conn, mod, frame, snac, channel, &userinfo, tlvlist, cookie); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); } else if (channel == 4) { - aim_tlvlist_t *tlvlist; + GSList *tlvlist; tlvlist = aim_tlvlist_read(bs); ret = incomingim_ch4(od, conn, mod, frame, snac, channel, &userinfo, tlvlist, cookie); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); } else { purple_debug_misc("oscar", "icbm: ICBM received on an unsupported channel. Ignoring. (chan = %04x)\n", channel); @@ -2284,7 +2284,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) return -EINVAL; @@ -2300,9 +2300,9 @@ byte_stream_put8(&frame->data, strlen(sn)); byte_stream_putstr(&frame->data, sn); - aim_tlvlist_add_16(&tl, 0x0003, code); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_add_16(&tlvlist, 0x0003, code); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame);
--- a/libpurple/protocols/oscar/family_icq.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_icq.c Fri Jun 01 23:53:05 2007 +0000 @@ -474,14 +474,14 @@ icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { int ret = 0; - aim_tlvlist_t *tl; + GSList *tlvlist; aim_tlv_t *datatlv; ByteStream qbs; guint32 ouruin; guint16 cmdlen, cmd, reqid; - if (!(tl = aim_tlvlist_read(bs)) || !(datatlv = aim_tlv_gettlv(tl, 0x0001, 1))) { - aim_tlvlist_free(&tl); + if (!(tlvlist = aim_tlvlist_read(bs)) || !(datatlv = aim_tlv_gettlv(tlvlist, 0x0001, 1))) { + aim_tlvlist_free(tlvlist); purple_debug_misc("oscar", "corrupt ICQ response\n"); return 0; } @@ -661,7 +661,7 @@ } } - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_locate.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Fri Jun 01 23:53:05 2007 +0000 @@ -930,7 +930,7 @@ int aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info) { - aim_tlvlist_t *tlvlist = NULL; + GSList *tlvlist = NULL; if (!bs || !info) return -EINVAL; @@ -965,9 +965,9 @@ if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN) aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen); - byte_stream_put16(bs, aim_tlvlist_count(&tlvlist)); + byte_stream_put16(bs, aim_tlvlist_count(tlvlist)); aim_tlvlist_write(bs, &tlvlist); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return 0; } @@ -1050,7 +1050,7 @@ static int rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_rxcallback_t userfunc; int ret = 0; guint16 maxsiglen = 0; @@ -1063,7 +1063,7 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, maxsiglen); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -1096,7 +1096,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; char *encoding; static const char defencoding[] = {"text/aolrtf; charset=\"%s\""}; @@ -1115,8 +1115,8 @@ /* no + 1 here because of %s */ encoding = g_malloc(strlen(defencoding) + strlen(profile_encoding)); snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding); - aim_tlvlist_add_str(&tl, 0x0001, encoding); - aim_tlvlist_add_raw(&tl, 0x0002, profile_len, (const guchar *)profile); + aim_tlvlist_add_str(&tlvlist, 0x0001, encoding); + aim_tlvlist_add_raw(&tlvlist, 0x0002, profile_len, (const guchar *)profile); g_free(encoding); } @@ -1132,20 +1132,20 @@ if (awaymsg_len) { encoding = g_malloc(strlen(defencoding) + strlen(awaymsg_encoding)); snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding); - aim_tlvlist_add_str(&tl, 0x0003, encoding); - aim_tlvlist_add_raw(&tl, 0x0004, awaymsg_len, (const guchar *)awaymsg); + aim_tlvlist_add_str(&tlvlist, 0x0003, encoding); + aim_tlvlist_add_raw(&tlvlist, 0x0004, awaymsg_len, (const guchar *)awaymsg); g_free(encoding); } else - aim_tlvlist_add_noval(&tl, 0x0004); + aim_tlvlist_add_noval(&tlvlist, 0x0004); } - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -1161,20 +1161,20 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE))) return -EINVAL; - aim_tlvlist_add_caps(&tl, 0x0005, caps); + aim_tlvlist_add_caps(&tlvlist, 0x0005, caps); - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -1221,7 +1221,7 @@ int ret = 0; aim_rxcallback_t userfunc; aim_userinfo_t *userinfo, *userinfo2; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_tlv_t *tlv = NULL; int was_explicit; @@ -1252,7 +1252,7 @@ userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length); userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; } - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); aim_locate_adduserinfo(od, userinfo); userinfo2 = aim_locate_finduserinfo(od, userinfo->sn); @@ -1284,42 +1284,42 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE))) return -EINVAL; - aim_tlvlist_add_16(&tl, 0x000a, privacy); + aim_tlvlist_add_16(&tlvlist, 0x000a, privacy); if (first) - aim_tlvlist_add_str(&tl, 0x0001, first); + aim_tlvlist_add_str(&tlvlist, 0x0001, first); if (last) - aim_tlvlist_add_str(&tl, 0x0002, last); + aim_tlvlist_add_str(&tlvlist, 0x0002, last); if (middle) - aim_tlvlist_add_str(&tl, 0x0003, middle); + aim_tlvlist_add_str(&tlvlist, 0x0003, middle); if (maiden) - aim_tlvlist_add_str(&tl, 0x0004, maiden); + aim_tlvlist_add_str(&tlvlist, 0x0004, maiden); if (state) - aim_tlvlist_add_str(&tl, 0x0007, state); + aim_tlvlist_add_str(&tlvlist, 0x0007, state); if (city) - aim_tlvlist_add_str(&tl, 0x0008, city); + aim_tlvlist_add_str(&tlvlist, 0x0008, city); if (nickname) - aim_tlvlist_add_str(&tl, 0x000c, nickname); + aim_tlvlist_add_str(&tlvlist, 0x000c, nickname); if (zip) - aim_tlvlist_add_str(&tl, 0x000d, zip); + aim_tlvlist_add_str(&tlvlist, 0x000d, zip); if (street) - aim_tlvlist_add_str(&tl, 0x0021, street); + aim_tlvlist_add_str(&tlvlist, 0x0021, street); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x0002, 0x0009, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0002, 0x0009, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -1365,32 +1365,32 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE))) return -EINVAL; /* ?? privacy ?? */ - aim_tlvlist_add_16(&tl, 0x000a, privacy); + aim_tlvlist_add_16(&tlvlist, 0x000a, privacy); if (interest1) - aim_tlvlist_add_str(&tl, 0x0000b, interest1); + aim_tlvlist_add_str(&tlvlist, 0x0000b, interest1); if (interest2) - aim_tlvlist_add_str(&tl, 0x0000b, interest2); + aim_tlvlist_add_str(&tlvlist, 0x0000b, interest2); if (interest3) - aim_tlvlist_add_str(&tl, 0x0000b, interest3); + aim_tlvlist_add_str(&tlvlist, 0x0000b, interest3); if (interest4) - aim_tlvlist_add_str(&tl, 0x0000b, interest4); + aim_tlvlist_add_str(&tlvlist, 0x0000b, interest4); if (interest5) - aim_tlvlist_add_str(&tl, 0x0000b, interest5); + aim_tlvlist_add_str(&tlvlist, 0x0000b, interest5); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x0002, 0x000f, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0002, 0x000f, 0x0000, 0); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame);
--- a/libpurple/protocols/oscar/family_odir.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_odir.c Fri Jun 01 23:53:05 2007 +0000 @@ -43,22 +43,22 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region || !email) return -EINVAL; /* Create a TLV chain, write it to the outgoing frame, then free the chain */ - aim_tlvlist_add_str(&tl, 0x001c, region); - aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */ - aim_tlvlist_add_str(&tl, 0x0005, email); + aim_tlvlist_add_str(&tlvlist, 0x001c, region); + aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0001); /* Type of search */ + aim_tlvlist_add_str(&tlvlist, 0x0005, email); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -91,41 +91,41 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region) return -EINVAL; /* Create a TLV chain, write it to the outgoing frame, then free the chain */ - aim_tlvlist_add_str(&tl, 0x001c, region); - aim_tlvlist_add_16(&tl, 0x000a, 0x0000); /* Type of search */ + aim_tlvlist_add_str(&tlvlist, 0x001c, region); + aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0000); /* Type of search */ if (first) - aim_tlvlist_add_str(&tl, 0x0001, first); + aim_tlvlist_add_str(&tlvlist, 0x0001, first); if (last) - aim_tlvlist_add_str(&tl, 0x0002, last); + aim_tlvlist_add_str(&tlvlist, 0x0002, last); if (middle) - aim_tlvlist_add_str(&tl, 0x0003, middle); + aim_tlvlist_add_str(&tlvlist, 0x0003, middle); if (maiden) - aim_tlvlist_add_str(&tl, 0x0004, maiden); + aim_tlvlist_add_str(&tlvlist, 0x0004, maiden); if (country) - aim_tlvlist_add_str(&tl, 0x0006, country); + aim_tlvlist_add_str(&tlvlist, 0x0006, country); if (state) - aim_tlvlist_add_str(&tl, 0x0007, state); + aim_tlvlist_add_str(&tlvlist, 0x0007, state); if (city) - aim_tlvlist_add_str(&tl, 0x0008, city); + aim_tlvlist_add_str(&tlvlist, 0x0008, city); if (nick) - aim_tlvlist_add_str(&tl, 0x000c, nick); + aim_tlvlist_add_str(&tlvlist, 0x000c, nick); if (zip) - aim_tlvlist_add_str(&tl, 0x000d, zip); + aim_tlvlist_add_str(&tlvlist, 0x000d, zip); if (address) - aim_tlvlist_add_str(&tl, 0x0021, address); + aim_tlvlist_add_str(&tlvlist, 0x0021, address); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -145,23 +145,23 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, 0x000f)) || !region) return -EINVAL; /* Create a TLV chain, write it to the outgoing frame, then free the chain */ - aim_tlvlist_add_str(&tl, 0x001c, region); - aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */ + aim_tlvlist_add_str(&tlvlist, 0x001c, region); + aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0001); /* Type of search */ if (interest) - aim_tlvlist_add_str(&tl, 0x0001, interest); + aim_tlvlist_add_str(&tlvlist, 0x0001, interest); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -189,22 +189,22 @@ /* Allocate a linked list, 1 node per result */ while (numresults) { struct aim_odir *new; - aim_tlvlist_t *tl = aim_tlvlist_readnum(bs, byte_stream_get16(bs)); + GSList *tlvlist = aim_tlvlist_readnum(bs, byte_stream_get16(bs)); new = (struct aim_odir *)g_malloc(sizeof(struct aim_odir)); - new->first = aim_tlv_getstr(tl, 0x0001, 1); - new->last = aim_tlv_getstr(tl, 0x0002, 1); - new->middle = aim_tlv_getstr(tl, 0x0003, 1); - new->maiden = aim_tlv_getstr(tl, 0x0004, 1); - new->email = aim_tlv_getstr(tl, 0x0005, 1); - new->country = aim_tlv_getstr(tl, 0x0006, 1); - new->state = aim_tlv_getstr(tl, 0x0007, 1); - new->city = aim_tlv_getstr(tl, 0x0008, 1); - new->sn = aim_tlv_getstr(tl, 0x0009, 1); - new->interest = aim_tlv_getstr(tl, 0x000b, 1); - new->nick = aim_tlv_getstr(tl, 0x000c, 1); - new->zip = aim_tlv_getstr(tl, 0x000d, 1); - new->region = aim_tlv_getstr(tl, 0x001c, 1); - new->address = aim_tlv_getstr(tl, 0x0021, 1); + new->first = aim_tlv_getstr(tlvlist, 0x0001, 1); + new->last = aim_tlv_getstr(tlvlist, 0x0002, 1); + new->middle = aim_tlv_getstr(tlvlist, 0x0003, 1); + new->maiden = aim_tlv_getstr(tlvlist, 0x0004, 1); + new->email = aim_tlv_getstr(tlvlist, 0x0005, 1); + new->country = aim_tlv_getstr(tlvlist, 0x0006, 1); + new->state = aim_tlv_getstr(tlvlist, 0x0007, 1); + new->city = aim_tlv_getstr(tlvlist, 0x0008, 1); + new->sn = aim_tlv_getstr(tlvlist, 0x0009, 1); + new->interest = aim_tlv_getstr(tlvlist, 0x000b, 1); + new->nick = aim_tlv_getstr(tlvlist, 0x000c, 1); + new->zip = aim_tlv_getstr(tlvlist, 0x000d, 1); + new->region = aim_tlv_getstr(tlvlist, 0x001c, 1); + new->address = aim_tlv_getstr(tlvlist, 0x0021, 1); new->next = results; results = new; numresults--;
--- a/libpurple/protocols/oscar/family_oservice.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_oservice.c Fri Jun 01 23:53:05 2007 +0000 @@ -123,7 +123,7 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; struct chatsnacinfo csi; conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS); @@ -145,9 +145,9 @@ */ byte_stream_put16(&frame->data, 0x000e); - aim_tlvlist_add_chatroom(&tl, 0x0001, exchange, roomname, instance); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_add_chatroom(&tlvlist, 0x0001, exchange, roomname, instance); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -160,7 +160,7 @@ { struct aim_redirect_data redir; aim_rxcallback_t userfunc; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; aim_snac_t *origsnac = NULL; int ret = 0; @@ -171,7 +171,7 @@ if (!aim_tlv_gettlv(tlvlist, 0x000d, 1) || !aim_tlv_gettlv(tlvlist, 0x0005, 1) || !aim_tlv_gettlv(tlvlist, 0x0006, 1)) { - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return 0; } @@ -201,7 +201,7 @@ g_free(origsnac->data); g_free(origsnac); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -606,7 +606,7 @@ aim_rxcallback_t userfunc; int ret = 0; guint16 groupcount, i; - aim_tlvlist_t *tl; + GSList *tlvlist; char *ip = NULL; aim_tlv_t *cktlv; @@ -630,17 +630,17 @@ purple_debug_misc("oscar", "bifurcated migration unsupported -- group 0x%04x\n", group); } - tl = aim_tlvlist_read(bs); + tlvlist = aim_tlvlist_read(bs); - if (aim_tlv_gettlv(tl, 0x0005, 1)) - ip = aim_tlv_getstr(tl, 0x0005, 1); + if (aim_tlv_gettlv(tlvlist, 0x0005, 1)) + ip = aim_tlv_getstr(tlvlist, 0x0005, 1); - cktlv = aim_tlv_gettlv(tl, 0x0006, 1); + cktlv = aim_tlv_gettlv(tlvlist, 0x0006, 1); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, ip, cktlv ? cktlv->value : NULL); - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); g_free(ip); return ret; @@ -653,7 +653,7 @@ aim_rxcallback_t userfunc; char *msg = NULL; int ret = 0; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; guint16 id; /* @@ -681,7 +681,7 @@ g_free(msg); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); return ret; } @@ -805,24 +805,24 @@ FlapConnection *conn; FlapFrame *frame; aim_snacid_t snacid; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM))) return -EINVAL; if (seticqstatus) { - aim_tlvlist_add_32(&tl, 0x0006, icqstatus | + aim_tlvlist_add_32(&tlvlist, 0x0006, icqstatus | AIM_ICQ_STATE_HIDEIP | AIM_ICQ_STATE_DIRECTREQUIREAUTH); } #if 0 if (other_stuff_that_isnt_implemented) { - aim_tlvlist_add_raw(&tl, 0x000c, 0x0025, + aim_tlvlist_add_raw(&tlvlist, 0x000c, 0x0025, chunk_of_x25_bytes_with_ip_address_etc); - aim_tlvlist_add_raw(&tl, 0x0011, 0x0005, unknown 0x01 61 10 f6 41); - aim_tlvlist_add_16(&tl, 0x0012, unknown 0x00 00); + aim_tlvlist_add_raw(&tlvlist, 0x0011, 0x0005, unknown 0x01 61 10 f6 41); + aim_tlvlist_add_16(&tlvlist, 0x0012, unknown 0x00 00); } #endif @@ -851,18 +851,18 @@ byte_stream_putstr(&tmpbs, itmsurl); byte_stream_put16(&tmpbs, 0x0000); - aim_tlvlist_add_raw(&tl, 0x001d, + aim_tlvlist_add_raw(&tlvlist, 0x001d, byte_stream_curpos(&tmpbs), tmpbs.data); g_free(tmpbs.data); } - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(&tl)); + frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0001, 0x001e, 0x0000, snacid); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); @@ -913,14 +913,14 @@ int ret = 0; aim_rxcallback_t userfunc; guint32 offset, len; - aim_tlvlist_t *list; + GSList *tlvlist; char *modname; offset = byte_stream_get32(bs); len = byte_stream_get32(bs); - list = aim_tlvlist_read(bs); + tlvlist = aim_tlvlist_read(bs); - modname = aim_tlv_getstr(list, 0x0001, 1); + modname = aim_tlv_getstr(tlvlist, 0x0001, 1); purple_debug_info("oscar", "Got memory request for data at 0x%08lx (%d bytes) of requested %s\n", offset, len, modname ? modname : "aim.exe"); @@ -928,7 +928,7 @@ ret = userfunc(od, conn, frame, offset, len, modname); g_free(modname); - aim_tlvlist_free(&list); + aim_tlvlist_free(tlvlist); return ret; }
--- a/libpurple/protocols/oscar/family_popup.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_popup.c Fri Jun 01 23:53:05 2007 +0000 @@ -37,23 +37,23 @@ parsepopup(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { aim_rxcallback_t userfunc; - aim_tlvlist_t *tl; + GSList *tlvlist; int ret = 0; char *msg, *url; guint16 width, height, delay; - tl = aim_tlvlist_read(bs); + tlvlist = aim_tlvlist_read(bs); - msg = aim_tlv_getstr(tl, 0x0001, 1); - url = aim_tlv_getstr(tl, 0x0002, 1); - width = aim_tlv_get16(tl, 0x0003, 1); - height = aim_tlv_get16(tl, 0x0004, 1); - delay = aim_tlv_get16(tl, 0x0005, 1); + msg = aim_tlv_getstr(tlvlist, 0x0001, 1); + url = aim_tlv_getstr(tlvlist, 0x0002, 1); + width = aim_tlv_get16(tlvlist, 0x0003, 1); + height = aim_tlv_get16(tlvlist, 0x0004, 1); + delay = aim_tlv_get16(tlvlist, 0x0005, 1); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, msg, url, width, height, delay); - aim_tlvlist_free(&tl); + aim_tlvlist_free(tlvlist); g_free(msg); g_free(url);
--- a/libpurple/protocols/oscar/family_userlookup.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/family_userlookup.c Fri Jun 01 23:53:05 2007 +0000 @@ -89,7 +89,7 @@ static int reply(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { int j = 0, m, ret = 0; - aim_tlvlist_t *tlvlist; + GSList *tlvlist; char *cur = NULL, *buf = NULL; aim_rxcallback_t userfunc; aim_snac_t *snac2; @@ -99,7 +99,7 @@ searchaddr = (const char *)snac2->data; tlvlist = aim_tlvlist_read(bs); - m = aim_tlvlist_count(&tlvlist); + m = aim_tlvlist_count(tlvlist); /* XXX uhm. * This is the only place that uses something other than 1 for the 3rd @@ -116,7 +116,7 @@ } g_free(cur); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, searchaddr, j, buf);
--- a/libpurple/protocols/oscar/flap_connection.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Fri Jun 01 23:53:05 2007 +0000 @@ -61,13 +61,13 @@ flap_connection_send_version_with_cookie(OscarData *od, FlapConnection *conn, guint16 length, const guint8 *chipsahoy) { FlapFrame *frame; - aim_tlvlist_t *tl = NULL; + GSList *tlvlist = NULL; frame = flap_frame_new(od, 0x01, 4 + 2 + 2 + length); byte_stream_put32(&frame->data, 0x00000001); - aim_tlvlist_add_raw(&tl, 0x0006, length, chipsahoy); - aim_tlvlist_write(&frame->data, &tl); - aim_tlvlist_free(&tl); + aim_tlvlist_add_raw(&tlvlist, 0x0006, length, chipsahoy); + aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_free(tlvlist); flap_connection_send(conn, frame); } @@ -693,7 +693,7 @@ static void parse_flap_ch4(OscarData *od, FlapConnection *conn, FlapFrame *frame) { - aim_tlvlist_t *tlvlist; + GSList *tlvlist; char *msg = NULL; guint16 code = 0; aim_rxcallback_t userfunc; @@ -721,7 +721,7 @@ if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) userfunc(od, conn, frame, code, msg); - aim_tlvlist_free(&tlvlist); + aim_tlvlist_free(tlvlist); g_free(msg); }
--- a/libpurple/protocols/oscar/oscar.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Fri Jun 01 23:53:05 2007 +0000 @@ -2202,7 +2202,7 @@ buddy->name, group->name); aim_ssi_sendauthrequest(od, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list.")); if (!aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY)) - aim_ssi_addbuddy(od, buddy->name, group->name, purple_buddy_get_alias_only(buddy), NULL, NULL, 1); + aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE); } } @@ -4592,7 +4592,7 @@ if ((od->ssi.received_data) && !(aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY))) { purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n", buddy->name, group->name); - aim_ssi_addbuddy(od, buddy->name, group->name, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); + aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); } /* XXX - Should this be done from AIM accounts, as well? */
--- a/libpurple/protocols/oscar/oscar.h Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.h Fri Jun 01 23:53:05 2007 +0000 @@ -1172,7 +1172,7 @@ guint16 gid; guint16 bid; guint16 type; - struct aim_tlvlist_s *data; + GSList *data; struct aim_ssi_item *next; }; @@ -1208,7 +1208,7 @@ gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn); /* Client functions for changing SSI data */ -int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth); +int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth); int aim_ssi_addpermit(OscarData *od, const char *name); int aim_ssi_adddeny(OscarData *od, const char *name); int aim_ssi_delbuddy(OscarData *od, const char *name, const char *group); @@ -1357,54 +1357,47 @@ guint8 *value; } aim_tlv_t; -/* TLV List structure */ -typedef struct aim_tlvlist_s -{ - aim_tlv_t *tlv; - struct aim_tlvlist_s *next; -} aim_tlvlist_t; - /* TLV handling functions */ char *aim_tlv_getvalue_as_string(aim_tlv_t *tlv); -aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, guint16 type, const int nth); -int aim_tlv_getlength(aim_tlvlist_t *list, guint16 type, const int nth); -char *aim_tlv_getstr(aim_tlvlist_t *list, const guint16 type, const int nth); -guint8 aim_tlv_get8(aim_tlvlist_t *list, const guint16 type, const int nth); -guint16 aim_tlv_get16(aim_tlvlist_t *list, const guint16 type, const int nth); -guint32 aim_tlv_get32(aim_tlvlist_t *list, const guint16 type, const int nth); +aim_tlv_t *aim_tlv_gettlv(GSList *list, guint16 type, const int nth); +int aim_tlv_getlength(GSList *list, guint16 type, const int nth); +char *aim_tlv_getstr(GSList *list, const guint16 type, const int nth); +guint8 aim_tlv_get8(GSList *list, const guint16 type, const int nth); +guint16 aim_tlv_get16(GSList *list, const guint16 type, const int nth); +guint32 aim_tlv_get32(GSList *list, const guint16 type, const int nth); /* TLV list handling functions */ -aim_tlvlist_t *aim_tlvlist_read(ByteStream *bs); -aim_tlvlist_t *aim_tlvlist_readnum(ByteStream *bs, guint16 num); -aim_tlvlist_t *aim_tlvlist_readlen(ByteStream *bs, guint16 len); -aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig); +GSList *aim_tlvlist_read(ByteStream *bs); +GSList *aim_tlvlist_readnum(ByteStream *bs, guint16 num); +GSList *aim_tlvlist_readlen(ByteStream *bs, guint16 len); +GSList *aim_tlvlist_copy(GSList *orig); -int aim_tlvlist_count(aim_tlvlist_t **list); -int aim_tlvlist_size(aim_tlvlist_t **list); -int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two); -int aim_tlvlist_write(ByteStream *bs, aim_tlvlist_t **list); -void aim_tlvlist_free(aim_tlvlist_t **list); +int aim_tlvlist_count(GSList *list); +int aim_tlvlist_size(GSList *list); +int aim_tlvlist_cmp(GSList *one, GSList *two); +int aim_tlvlist_write(ByteStream *bs, GSList **list); +void aim_tlvlist_free(GSList *list); -int aim_tlvlist_add_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value); -int aim_tlvlist_add_noval(aim_tlvlist_t **list, const guint16 type); -int aim_tlvlist_add_8(aim_tlvlist_t **list, const guint16 type, const guint8 value); -int aim_tlvlist_add_16(aim_tlvlist_t **list, const guint16 type, const guint16 value); -int aim_tlvlist_add_32(aim_tlvlist_t **list, const guint16 type, const guint32 value); -int aim_tlvlist_add_str(aim_tlvlist_t **list, const guint16 type, const char *value); -int aim_tlvlist_add_caps(aim_tlvlist_t **list, const guint16 type, const guint32 caps); -int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *userinfo); -int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance); -int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl); +int aim_tlvlist_add_raw(GSList **list, const guint16 type, const guint16 length, const guint8 *value); +int aim_tlvlist_add_noval(GSList **list, const guint16 type); +int aim_tlvlist_add_8(GSList **list, const guint16 type, const guint8 value); +int aim_tlvlist_add_16(GSList **list, const guint16 type, const guint16 value); +int aim_tlvlist_add_32(GSList **list, const guint16 type, const guint32 value); +int aim_tlvlist_add_str(GSList **list, const guint16 type, const char *value); +int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps); +int aim_tlvlist_add_userinfo(GSList **list, guint16 type, aim_userinfo_t *userinfo); +int aim_tlvlist_add_chatroom(GSList **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance); +int aim_tlvlist_add_frozentlvlist(GSList **list, guint16 type, GSList **tl); -int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const guint16 type, const guint16 lenth, const guint8 *value); -int aim_tlvlist_replace_str(aim_tlvlist_t **list, const guint16 type, const char *str); -int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const guint16 type); -int aim_tlvlist_replace_8(aim_tlvlist_t **list, const guint16 type, const guint8 value); -int aim_tlvlist_replace_16(aim_tlvlist_t **list, const guint16 type, const guint16 value); -int aim_tlvlist_replace_32(aim_tlvlist_t **list, const guint16 type, const guint32 value); +int aim_tlvlist_replace_raw(GSList **list, const guint16 type, const guint16 lenth, const guint8 *value); +int aim_tlvlist_replace_str(GSList **list, const guint16 type, const char *str); +int aim_tlvlist_replace_noval(GSList **list, const guint16 type); +int aim_tlvlist_replace_8(GSList **list, const guint16 type, const guint8 value); +int aim_tlvlist_replace_16(GSList **list, const guint16 type, const guint16 value); +int aim_tlvlist_replace_32(GSList **list, const guint16 type, const guint32 value); -void aim_tlvlist_remove(aim_tlvlist_t **list, const guint16 type); +void aim_tlvlist_remove(GSList **list, const guint16 type);
--- a/libpurple/protocols/oscar/tlv.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/oscar/tlv.c Fri Jun 01 23:53:05 2007 +0000 @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "oscar.h" static aim_tlv_t * @@ -35,17 +34,57 @@ } static void -freetlv(aim_tlv_t **oldtlv) +freetlv(aim_tlv_t *oldtlv) { + g_free(oldtlv->value); + g_free(oldtlv); +} - if (!oldtlv || !*oldtlv) - return; +static GSList * +aim_tlv_read(GSList *list, ByteStream *bs) +{ + guint16 type, length; + aim_tlv_t *tlv; + + type = byte_stream_get16(bs); + length = byte_stream_get16(bs); - g_free((*oldtlv)->value); - g_free(*oldtlv); - *oldtlv = NULL; +#if 0 + /* + * This code hasn't been needed in years. It's been commented + * out since 2003, at the latest. It seems likely that it was + * just a bug in their server code that has since been fixed. + * In any case, here's the orignal comment, kept for historical + * purposes: + * + * Okay, so now AOL has decided that any TLV of + * type 0x0013 can only be two bytes, despite + * what the actual given length is. So here + * we dump any invalid TLVs of that sort. Hopefully + * there's no special cases to this special case. + * - mid (30jun2000) + */ + if ((type == 0x0013) && (length != 0x0002)) { + length = 0x0002; + return list; + } +#endif + if (length > byte_stream_empty(bs)) { + aim_tlvlist_free(list); + return NULL; + } - return; + tlv = createtlv(type, length, NULL); + if (tlv->length > 0) { + tlv->value = byte_stream_getraw(bs, length); + if (!tlv->value) { + freetlv(tlv); + aim_tlvlist_free(list); + return NULL; + } + } + + return g_slist_prepend(list, tlv); } /** @@ -56,7 +95,7 @@ * routines. When done with a TLV chain, aim_tlvlist_free() should * be called to free the dynamic substructures. * - * XXX There should be a flag setable here to have the tlvlist contain + * TODO: There should be a flag setable here to have the tlvlist contain * bstream references, so that at least the ->value portion of each * element doesn't need to be malloc/memcpy'd. This could prove to be * just as efficient as the in-place TLV parsing used in a couple places @@ -65,56 +104,17 @@ * @param bs Input bstream * @return Return the TLV chain read */ -aim_tlvlist_t *aim_tlvlist_read(ByteStream *bs) +GSList *aim_tlvlist_read(ByteStream *bs) { - aim_tlvlist_t *list = NULL, *cur; + GSList *list = NULL; while (byte_stream_empty(bs) > 0) { - guint16 type, length; - - type = byte_stream_get16(bs); - length = byte_stream_get16(bs); - -#if 0 /* temporarily disabled until I know if they're still doing it or not */ - /* - * Okay, so now AOL has decided that any TLV of - * type 0x0013 can only be two bytes, despite - * what the actual given length is. So here - * we dump any invalid TLVs of that sort. Hopefully - * there's no special cases to this special case. - * - mid (30jun2000) - */ - if ((type == 0x0013) && (length != 0x0002)) - length = 0x0002; -#else - if (0) - ; -#endif - else { - - if (length > byte_stream_empty(bs)) { - aim_tlvlist_free(&list); - return NULL; - } - - cur = g_new0(aim_tlvlist_t, 1); - cur->tlv = createtlv(type, length, NULL); - if (cur->tlv->length > 0) { - cur->tlv->value = byte_stream_getraw(bs, length); - if (!cur->tlv->value) { - freetlv(&cur->tlv); - g_free(cur); - aim_tlvlist_free(&list); - return NULL; - } - } - - cur->next = list; - list = cur; - } + list = aim_tlv_read(list, bs); + if (list == NULL) + return NULL; } - return list; + return g_slist_reverse(list); } /** @@ -125,7 +125,7 @@ * routines. When done with a TLV chain, aim_tlvlist_free() should * be called to free the dynamic substructures. * - * XXX There should be a flag setable here to have the tlvlist contain + * TODO: There should be a flag setable here to have the tlvlist contain * bstream references, so that at least the ->value portion of each * element doesn't need to be malloc/memcpy'd. This could prove to be * just as efficient as the in-place TLV parsing used in a couple places @@ -138,40 +138,18 @@ * preceded by the number of TLVs. So you can limit that with this. * @return Return the TLV chain read */ -aim_tlvlist_t *aim_tlvlist_readnum(ByteStream *bs, guint16 num) +GSList *aim_tlvlist_readnum(ByteStream *bs, guint16 num) { - aim_tlvlist_t *list = NULL, *cur; + GSList *list = NULL; while ((byte_stream_empty(bs) > 0) && (num != 0)) { - guint16 type, length; - - type = byte_stream_get16(bs); - length = byte_stream_get16(bs); - - if (length > byte_stream_empty(bs)) { - aim_tlvlist_free(&list); + list = aim_tlv_read(list, bs); + if (list == NULL) return NULL; - } - - cur = g_new0(aim_tlvlist_t, 1); - cur->tlv = createtlv(type, length, NULL); - if (cur->tlv->length > 0) { - cur->tlv->value = byte_stream_getraw(bs, length); - if (!cur->tlv->value) { - freetlv(&cur->tlv); - g_free(cur); - aim_tlvlist_free(&list); - return NULL; - } - } - - if (num > 0) - num--; - cur->next = list; - list = cur; + num--; } - return list; + return g_slist_reverse(list); } /** @@ -182,7 +160,7 @@ * routines. When done with a TLV chain, aim_tlvlist_free() should * be called to free the dynamic substructures. * - * XXX There should be a flag setable here to have the tlvlist contain + * TODO: There should be a flag setable here to have the tlvlist contain * bstream references, so that at least the ->value portion of each * element doesn't need to be malloc/memcpy'd. This could prove to be * just as efficient as the in-place TLV parsing used in a couple places @@ -195,39 +173,19 @@ * preceded by the length of the TLVs. So you can limit that with this. * @return Return the TLV chain read */ -aim_tlvlist_t *aim_tlvlist_readlen(ByteStream *bs, guint16 len) +GSList *aim_tlvlist_readlen(ByteStream *bs, guint16 len) { - aim_tlvlist_t *list = NULL, *cur; + GSList *list = NULL; while ((byte_stream_empty(bs) > 0) && (len > 0)) { - guint16 type, length; - - type = byte_stream_get16(bs); - length = byte_stream_get16(bs); - - if (length > byte_stream_empty(bs)) { - aim_tlvlist_free(&list); + list = aim_tlv_read(list, bs); + if (list == NULL) return NULL; - } - cur = g_new0(aim_tlvlist_t, 1); - cur->tlv = createtlv(type, length, NULL); - if (cur->tlv->length > 0) { - cur->tlv->value = byte_stream_getraw(bs, length); - if (!cur->tlv->value) { - freetlv(&cur->tlv); - g_free(cur); - aim_tlvlist_free(&list); - return NULL; - } - } - - len -= aim_tlvlist_size(&cur); - cur->next = list; - list = cur; + len -= 2 + 2 + ((aim_tlv_t *)list->data)->length; } - return list; + return g_slist_reverse(list); } /** @@ -237,12 +195,14 @@ * @param orig The TLV chain you want to make a copy of. * @return A newly allocated TLV chain. */ -aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig) +GSList *aim_tlvlist_copy(GSList *orig) { - aim_tlvlist_t *new = NULL; + GSList *new = NULL; + aim_tlv_t *tlv; - while (orig) { - aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value); + while (orig != NULL) { + tlv = orig->data; + aim_tlvlist_add_raw(&new, tlv->type, tlv->length, tlv->value); orig = orig->next; } @@ -257,15 +217,15 @@ * @param two The other TLV chain to compare. * @return Return 0 if the lists are the same, return 1 if they are different. */ -int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two) +int aim_tlvlist_cmp(GSList *one, GSList *two) { ByteStream bs1, bs2; - if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two)) + if (aim_tlvlist_size(one) != aim_tlvlist_size(two)) return 1; - byte_stream_new(&bs1, aim_tlvlist_size(&one)); - byte_stream_new(&bs2, aim_tlvlist_size(&two)); + byte_stream_new(&bs1, aim_tlvlist_size(one)); + byte_stream_new(&bs2, aim_tlvlist_size(two)); aim_tlvlist_write(&bs1, &one); aim_tlvlist_write(&bs2, &two); @@ -291,26 +251,13 @@ * * @param list Chain to be freed */ -void aim_tlvlist_free(aim_tlvlist_t **list) +void aim_tlvlist_free(GSList *list) { - aim_tlvlist_t *cur; - - if (!list || !*list) - return; - - for (cur = *list; cur; ) { - aim_tlvlist_t *tmp; - - freetlv(&cur->tlv); - - tmp = cur->next; - g_free(cur); - cur = tmp; + while (list != NULL) + { + freetlv(list->data); + list = g_slist_delete_link(list, list); } - - list = NULL; - - return; } /** @@ -319,15 +266,15 @@ * @param list Chain to be counted. * @return The number of TLVs stored in the passed chain. */ -int aim_tlvlist_count(aim_tlvlist_t **list) +int aim_tlvlist_count(GSList *list) { - aim_tlvlist_t *cur; + GSList *cur; int count; - if (!list || !*list) + if (list == NULL) return 0; - for (cur = *list, count = 0; cur; cur = cur->next) + for (cur = list, count = 0; cur; cur = cur->next) count++; return count; @@ -340,16 +287,16 @@ * @return The number of bytes that would be needed to * write the passed TLV chain to a data buffer. */ -int aim_tlvlist_size(aim_tlvlist_t **list) +int aim_tlvlist_size(GSList *list) { - aim_tlvlist_t *cur; + GSList *cur; int size; - if (!list || !*list) + if (list == NULL) return 0; - for (cur = *list, size = 0; cur; cur = cur->next) - size += (4 + cur->tlv->length); + for (cur = list, size = 0; cur; cur = cur->next) + size += (4 + ((aim_tlv_t *)cur->data)->length); return size; } @@ -364,27 +311,20 @@ * @param value String to add. * @return The size of the value added. */ -int aim_tlvlist_add_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) +int aim_tlvlist_add_raw(GSList **list, const guint16 type, const guint16 length, const guint8 *value) { - aim_tlvlist_t *newtlv, *cur; + aim_tlv_t *tlv; if (list == NULL) return 0; - newtlv = g_new0(aim_tlvlist_t, 1); - newtlv->tlv = createtlv(type, length, NULL); - if (newtlv->tlv->length > 0) - newtlv->tlv->value = g_memdup(value, length); + tlv = createtlv(type, length, NULL); + if (tlv->length > 0) + tlv->value = g_memdup(value, length); - if (!*list) - *list = newtlv; - else { - for(cur = *list; cur->next; cur = cur->next) - ; - cur->next = newtlv; - } + *list = g_slist_append(*list, tlv); - return newtlv->tlv->length; + return tlv->length; } /** @@ -395,7 +335,7 @@ * @param value Value to add. * @return The size of the value added. */ -int aim_tlvlist_add_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) +int aim_tlvlist_add_8(GSList **list, const guint16 type, const guint8 value) { guint8 v8[1]; @@ -412,7 +352,7 @@ * @param value Value to add. * @return The size of the value added. */ -int aim_tlvlist_add_16(aim_tlvlist_t **list, const guint16 type, const guint16 value) +int aim_tlvlist_add_16(GSList **list, const guint16 type, const guint16 value) { guint8 v16[2]; @@ -429,7 +369,7 @@ * @param value Value to add. * @return The size of the value added. */ -int aim_tlvlist_add_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) +int aim_tlvlist_add_32(GSList **list, const guint16 type, const guint32 value) { guint8 v32[4]; @@ -446,7 +386,7 @@ * @param value Value to add. * @return The size of the value added. */ -int aim_tlvlist_add_str(aim_tlvlist_t **list, const guint16 type, const char *value) +int aim_tlvlist_add_str(GSList **list, const guint16 type, const char *value) { return aim_tlvlist_add_raw(list, type, strlen(value), (guint8 *)value); } @@ -467,12 +407,12 @@ * @param caps Bitfield of capability flags to send * @return The size of the value added. */ -int aim_tlvlist_add_caps(aim_tlvlist_t **list, const guint16 type, const guint32 caps) +int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint32 caps) { - guint8 buf[16*16]; /* XXX icky fixed length buffer */ + guint8 buf[256]; /* TODO: Don't use a fixed length buffer */ ByteStream bs; - if (!caps) + if (caps == 0) return 0; /* nothing there anyway */ byte_stream_init(&bs, buf, sizeof(buf)); @@ -489,9 +429,9 @@ * @param type TLV type to add. * @return The size of the value added. */ -int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *userinfo) +int aim_tlvlist_add_userinfo(GSList **list, guint16 type, aim_userinfo_t *userinfo) { - guint8 buf[1024]; /* bleh */ + guint8 buf[1024]; /* TODO: Don't use a fixed length buffer */ ByteStream bs; byte_stream_init(&bs, buf, sizeof(buf)); @@ -510,7 +450,7 @@ * @param instance The instance. * @return The size of the value added. */ -int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) +int aim_tlvlist_add_chatroom(GSList **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance) { int len; ByteStream bs; @@ -536,7 +476,7 @@ * @param type TLV type to add. * @return The size of the value added. */ -int aim_tlvlist_add_noval(aim_tlvlist_t **list, const guint16 type) +int aim_tlvlist_add_noval(GSList **list, const guint16 type) { return aim_tlvlist_add_raw(list, type, 0, NULL); } @@ -546,7 +486,7 @@ * it is written using this. Or rather, it can be, but updates won't be * made to this. * - * XXX should probably support sublists for real. + * TODO: Should probably support sublists for real. * * This is so neat. * @@ -557,19 +497,19 @@ * 0 is returned if there was an error or if the destination * TLV chain has length 0. */ -int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl) +int aim_tlvlist_add_frozentlvlist(GSList **list, guint16 type, GSList **tlvlist) { int buflen; ByteStream bs; - buflen = aim_tlvlist_size(tl); + buflen = aim_tlvlist_size(*tlvlist); if (buflen <= 0) return 0; byte_stream_new(&bs, buflen); - aim_tlvlist_write(&bs, tl); + aim_tlvlist_write(&bs, tlvlist); aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), bs.data); @@ -589,25 +529,33 @@ * @param value String to add. * @return The length of the TLV. */ -int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const guint16 type, const guint16 length, const guint8 *value) +int aim_tlvlist_replace_raw(GSList **list, const guint16 type, const guint16 length, const guint8 *value) { - aim_tlvlist_t *cur; + GSList *cur; + aim_tlv_t *tlv; if (list == NULL) return 0; - for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next); + for (cur = *list; cur != NULL; cur = cur->next) + { + tlv = cur->data; + if (tlv->type == type) + break; + } + if (cur == NULL) + /* TLV does not exist, so add a new one */ return aim_tlvlist_add_raw(list, type, length, value); - g_free(cur->tlv->value); - cur->tlv->length = length; - if (cur->tlv->length > 0) { - cur->tlv->value = g_memdup(value, length); + g_free(tlv->value); + tlv->length = length; + if (tlv->length > 0) { + tlv->value = g_memdup(value, length); } else - cur->tlv->value = NULL; + tlv->value = NULL; - return cur->tlv->length; + return tlv->length; } /** @@ -620,7 +568,7 @@ * @param str String to add. * @return The length of the TLV. */ -int aim_tlvlist_replace_str(aim_tlvlist_t **list, const guint16 type, const char *str) +int aim_tlvlist_replace_str(GSList **list, const guint16 type, const char *str) { return aim_tlvlist_replace_raw(list, type, strlen(str), (const guchar *)str); } @@ -634,7 +582,7 @@ * @param type TLV type. * @return The length of the TLV. */ -int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const guint16 type) +int aim_tlvlist_replace_noval(GSList **list, const guint16 type) { return aim_tlvlist_replace_raw(list, type, 0, NULL); } @@ -649,7 +597,7 @@ * @param value 8 bit value to add. * @return The length of the TLV. */ -int aim_tlvlist_replace_8(aim_tlvlist_t **list, const guint16 type, const guint8 value) +int aim_tlvlist_replace_8(GSList **list, const guint16 type, const guint8 value) { guint8 v8[1]; @@ -668,7 +616,7 @@ * @param value 32 bit value to add. * @return The length of the TLV. */ -int aim_tlvlist_replace_32(aim_tlvlist_t **list, const guint16 type, const guint32 value) +int aim_tlvlist_replace_32(GSList **list, const guint16 type, const guint32 value) { guint8 v32[4]; @@ -678,36 +626,36 @@ } /** - * Remove a TLV of a given type. If you attempt to remove a TLV that - * does not exist, nothing happens. + * Remove all TLVs of a given type. If you attempt to remove a TLV + * that does not exist, nothing happens. * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. */ -void aim_tlvlist_remove(aim_tlvlist_t **list, const guint16 type) +void aim_tlvlist_remove(GSList **list, const guint16 type) { - aim_tlvlist_t *del; + GSList *cur, *next; + aim_tlv_t *tlv; - if (!list || !(*list)) + if (list == NULL || *list == NULL) return; - /* Remove the item from the list */ - if ((*list)->tlv->type == type) { - del = *list; - *list = (*list)->next; - } else { - aim_tlvlist_t *cur; - for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next); - if (!cur->next) - return; - del = cur->next; - cur->next = del->next; + cur = *list; + while (cur != NULL) + { + tlv = cur->data; + next = cur->next; + + if (tlv->type == type) + { + /* Delete this TLV */ + *list = g_slist_delete_link(*list, cur); + g_free(tlv->value); + g_free(tlv); + } + + cur = next; } - - /* Free the removed item */ - g_free(del->tlv->value); - g_free(del->tlv); - g_free(del); } /** @@ -718,32 +666,34 @@ * aim_tlvlist_free() must still be called to free up the memory used * by the chain structures. * - * XXX clean this up, make better use of bstreams + * TODO: Clean this up, make better use of bstreams * * @param bs Input bstream * @param list Source TLV chain * @return Return 0 if the destination bstream is too small. */ -int aim_tlvlist_write(ByteStream *bs, aim_tlvlist_t **list) +int aim_tlvlist_write(ByteStream *bs, GSList **list) { int goodbuflen; - aim_tlvlist_t *cur; + GSList *cur; + aim_tlv_t *tlv; /* do an initial run to test total length */ - goodbuflen = aim_tlvlist_size(list); + goodbuflen = aim_tlvlist_size(*list); if (goodbuflen > byte_stream_empty(bs)) return 0; /* not enough buffer */ /* do the real write-out */ for (cur = *list; cur; cur = cur->next) { - byte_stream_put16(bs, cur->tlv->type); - byte_stream_put16(bs, cur->tlv->length); - if (cur->tlv->length) - byte_stream_putraw(bs, cur->tlv->value, cur->tlv->length); + tlv = cur->data; + byte_stream_put16(bs, tlv->type); + byte_stream_put16(bs, tlv->length); + if (tlv->length > 0) + byte_stream_putraw(bs, tlv->value, tlv->length); } - return 1; /* XXX this is a nonsensical return */ + return 1; /* TODO: This is a nonsensical return */ } @@ -760,17 +710,19 @@ * @param nth Index of TLV of type to get. * @return The TLV you were looking for, or NULL if one could not be found. */ -aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const guint16 type, const int nth) +aim_tlv_t *aim_tlv_gettlv(GSList *list, const guint16 type, const int nth) { - aim_tlvlist_t *cur; + GSList *cur; + aim_tlv_t *tlv; int i; - for (cur = list, i = 0; cur; cur = cur->next) { - if (cur && cur->tlv) { - if (cur->tlv->type == type) + for (cur = list, i = 0; cur != NULL; cur = cur->next) { + tlv = cur->data; + if (tlv != NULL) { /* TODO: This NULL check shouldn't be needed */ + if (tlv->type == type) i++; if (i >= nth) - return cur->tlv; + return tlv; } } @@ -786,21 +738,15 @@ * @return The length of the data in this TLV, or -1 if the TLV could not be * found. Unless -1 is returned, this value will be 2 bytes. */ -int aim_tlv_getlength(aim_tlvlist_t *list, const guint16 type, const int nth) +int aim_tlv_getlength(GSList *list, const guint16 type, const int nth) { - aim_tlvlist_t *cur; - int i; + aim_tlv_t *tlv; - for (cur = list, i = 0; cur; cur = cur->next) { - if (cur && cur->tlv) { - if (cur->tlv->type == type) - i++; - if (i >= nth) - return cur->tlv->length; - } - } + tlv = aim_tlv_gettlv(list, type, nth); + if (tlv == NULL) + return -1; - return -1; + return tlv->length; } char * @@ -825,11 +771,12 @@ * not be found. This is a dynamic buffer and must be freed by the * caller. */ -char *aim_tlv_getstr(aim_tlvlist_t *list, const guint16 type, const int nth) +char *aim_tlv_getstr(GSList *list, const guint16 type, const int nth) { aim_tlv_t *tlv; - if (!(tlv = aim_tlv_gettlv(list, type, nth))) + tlv = aim_tlv_gettlv(list, type, nth); + if (tlv == NULL) return NULL; return aim_tlv_getvalue_as_string(tlv); @@ -845,12 +792,14 @@ * @return The value the TLV you were looking for, or 0 if one could * not be found. */ -guint8 aim_tlv_get8(aim_tlvlist_t *list, const guint16 type, const int nth) +guint8 aim_tlv_get8(GSList *list, const guint16 type, const int nth) { aim_tlv_t *tlv; - if (!(tlv = aim_tlv_gettlv(list, type, nth))) + tlv = aim_tlv_gettlv(list, type, nth); + if (tlv == NULL) return 0; /* erm */ + return aimutil_get8(tlv->value); } @@ -864,12 +813,14 @@ * @return The value the TLV you were looking for, or 0 if one could * not be found. */ -guint16 aim_tlv_get16(aim_tlvlist_t *list, const guint16 type, const int nth) +guint16 aim_tlv_get16(GSList *list, const guint16 type, const int nth) { aim_tlv_t *tlv; - if (!(tlv = aim_tlv_gettlv(list, type, nth))) + tlv = aim_tlv_gettlv(list, type, nth); + if (tlv == NULL) return 0; /* erm */ + return aimutil_get16(tlv->value); } @@ -883,11 +834,13 @@ * @return The value the TLV you were looking for, or 0 if one could * not be found. */ -guint32 aim_tlv_get32(aim_tlvlist_t *list, const guint16 type, const int nth) +guint32 aim_tlv_get32(GSList *list, const guint16 type, const int nth) { aim_tlv_t *tlv; - if (!(tlv = aim_tlv_gettlv(list, type, nth))) + tlv = aim_tlv_gettlv(list, type, nth); + if (tlv == NULL) return 0; /* erm */ + return aimutil_get32(tlv->value); }
--- a/libpurple/protocols/silc/silc.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/silc/silc.c Fri Jun 01 23:53:05 2007 +0000 @@ -391,7 +391,7 @@ /* Send QUIT */ silc_client_command_call(sg->client, sg->conn, NULL, - "QUIT", "Download Purple: " PURPLE_WEBSITE, NULL); + "QUIT", "Download this: " PURPLE_WEBSITE, NULL); if (sg->conn) silc_client_close_connection(sg->client, sg->conn); @@ -1552,7 +1552,7 @@ return PURPLE_CMD_RET_FAILED; silc_client_command_call(sg->client, sg->conn, NULL, - "QUIT", (args && args[0]) ? args[0] : "Download Purple: " PURPLE_WEBSITE, NULL); + "QUIT", (args && args[0]) ? args[0] : "Download this: " PURPLE_WEBSITE, NULL); return PURPLE_CMD_RET_OK; }
--- a/libpurple/protocols/zephyr/zephyr.h Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/protocols/zephyr/zephyr.h Fri Jun 01 23:53:05 2007 +0000 @@ -109,7 +109,7 @@ ZChecksum_t z_checksum; int z_num_other_fields; char *z_other_fields[Z_MAXOTHERFIELDS]; - void *z_message; + caddr_t z_message; int z_message_len; } ZNotice_t;
--- a/libpurple/proxy.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/proxy.c Fri Jun 01 23:53:05 2007 +0000 @@ -1059,6 +1059,22 @@ } } +static gboolean +s5_ensure_buffer_length(PurpleProxyConnectData *connect_data, int len) +{ + if(connect_data->read_len < len) { + if(connect_data->read_buf_len < len) { + /* it's not just that we haven't read enough, it's that we haven't tried to read enough yet */ + purple_debug_info("s5", "reallocing from %d to %d\n", connect_data->read_buf_len, len); + connect_data->read_buf_len = len; + connect_data->read_buffer = g_realloc(connect_data->read_buffer, connect_data->read_buf_len); + } + return FALSE; + } + + return TRUE; +} + static void s5_canread_again(gpointer data, gint source, PurpleInputCondition cond) { @@ -1067,7 +1083,7 @@ int len; if (connect_data->read_buffer == NULL) { - connect_data->read_buf_len = 512; + connect_data->read_buf_len = 4; connect_data->read_buffer = g_malloc(connect_data->read_buf_len); connect_data->read_len = 0; } @@ -1075,8 +1091,6 @@ dest = connect_data->read_buffer + connect_data->read_len; buf = connect_data->read_buffer; - purple_debug_info("socks5 proxy", "Able to read again.\n"); - len = read(connect_data->fd, dest, (connect_data->read_buf_len - connect_data->read_len)); if (len == 0) @@ -1119,33 +1133,31 @@ /* Skip past BND.ADDR */ switch(buf[3]) { case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */ - if(connect_data->read_len < 4 + 4) + if(!s5_ensure_buffer_length(connect_data, 4 + 4)) return; buf += 4 + 4; break; case 0x03: /* the address field contains a fully-qualified domain name. The first octet of the address field contains the number of octets of name that follow, there is no terminating NUL octet. */ - if(connect_data->read_len < 4 + 1) + if(!s5_ensure_buffer_length(connect_data, 4 + 1)) return; - buf += 4 + 1; - if(connect_data->read_len < 4 + 1 + buf[0]) + buf += 4; + if(!s5_ensure_buffer_length(connect_data, 4 + 1 + buf[0])) return; - buf += buf[0]; + buf += buf[0] + 1; break; case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */ - if(connect_data->read_len < 4 + 16) + if(!s5_ensure_buffer_length(connect_data, 4 + 16)) return; buf += 4 + 16; break; } - if(connect_data->read_len < (buf - connect_data->read_buffer) + 2) + /* Skip past BND.PORT */ + if(!s5_ensure_buffer_length(connect_data, (buf - connect_data->read_buffer) + 2)) return; - /* Skip past BND.PORT */ - buf += 2; - purple_proxy_connect_data_connected(connect_data); }
--- a/libpurple/purple-client.c Thu May 31 00:40:46 2007 +0000 +++ b/libpurple/purple-client.c Fri Jun 01 23:53:05 2007 +0000 @@ -5,7 +5,7 @@ #include <stdlib.h> #include "dbus-purple.h" -#include "purple-client-bindings.h" +#include "purple-client.h" static DBusGConnection *bus; static DBusGProxy *purple_proxy;
--- a/pidgin/Makefile.mingw Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/Makefile.mingw Fri Jun 01 23:53:05 2007 +0000 @@ -106,26 +106,22 @@ ## ## LIBRARIES ## -LIBPURPLES = \ - -lpurple \ - -lglib-2.0 \ - -lgthread-2.0 \ - -lgobject-2.0 \ - -lgmodule-2.0 \ + +PIDGIN_LIBS = \ -lintl \ - -lws2_32 \ - -lwinmm \ - -lz - -GTKPURPLES = \ - $(LIBPURPLES) \ + -lglib-2.0 \ + -lgobject-2.0 \ + -lgthread-2.0 \ + -lpurple \ + -lz \ -lidletrack \ -lgtk-win32-2.0 \ -latk-1.0 \ -lpango-1.0 \ -lgdk-win32-2.0 \ -lgdk_pixbuf-2.0 \ - -lgdi32 + -lgdi32 \ + -lwinmm include $(PIDGIN_COMMON_RULES) @@ -159,7 +155,7 @@ $(EXE_OBJECTS) $(PIDGIN_OBJECTS): $(PIDGIN_CONFIG_H) $(PIDGIN_TARGET).dll $(PIDGIN_TARGET).dll.a: $(PURPLE_DLL).a $(PIDGIN_IDLETRACK_DLL).a $(PIDGIN_OBJECTS) - $(CC) -shared $(PIDGIN_OBJECTS) $(LIB_PATHS) $(GTKPURPLES) $(DLL_LD_FLAGS) -Wl,--output-def,$(PIDGIN_TARGET).def,--out-implib,$(PIDGIN_TARGET).dll.a -o $(PIDGIN_TARGET).dll + $(CC) -shared $(PIDGIN_OBJECTS) $(LIB_PATHS) $(PIDGIN_LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(PIDGIN_TARGET).def,--out-implib,$(PIDGIN_TARGET).dll.a -o $(PIDGIN_TARGET).dll $(EXE_TARGET).exe: $(PIDGIN_CONFIG_H) $(PIDGIN_DLL).a $(PIDGIN_IDLETRACK_DLL).a $(EXE_OBJECTS) $(CC) $(LDFLAGS) $(EXE_OBJECTS) -o $(EXE_TARGET).exe
--- a/pidgin/gtkaccount.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkaccount.c Fri Jun 01 23:53:05 2007 +0000 @@ -498,8 +498,8 @@ menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu)); item = gtk_menu_get_active(GTK_MENU(menu)); protocol = g_object_get_data(G_OBJECT(item), "protocol"); - if (value == NULL && !strcmp(protocol, "prpl-fake") && - !strcmp(purple_account_user_split_get_text(split), _("Domain"))) + if (value == NULL && protocol != NULL && !strcmp(protocol, "prpl-fake") && + !strcmp(purple_account_user_split_get_text(split), _("Domain"))) value = "gmail.com"; if (value != NULL) @@ -827,9 +827,9 @@ menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu)); item = gtk_menu_get_active(GTK_MENU(menu)); protocol = g_object_get_data(G_OBJECT(item), "protocol"); - if (str_value == NULL && !strcmp(protocol, "prpl-fake") && + if (str_value == NULL && protocol != NULL && !strcmp(protocol, "prpl-fake") && !strcmp(_("Connect server"), purple_account_option_get_text(option))) - str_value = "talk.google.com"; + str_value = "talk.google.com"; if (str_value != NULL) gtk_entry_set_text(GTK_ENTRY(entry), str_value); @@ -2025,19 +2025,26 @@ { GdkPixbuf *pixbuf, *buddyicon = NULL; PurpleStoredImage *img = NULL; + PurplePlugin *prpl; + PurplePluginProtocolInfo *prpl_info = NULL; pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM); if ((pixbuf != NULL) && purple_account_is_disconnected(account)) gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); - if (purple_account_get_bool(account, "use-global-buddyicon", TRUE)) { - if (global_buddyicon != NULL) - buddyicon = g_object_ref(G_OBJECT(global_buddyicon)); - /* This is for when set_account() is called for a single account */ - else + prpl = purple_find_prpl(purple_account_get_protocol_id(account)); + if (prpl != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info != NULL && prpl_info->icon_spec.format != NULL) { + if (purple_account_get_bool(account, "use-global-buddyicon", TRUE)) { + if (global_buddyicon != NULL) + buddyicon = g_object_ref(G_OBJECT(global_buddyicon)); + /* This is for when set_account() is called for a single account */ + else + img = purple_buddy_icons_find_account_icon(account); + } else { img = purple_buddy_icons_find_account_icon(account); - } else { - img = purple_buddy_icons_find_account_icon(account); + } } if (img != NULL) {
--- a/pidgin/gtkblist.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkblist.c Fri Jun 01 23:53:05 2007 +0000 @@ -2721,6 +2721,7 @@ { GtkTreePath *path; int delay; + GdkRectangle rect; /* * When dragging a buddy into a contact, this is the delay before @@ -2736,7 +2737,17 @@ } gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), x, y, &path, NULL, NULL, NULL); - gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); + gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect); + + /* Only autoexpand when in the middle of the cell to avoid annoying un-intended expands */ + if (y < rect.y + (rect.height / 3) || + y > rect.y + (2 * (rect.height /3))) + return FALSE; + + rect.height = rect.height / 3; + rect.y += rect.height; + + gtkblist->tip_rect = rect; if (path) gtk_tree_path_free(path); @@ -3235,6 +3246,9 @@ else if (purple_presence_is_idle(p) && size == PIDGIN_STATUS_ICON_SMALL) ret = gtk_widget_render_icon (GTK_WIDGET(gtkblist->treeview), PIDGIN_STOCK_STATUS_AVAILABLE_I, icon_size, "GtkTreeView"); + else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE)) + ret = gtk_widget_render_icon(GTK_WIDGET(gtkblist->treeview), PIDGIN_STOCK_STATUS_INVISIBLE, + icon_size, "GtkTreeView"); else ret = gtk_widget_render_icon(GTK_WIDGET(gtkblist->treeview), PIDGIN_STOCK_STATUS_AVAILABLE, icon_size, "GtkTreeView");
--- a/pidgin/gtkconv.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkconv.c Fri Jun 01 23:53:05 2007 +0000 @@ -235,6 +235,10 @@ return FALSE; } + if (gdk_window_get_state(gtkconv->win->window->window) & GDK_WINDOW_STATE_MAXIMIZED) { + return FALSE; + } + /* I find that I resize the window when it has a bunch of conversations in it, mostly so that the * tab bar will fit, but then I don't want new windows taking up the entire screen. I check to see * if there is only one conversation in the window. This way we'll be setting new windows to the @@ -6951,6 +6955,9 @@ purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/tab_side", GTK_POS_TOP); purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/scrollback_lines", 4000); + purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font", TRUE); + purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", ""); + /* Conversations -> Chat */ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/chat"); purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width", 410);
--- a/pidgin/gtkimhtmltoolbar.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Fri Jun 01 23:53:05 2007 +0000 @@ -852,6 +852,64 @@ update_buttons(toolbar); } + +/* This comes from gtkmenutoolbutton.c from gtk+ + * Copyright (C) 2003 Ricardo Fernandez Pascual + * Copyright (C) 2004 Paolo Borelli + */ +menu_position_func (GtkMenu *menu, + int *x, + int *y, + gboolean *push_in, + GtkWidget *widget) +{ + GtkRequisition req; + GtkRequisition menu_req; + GtkOrientation orientation; + GtkTextDirection direction; + GdkRectangle monitor; + gint monitor_num; + GdkScreen *screen; + + gtk_widget_size_request (GTK_WIDGET (widget), &menu_req); + + direction = gtk_widget_get_direction (widget); + + screen = gtk_widget_get_screen (GTK_WIDGET (menu)); + monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window); + if (monitor_num < 0) + monitor_num = 0; + gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); + + gdk_window_get_origin (widget->window, x, y); + *x += widget->allocation.x; + *y += widget->allocation.y; + + if (direction == GTK_TEXT_DIR_LTR) + *x += MAX (widget->allocation.width - menu_req.width, 0); + else if (menu_req.width > widget->allocation.width) + *x -= menu_req.width - widget->allocation.width; + + if ((*y + widget->allocation.height + menu_req.height) <= monitor.y + monitor.height) + *y += widget->allocation.height; + else if ((*y - menu_req.height) >= monitor.y) + *y -= menu_req.height; + else if (monitor.y + monitor.height - (*y + widget->allocation.height) > *y) + *y += widget->allocation.height; + else + *y -= menu_req.height; + *push_in = FALSE; +} + +static void pidgin_menu_clicked(GtkWidget *button, GtkMenu *menu) { + gtk_widget_show_all(menu); + gtk_menu_popup(menu, NULL, NULL, menu_position_func, button, 0, gtk_get_current_event_time()); +} + +static void pidgin_menu_deactivate(GtkWidget *menu, GtkToggleButton *button) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE); +} + enum { LAST_SIGNAL }; @@ -899,12 +957,91 @@ gobject_class->finalize = gtk_imhtmltoolbar_finalize; } +static void gtk_imhtmltoolbar_create_old_buttons(GtkIMHtmlToolbar *toolbar) +{ + GtkWidget *button; + /* Bold */ + button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_BOLD); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(do_bold), toolbar); + toolbar->bold = button; + + + /* Italic */ + button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_ITALIC); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(do_italic), toolbar); + toolbar->italic = button; + + /* Underline */ + button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_UNDERLINE); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(do_underline), toolbar); + toolbar->underline = button; + + /* Increase font size */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_LARGER); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(do_big), toolbar); + toolbar->larger_size = button; + + /* Decrease font size */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(do_small), toolbar); + toolbar->smaller_size = button; + + /* Font Face */ + + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FONT_FACE); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(toggle_font), toolbar); + toolbar->font = button; + + /* Foreground Color */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FGCOLOR); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(toggle_fg_color), toolbar); + toolbar->fgcolor = button; + + /* Background Color */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_BGCOLOR); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(toggle_bg_color), toolbar); + toolbar->bgcolor = button; + + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_LINK); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(insert_link_cb), toolbar); + toolbar->link = button; + + /* Insert IM Image */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(insert_image_cb), toolbar); + toolbar->image = button; + + /* Insert Smiley */ + button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(insert_smiley_cb), toolbar); + toolbar->smiley = button; + + +} + static void gtk_imhtmltoolbar_init (GtkIMHtmlToolbar *toolbar) { GtkWidget *hbox = GTK_WIDGET(toolbar); + GtkWidget *bbox; + GtkWidget *image; + GtkWidget *label; + GtkWidget *insert_button; + GtkWidget *font_button; + GtkWidget *font_menu; + GtkWidget *insert_menu; GtkWidget *button; GtkWidget *sep; - GtkSizeGroup *sg; toolbar->imhtml = NULL; toolbar->font_dialog = NULL; @@ -917,164 +1054,116 @@ toolbar->tooltips = gtk_tooltips_new(); gtk_box_set_spacing(GTK_BOX(toolbar), 3); - sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); + + gtk_imhtmltoolbar_create_old_buttons(toolbar); /* Bold */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_BOLD); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Bold"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_bold), toolbar); + font_button = gtk_toggle_button_new(); + gtk_button_set_relief(GTK_BUTTON(font_button), GTK_RELIEF_NONE); + bbox = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(font_button), bbox); + image = gtk_image_new_from_stock(GTK_STOCK_BOLD, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); + label = gtk_label_new_with_mnemonic(_("_Font")); + gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), font_button, FALSE, FALSE, 0); + gtk_widget_show_all(font_button); - toolbar->bold = button; + font_menu = gtk_menu_new(); + + button = gtk_check_menu_item_new_with_mnemonic(_("_Bold")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->bold); + gtk_menu_shell_append(font_menu, button); - /* Italic */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_ITALIC); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Italic"), NULL); + button = gtk_check_menu_item_new_with_mnemonic(_("_Italic")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->italic); + gtk_menu_shell_append(font_menu, button); + + button = gtk_check_menu_item_new_with_mnemonic(_("_Underline")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->underline); + gtk_menu_shell_append(font_menu, button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_italic), toolbar); + button = gtk_menu_item_new_with_mnemonic(_("_Larger")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->larger_size); + gtk_menu_shell_append(font_menu, button); - toolbar->italic = button; + button = gtk_menu_item_new_with_mnemonic(_("_Normal")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->normal_size); + gtk_menu_shell_append(font_menu, button); + + button = gtk_menu_item_new_with_mnemonic(_("_Smaller")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->smaller_size); + gtk_menu_shell_append(font_menu, button); - /* Underline */ - button = pidgin_pixbuf_toolbar_button_from_stock(GTK_STOCK_UNDERLINE); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Underline"), NULL); + button = gtk_menu_item_new_with_mnemonic(_("_Font face")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->font); + gtk_menu_shell_append(font_menu, button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_underline), toolbar); + button = gtk_menu_item_new_with_mnemonic(_("_Foreground color")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->fgcolor); + gtk_menu_shell_append(font_menu, button); - toolbar->underline = button; + button = gtk_menu_item_new_with_mnemonic(_("_Background color")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->bgcolor); + gtk_menu_shell_append(font_menu, button); + + g_signal_connect(G_OBJECT(font_button), "clicked", G_CALLBACK(pidgin_menu_clicked), font_menu); + g_signal_connect(G_OBJECT(font_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), font_button); /* Sep */ sep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); - - /* Increase font size */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_LARGER); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Larger font size"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_big), toolbar); - - toolbar->larger_size = button; - - /* Decrease font size */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Smaller font size"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(do_small), toolbar); - - toolbar->smaller_size = button; - - /* Sep */ - sep = gtk_vseparator_new(); - gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); - - /* Font Face */ - - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FONT_FACE); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Font face"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_font), toolbar); - - toolbar->font = button; - - /* Foreground Color */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_FGCOLOR); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Foreground font color"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_fg_color), toolbar); - - toolbar->fgcolor = button; - - /* Background Color */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_BGCOLOR); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Background color"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(toggle_bg_color), toolbar); - - toolbar->bgcolor = button; - - /* Sep */ - sep = gtk_vseparator_new(); - gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); + gtk_widget_show_all(sep); /* Reset Formatting */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_CLEAR); - gtk_size_group_add_widget(sg, button); + button = gtk_toggle_button_new(); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + bbox = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(button), bbox); + image = gtk_image_new_from_stock(PIDGIN_STOCK_CLEAR, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); + label = gtk_label_new_with_mnemonic(_("_Reset font")); + gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("Reset formatting"), NULL); - + gtk_widget_show_all(button); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_formatting_cb), toolbar); - toolbar->clear = button; /* Sep */ sep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); + gtk_widget_show_all(sep); /* Insert Link */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_LINK); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Insert link"), NULL); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_link_cb), toolbar); - - toolbar->link = button; - - /* Insert IM Image */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Insert image"), NULL); + insert_button = gtk_toggle_button_new(); + gtk_button_set_relief(GTK_BUTTON(insert_button), GTK_RELIEF_NONE); + bbox = gtk_hbox_new(FALSE, 3); + gtk_container_add(GTK_CONTAINER(insert_button), bbox); + image = gtk_image_new_from_stock(PIDGIN_STOCK_TOOLBAR_INSERT, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); + label = gtk_label_new_with_mnemonic(_("_Insert")); + gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), insert_button, FALSE, FALSE, 0); + gtk_widget_show_all(insert_button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_image_cb), toolbar); - - toolbar->image = button; + insert_menu = gtk_menu_new(); + + button = gtk_menu_item_new_with_mnemonic(_("_Smiley")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->smiley); + gtk_menu_shell_append(insert_menu, button); + + button = gtk_menu_item_new_with_mnemonic(_("_Image")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->image); + gtk_menu_shell_append(insert_menu, button); - /* Insert Smiley */ - button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SMILEY); - gtk_size_group_add_widget(sg, button); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(toolbar->tooltips, button, _("Insert smiley"), NULL); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(insert_smiley_cb), toolbar); - - toolbar->smiley = button; - + button = gtk_menu_item_new_with_mnemonic(_("_Link")); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gtk_button_clicked), toolbar->link); + gtk_menu_shell_append(insert_menu, button); + + g_signal_connect(G_OBJECT(insert_button), "clicked", G_CALLBACK(pidgin_menu_clicked), insert_menu); + g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button); toolbar->sml = NULL; - gtk_widget_show_all(hbox); } GtkWidget *gtk_imhtmltoolbar_new()
--- a/pidgin/gtkmain.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkmain.c Fri Jun 01 23:53:05 2007 +0000 @@ -473,6 +473,9 @@ #else debug_enabled = FALSE; #endif + + /* This is the first Glib function call. Make sure to initialize GThread bfeore then */ + g_thread_init(NULL); #ifdef ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR);
--- a/pidgin/gtkprefs.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkprefs.c Fri Jun 01 23:53:05 2007 +0000 @@ -382,7 +382,7 @@ new_theme = current_smiley_theme; description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n" "<span size='smaller' foreground='white'>%s</span>", - new_theme->name, new_theme->author, new_theme->desc); + _(new_theme->name), _(new_theme->author), _(new_theme->desc)); gtk_list_store_set(smiley_theme_store, &iter, 1, description, -1); g_free(description); @@ -391,7 +391,7 @@ if (gtk_tree_model_get_iter(model, &iter, oldpath)) { description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n" "<span size='smaller' foreground='dim grey'>%s</span>", - old_theme->name, old_theme->author, old_theme->desc); + _(old_theme->name), _(old_theme->author), _(old_theme->desc)); gtk_list_store_set(smiley_theme_store, &iter, 1, description, -1); g_free(description); @@ -426,7 +426,7 @@ struct smiley_theme *theme = themes->data; char *description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n" "<span size='smaller' foreground='dim grey'>%s</span>", - theme->name, theme->author, theme->desc); + _(theme->name), _(theme->author), _(theme->desc)); gtk_list_store_append (smiley_theme_store, &iter); /* @@ -881,6 +881,15 @@ return ret; } +#if GTK_CHECK_VERSION(2,4,0) +static void +pidgin_custom_font_set(GtkFontButton *font_button, gpointer nul) +{ + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", + gtk_font_button_get_font_name(font_button)); +} +#endif + static GtkWidget * conv_page() { @@ -889,9 +898,17 @@ GtkWidget *toolbar; GtkWidget *iconpref1; GtkWidget *iconpref2; + GtkWidget *fontpref; GtkWidget *imhtml; GtkWidget *frame; +#if GTK_CHECK_VERSION(2,4,0) + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *font_button; + const char *font_name; +#endif + ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER); @@ -922,6 +939,26 @@ pidgin_prefs_checkbox(_("F_lash window when IMs are received"), PIDGIN_PREFS_ROOT "/win32/blink_im", vbox); #endif +#if GTK_CHECK_VERSION(2,4,0) + vbox = pidgin_make_frame(ret, _("Font")); + if (purple_running_gnome()) + fontpref = pidgin_prefs_checkbox(_("Use document font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox); + else + fontpref = pidgin_prefs_checkbox(_("Use font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox); + hbox = gtk_hbox_new(FALSE, 3); + label = gtk_label_new_with_mnemonic(_("Conversation _font:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + font_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font"); + font_button = gtk_font_button_new_with_font(purple_prefs_get_string(font_name ? font_name : NULL)); + gtk_font_button_set_show_style(GTK_FONT_BUTTON(font_button), TRUE); + gtk_box_pack_start(GTK_BOX(hbox), font_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) + gtk_widget_set_sensitive(hbox, FALSE); + g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(pidgin_toggle_sensitive), hbox); + g_signal_connect(G_OBJECT(font_button), "font-set", G_CALLBACK(pidgin_custom_font_set), NULL); +#endif + vbox = pidgin_make_frame(ret, _("Default Formatting")); frame = pidgin_create_imhtml(TRUE, &imhtml, &toolbar, NULL);
--- a/pidgin/gtkstatusbox.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkstatusbox.c Fri Jun 01 23:53:05 2007 +0000 @@ -2029,6 +2029,10 @@ int w, h; GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM); gtk_icon_size_lookup(icon_size, &w, &h); + if (height > width) + w = width * h / height; + else if (width > height) + h = height * w / width; gdk_pixbuf_loader_set_size(loader, w, h); #endif }
--- a/pidgin/gtkthemes.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkthemes.c Fri Jun 01 23:53:05 2007 +0000 @@ -150,7 +150,7 @@ } else if (!g_ascii_strncasecmp(i, "Name=", strlen("Name="))) { int len; g_free(theme->name); - theme->name = g_strdup(i+ strlen("Name=")); + theme->name = g_strdup(i + strlen("Name=")); len = strlen(theme->name); theme->name[len-1] = 0; if(len > 2 && theme->name[len-2] == '\r')
--- a/pidgin/gtkutils.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/gtkutils.c Fri Jun 01 23:53:05 2007 +0000 @@ -94,6 +94,7 @@ void pidgin_setup_imhtml(GtkWidget *imhtml) { + PangoFontDescription *desc = NULL; g_return_if_fail(imhtml != NULL); g_return_if_fail(GTK_IS_IMHTML(imhtml)); @@ -104,10 +105,12 @@ gtk_imhtml_set_funcs(GTK_IMHTML(imhtml), >kimhtml_cbs); - /* Use the GNOME "document" font, if applicable */ - if (purple_running_gnome()) { + if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) { + const char *font = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font"); + desc = pango_font_description_from_string(font); + } else if (purple_running_gnome()) { + /* Use the GNOME "document" font, if applicable */ char *path, *font; - PangoFontDescription *desc = NULL; if ((path = g_find_program_in_path("gconftool-2"))) { g_free(path); @@ -118,11 +121,11 @@ } desc = pango_font_description_from_string(font); g_free(font); - - if (desc) { - gtk_widget_modify_font(imhtml, desc); - pango_font_description_free(desc); - } + } + + if (desc) { + gtk_widget_modify_font(imhtml, desc); + pango_font_description_free(desc); } } @@ -1454,8 +1457,7 @@ else purple_request_choice(NULL, NULL, _("You have dragged an image"), - (ft ? _("You can send this image as a file transfer or " - "embed it into this message, or use it as the buddy icon for this user.") : + (ft ? _("You can send this image as a file transfer, or use it as the buddy icon for this user.") : _("You can insert this image into this message, or use it as the buddy icon for this user")), (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE), "OK", (GCallback)dnd_image_ok_callback,
--- a/pidgin/pidginstock.c Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/pidginstock.c Fri Jun 01 23:53:05 2007 +0000 @@ -151,6 +151,7 @@ { PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
--- a/pidgin/pidginstock.h Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/pidginstock.h Fri Jun 01 23:53:05 2007 +0000 @@ -116,6 +116,7 @@ #define PIDGIN_STOCK_TOOLBAR_FONT_FACE "pidgin-font-face" #define PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER "pidgin-text-smaller" #define PIDGIN_STOCK_TOOLBAR_TEXT_LARGER "pidgin-text-larger" +#define PIDGIN_STOCK_TOOLBAR_INSERT "pidgin-insert" #define PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE "pidgin-insert-image" #define PIDGIN_STOCK_TOOLBAR_INSERT_LINK "pidgin-insert-link" #define PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW "pidgin-message-new"
--- a/pidgin/pixmaps/emotes/default/22/Makefile.am Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/pixmaps/emotes/default/22/Makefile.am Fri Jun 01 23:53:05 2007 +0000 @@ -173,8 +173,15 @@ yin-yang.png pidginsmileypixdir = $(datadir)/pixmaps/pidgin/emotes/default +pidginsmileypix_in_files = default.theme.in pidginsmileypix_DATA = \ $(SMILEYS) \ theme -EXTRA_DIST = $(pidginsmileypix_DATA) +theme: default.theme.in + sed -e 's/^_Name=/Name=/' \ + -e 's/^_Description=/Description=/' \ + -e 's/^_Author=/Author=/' \ + $< > $@ + +EXTRA_DIST = $(pidginsmileypix_DATA) $(pidginsmileypix_in_files)
--- a/pidgin/pixmaps/emotes/default/22/Makefile.mingw Thu May 31 00:40:46 2007 +0000 +++ b/pidgin/pixmaps/emotes/default/22/Makefile.mingw Fri Jun 01 23:53:05 2007 +0000 @@ -10,11 +10,13 @@ datadir = $(PIDGIN_INSTALL_DIR) include ./Makefile.am -.PHONY: install +.PHONY: install clean -install: +install: theme if test '$(pidginsmileypix_DATA)'; then \ mkdir -p $(pidginsmileypixdir); \ cp $(pidginsmileypix_DATA) $(pidginsmileypixdir); \ fi; +clean: + rm -f theme
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pixmaps/emotes/default/22/default.theme.in Fri Jun 01 23:53:05 2007 +0000 @@ -0,0 +1,357 @@ +_Name=Default +_Description=Pidgin smileys +Icon=smile.png +Author=Hylke Bons + +# default smileys +[default] +smile.png :) :-) +smile-big.png :-D :-d :D :d +sad.png :-( :( +wink.png ;-) ;) +tongue.png :P :-P :-p :p +shock.png =-O =-o +kiss.png :-* +glasses-cool.png 8-) +embarrassed.png :-[ +crying.png :'( +thinking.png :-/ :-\\ +angel.png O:-) o:-) +shut-mouth.png :-X +moneymouth.png :-$ +foot-in-mouth.png :-! +shout.png >:o >:O +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Following AIM 6.1 +[AIM] +smile.png :-) :) +wink.png ;-) ;) +sad.png :-( :( +tongue.png :-P :P +shock.png =-O +kiss.png :-* +shout.png >:o +smile-big.png :-D :D +moneymouth.png :-$ +foot-in-mouth.png :-! +embarrassed.png :-[ +angel.png O:-) +thinking.png :-\\ :-/ +crying.png :'( +shut-mouth.png :-X +glasses-cool.png 8-) +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Following Windows Live Messenger 8.1 +[MSN] +smile.png :) :-) +smile-big.png :D :d :-D :-d +wink.png ;) ;-) +shock.png :-O :-o :O :o +tongue.png :P :p :-P :-p +glasses-cool.png (H) (h) +angry.png :@ :-@ +embarrassed.png :$ :-$ +confused.png :S :s :-S :-s +sad.png :( :-( +crying.png :'( +neutral.png :| :-| +devil.png (6) +angel.png (A) (a) +love.png (L) (l) +love-over.png (U) (u) +msn.png (M) (m) +cat.png (@) +dog.png (&) +moon.png (S) +star.png (*) +film.png (~) +musical-note.png (8) +mail.png (E) (e) +rose.png (F) (f) +rose-dead.png (W) (w) +clock.png (O) (o) +kiss.png (K) (k) +present.png (G) (g) +cake.png (^) +camera.png (P) (p) +lamp.png (I) (i) +coffee.png (C) (c) +phone.png (T) (t) +hug-left.png ({) +hug-right.png (}) +beer.png (B) (b) +drink.png (D) (d) +boy.png (Z) (z) +girl.png (X) (x) +good.png (Y) (y) +bad.png (N) (n) +vampire.png :[ :-[ +goat.png (nah) +sun.png (#) +rainbow.png (R) (r) +quiet.png :-# +teeth.png 8o| +glasses-nerdy.png 8-| +sarcastic.png ^o) +secret.png :-* +sick.png +o( +snail.png (sn) +turtle.png (tu) +plate.png (pl) +bowl.png (||) +pizza.png (pi) +soccerball.png (so) +car.png (au) +airplane.png (ap) +umbrella.png (um) +island.png (ip) +computer.png (co) +mobile.png (mp) +brb.png (brb) +rain.png (st) +highfive.png (h5) +coins.png (mo) +sheep.png (bah) +dont-know.png :^) +thinking.png *-) +thunder.png (li) +party.png <:o) +eyeroll.png 8-) +yawn.png |-) +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Hidden MSN emotes +sigarette.png (ci) (CI) +handcuffs.png (%) +console.png (xx) (XX) +fingers-crossed.png (yn) (YN) + +### Following QQ 2006 +[QQ] +shock.png /惊讶 /:O /jy /surprised +curl-lip.png /撇嘴 /:~ /pz /curl_lip +desire.png /色 /:* /se /desire +dazed.png /发呆 /:| /dazed +party.png /得意 /8-) /dy /revel +crying.png /流泪 /:< /ll /cry +bashful.png /害羞 /:$ /hx /bashful +shut-mouth.png /闭嘴 /:X /bz /shut_mouth +sleepy.png /睡 /:Z /shui /sleep +weep.png /大哭 /:'( /dk /weep +embarrassed.png /尴尬 /:-| /gg /embarassed +pissed-off.png /发怒 /:@ /fn /pissed_off +act-up.png /调皮 /:P /tp /act_up +smile-big.png /呲牙 /:D /cy /toothy_smile +smile.png /微笑 /:) /wx /small_smile +sad.png /难过 /:( /ng /sad +glasses-cool.png /酷 /:+ /kuk /cool +doctor.png /非典 /:# /feid /SARS +silly.png /抓狂 /:Q /zk /crazy +sick.png /吐 /:T /tu /vomit +snicker.png /偷笑 /;p /tx /titter +cute.png /可爱 /;-D /ka /cute +disdain.png /白眼 /;d /by /disdain +arrogant.png /傲慢 /;o /am /arrogant +starving.png /饥饿 /:g /jie /starving +yawn.png /困 /|-) /kun /sleepy +terror.png /惊恐 /:! /jk /terror +sweat.png /流汗 /:L /sweat +smirk.png /憨笑 /:> /hanx /smirk +soldier.png /大兵 /:; /db /soldier +struggle.png /奋斗 /;f /fendou /struggle +curse.png /咒骂 /:-S /zhm /curse +question.png /疑问 /? /yiw /question +quiet.png /嘘... /;x /xu /shh +hypnotized.png /晕 /;@ /yun /dizzy +excruciating.png /折磨 /:8 /zhem /excrutiating +freaked-out.png /衰 /;! /shuai /freaked_out +skeleton.png /骷髅 /!!! /kl /skeleton +hammer.png /敲打 /xx /qiao /hammer +bye.png /再见 /bye /zj /bye +go-away.png /闪人 /go /shan /go +tremble.png /发抖 /shake /fad /shake +in-love.png /爱情 /love /aiq /love +jump.png /跳 /jump /tiao /jump +search.png /找 /find /zhao /search +lashes.png /美眉 /& /mm /beautiful_eyebrows +pig.png /猪头 /pig /zt /pig +cat.png /猫咪 /cat /mm /cat +dog.png /小狗 /dog /xg /dog +hug-left.png /拥抱 /hug /yb /hug +coins.png /钱 /$ /qianc /money +lamp.png /灯泡 /! /dp /lightbulb +bowl.png /酒杯 /cup /bei /cup +cake.png /蛋糕 /cake /dg /cake +thunder.png /闪电 /li /shd /lightning +bomb.png /炸弹 /bome /zhd /bomb +knife.png /刀 /kn /dao /knife +soccerball.png /足球 /footb /zq /soccer +musical-note.png /音乐 /music /yy /music +poop.png /便便 /shit /bb /shit +coffee.png /咖啡 /coffee /kf /coffee +eat.png /饭 /eat /fan /eat +pill.png /药丸 /pill /yw /pill +rose.png /玫瑰 /rose /mg /rose +wilt.png /凋谢 /fade /dx /wilt +kiss.png /吻 /kiss /wen /kiss +love.png /爱心 /heart /xin /heart +love-over.png /心碎 /break /xs /broken_heart +meeting.png /会议 /meeting /hy /meeting +present.png /礼物 /gift /lw /gift +phone.png /电话 /phone /dh /phone +clock.png /时间 /time /sj /time +mail.png /邮件 /email /yj /email +tv.png /电视 /TV /ds /TV +sun.png /太阳 /sun /ty /sun +moon.png /月亮 /moon /yl /moon +good.png /强 /strong /qiang /thumbs_up +bad.png /弱 /weak /ruo /thumbs_down +handshake.png /握手 /share /ws /handshake +victory.png /胜利 /v /shl /victory +beauty.png /美女 /<J> /mn /beauty +qq.png /Q仔 /<QQ> /qz /qq +blowkiss.png /飞吻 /<L> /fw /blow_kiss +angry.png /怄火 /<O> /oh /angry +liquor.png /白酒 /<B> /bj /baijiu +can.png /汽水 /<U> /qsh /soda +watermelon.png /西瓜 /<W> /xigua /watermelon +rain.png /下雨 /<!!> /xy /rain +cloudy.png /多云 /<~> /duoy /cloudy +snowman.png /雪人 /<Z> /xr /snowman +star.png /星星 /<*> /xixing /star +girl.png /女 /<00> /nv /woman +boy.png /男 /<11> /nan /man +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Following ICQ 5.1 +[ICQ] +smile.png :-) :) +sad.png :-( :( +wink.png ;-) ;) +tongue.png :-P :P +laugh.png *JOKINGLY* +crying.png :'( +#*KISSED* +kiss.png :-* +embarrassed.png :-[ +angel.png O:-) +shut-mouth.png :-X :X +thinking.png :-\\ :-/ +shout.png >:o >:O +smile-big.png :-D :D +moneymouth.png :-$ +shock.png =-O +glasses-cool.png 8-) +#[:-} +sleepy.png *TIRED* +sick.png :-! +#*STOP* +#*KISSING* +devil.png ]:-> +rose.png @}->-- +bomb.png @= +good.png *THUMBS\ UP* +beer.png *DRINK* +in-love.png *IN\ LOVE* +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Following Yahoo! Messenger 8.1 +[Yahoo] +smile.png :) :-) +question.png :-/ :-\\ +shock.png :-O :O :-o :o +devil.png >:) +angel.png O:-) o:-) 0:-) +sick.png :-& +yawn.png (:| +hypnotized.png @-) +#on_the_phone :)] MISSING: "Wait,I'm phoning!" (not phone.png) => smily showing phone and hand ("stop") +sad.png :( :-( +in-love.png :x :-x :X :-X +angry.png X-( x-( X( x( +crying.png :(( +glasses-nerdy.png :-B :-b +quiet.png :-$ +drool.png =P~ =p~ +lying.png :^O :^o +call-me.png :-c +wink.png ;) ;-) +embarrassed.png :"> +mean.png :-> :> +laugh.png :)) :-)) +bye.png =; +arrogant.png [-( +thinking.png :-? +waiting.png :-w :-W +#at_wits_end ~x( ~X( MISSING: "Why.Does.This.Not.Work.AAAAARGH!!" => angry smily shouting and pulling hair off +smile-big.png :D :-D :d :-d +tongue.png :-P :P :-p :p +glasses-cool.png B-) b-) +neutral.png :| :-| +sleepy.png I-) i-) |-) +clown.png :o) :O) +doh.png #-o #-O +weep.png :-< +go-away.png :-h +lashes.png ;;) +kiss.png :-* :* +confused.png :-S :-s +sarcastic.png /:) +eyeroll.png 8-| +silly.png 8-} +clap.png =D> =d> +mad-tongue.png >:P >:p +#timeout :-t :-T MISSING: "Let's have a break." +hug-left.png >:D< >:d< +love-over.png =(( +sweat.png #:-S #:-s +rotfl.png =)) +#loser L-) l-) MISSING/YAHOO 6: "Loser!" +party.png <:-P <:-p +nailbiting.png :-SS :-Ss :-sS :-ss +cowboy.png <):) +desire.png 8-> +! skywalker.png C:-) c:-) C:) c:) +! monkey.png :-(|) + +### Hidden Yahoo emotes +alien.png =:) >-) +beat-up.png b-( B-( +chicken.png ~:> +coffee.png ~o) ~O) +cow.png 3:-O 3:-o +dance.png \\:D/ \\:d/ +rose.png @};- +dont-know.png :-L :-l +skeleton.png 8-X 8-x +lamp.png *-:) +monkey.png :(|) +coins.png $-) +peace.png :)>- +pig.png :@) +pray.png [-o< [-O< +pumpkin.png (~~) +shame.png [-X [-x +flag.png **== +clover.png %%- +musical-note.png :-" +giggle.png ;)) +worship.png ^:)^ +star.png (*) +#waving.png >:/ +#talktohand.png :-@ +#youkiddingme.png :-j :-J + +### These only work in a certain IMvironment +#malefighter1.png o-> O-> +#malefighter2.png o=> O=> +#femalefighter.png o-+ O-+ +yin-yang.png (%) +
--- a/pidgin/pixmaps/emotes/default/22/theme Thu May 31 00:40:46 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -Name=Default -Description=Pidgin smileys -Icon=smile.png -Author=Hylke Bons - -# default smileys -[default] -smile.png :) :-) -smile-big.png :-D :-d :D :d -sad.png :-( :( -wink.png ;-) ;) -tongue.png :P :-P :-p :p -shock.png =-O =-o -kiss.png :-* -glasses-cool.png 8-) -embarrassed.png :-[ -crying.png :'( -thinking.png :-/ :-\\ -angel.png O:-) o:-) -shut-mouth.png :-X -moneymouth.png :-$ -foot-in-mouth.png :-! -shout.png >:o >:O -! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) - -### Following AIM 6.1 -[AIM] -smile.png :-) :) -wink.png ;-) ;) -sad.png :-( :( -tongue.png :-P :P -shock.png =-O -kiss.png :-* -shout.png >:o -smile-big.png :-D :D -moneymouth.png :-$ -foot-in-mouth.png :-! -embarrassed.png :-[ -angel.png O:-) -thinking.png :-\\ :-/ -crying.png :'( -shut-mouth.png :-X -glasses-cool.png 8-) -! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) - -### Following Windows Live Messenger 8.1 -[MSN] -smile.png :) :-) -smile-big.png :D :d :-D :-d -wink.png ;) ;-) -shock.png :-O :-o :O :o -tongue.png :P :p :-P :-p -glasses-cool.png (H) (h) -angry.png :@ :-@ -embarrassed.png :$ :-$ -confused.png :S :s :-S :-s -sad.png :( :-( -crying.png :'( -neutral.png :| :-| -devil.png (6) -angel.png (A) (a) -love.png (L) (l) -love-over.png (U) (u) -msn.png (M) (m) -cat.png (@) -dog.png (&) -moon.png (S) -star.png (*) -film.png (~) -musical-note.png (8) -mail.png (E) (e) -rose.png (F) (f) -rose-dead.png (W) (w) -clock.png (O) (o) -kiss.png (K) (k) -present.png (G) (g) -cake.png (^) -camera.png (P) (p) -lamp.png (I) (i) -coffee.png (C) (c) -phone.png (T) (t) -hug-left.png ({) -hug-right.png (}) -beer.png (B) (b) -drink.png (D) (d) -boy.png (Z) (z) -girl.png (X) (x) -good.png (Y) (y) -bad.png (N) (n) -vampire.png :[ :-[ -goat.png (nah) -sun.png (#) -rainbow.png (R) (r) -quiet.png :-# -teeth.png 8o| -glasses-nerdy.png 8-| -sarcastic.png ^o) -secret.png :-* -sick.png +o( -snail.png (sn) -turtle.png (tu) -plate.png (pl) -bowl.png (||) -pizza.png (pi) -soccerball.png (so) -car.png (au) -airplane.png (ap) -umbrella.png (um) -island.png (ip) -computer.png (co) -mobile.png (mp) -brb.png (brb) -rain.png (st) -highfive.png (h5) -coins.png (mo) -sheep.png (bah) -dont-know.png :^) -thinking.png *-) -thunder.png (li) -party.png <:o) -eyeroll.png 8-) -yawn.png |-) -! skywalker.png C:-) c:-) C:) c:) -! monkey.png :-(|) - -### Hidden MSN emotes -sigarette.png (ci) (CI) -handcuffs.png (%) -console.png (xx) (XX) -fingers-crossed.png (yn) (YN) - -### Following QQ 2006 -[QQ] -shock.png /惊讶 /:O /jy /surprised -curl-lip.png /撇嘴 /:~ /pz /curl_lip -desire.png /色 /:* /se /desire -dazed.png /发呆 /:| /dazed -party.png /得意 /8-) /dy /revel -crying.png /流泪 /:< /ll /cry -bashful.png /害羞 /:$ /hx /bashful -shut-mouth.png /闭嘴 /:X /bz /shut_mouth -sleepy.png /睡 /:Z /shui /sleep -weep.png /大哭 /:'( /dk /weep -embarrassed.png /尴尬 /:-| /gg /embarassed -pissed-off.png /发怒 /:@ /fn /pissed_off -act-up.png /调皮 /:P /tp /act_up -smile-big.png /呲牙 /:D /cy /toothy_smile -smile.png /微笑 /:) /wx /small_smile -sad.png /难过 /:( /ng /sad -glasses-cool.png /酷 /:+ /kuk /cool -doctor.png /非典 /:# /feid /SARS -silly.png /抓狂 /:Q /zk /crazy -sick.png /吐 /:T /tu /vomit -snicker.png /偷笑 /;p /tx /titter