Mercurial > pidgin
changeset 22753:3b14215d2ca4
merge of 'a2c4bf662d1fdab8c870c1ebbca30968af4bb80a'
and 'caaa65e1c157e6cb43219237f88a4ad298f3bbf5'
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 28 Apr 2008 06:27:11 +0000 |
parents | a184ac4eace6 (current diff) 29cd77930050 (diff) |
children | 8c3f6126759c |
files | finch/libgnt/pygnt/Files.txt finch/libgnt/pygnt/Makefile.am finch/libgnt/pygnt/Makefile.make finch/libgnt/pygnt/README.txt finch/libgnt/pygnt/common.c finch/libgnt/pygnt/common.h finch/libgnt/pygnt/dbus-gnt finch/libgnt/pygnt/example/rss/gnthtml.py finch/libgnt/pygnt/example/rss/gntrss-ui.py finch/libgnt/pygnt/example/rss/gntrss.py finch/libgnt/pygnt/file.py finch/libgnt/pygnt/gendef.sh finch/libgnt/pygnt/gnt.override finch/libgnt/pygnt/gntbox.override finch/libgnt/pygnt/gntfilesel.override finch/libgnt/pygnt/gntmodule.c finch/libgnt/pygnt/gnttree.override finch/libgnt/pygnt/gntwidget.override finch/libgnt/pygnt/test.py |
diffstat | 92 files changed, 1701 insertions(+), 2843 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Thu Apr 17 07:12:45 2008 +0000 +++ b/COPYRIGHT Mon Apr 28 06:27:11 2008 +0000 @@ -360,6 +360,7 @@ Dossy Shiobara Michael Shkutkov Shreevatsa R +Dylan Simon <dylan@dylex.net> Ettore Simone John Silvestri Craig Slusher
--- a/ChangeLog Thu Apr 17 07:12:45 2008 +0000 +++ b/ChangeLog Mon Apr 28 06:27:11 2008 +0000 @@ -5,10 +5,17 @@ * In MySpaceIM, messages from spambots are discarded (Justin Williams) * Strip mIRC formatting codes from quit and part messages. * IRC now displays ban lists in-channel for joined channels. - + * Fixed a bug where the list of loaded plugins would get removed when + switching between different operating systems. + Pidgin: * The typing notification in the conversation history can be disabled or customized (font, color etc.) in .gtkrc-2.0. + * Added a plugin (not built by default) which adds a Send button back + to the conversation window. People without physical keyboards have a + hard time with the lack of the button. + * Clicking on the buddyicon in the conversation window toggles the size of + the icon between small and large. General: * The configure script now dies on more absent dependencies. The
--- a/ChangeLog.API Thu Apr 17 07:12:45 2008 +0000 +++ b/ChangeLog.API Mon Apr 28 06:27:11 2008 +0000 @@ -1,5 +1,17 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.x.x: + perl: + Added: + * Purple::Prefs::get_children_names. + * Purple::timeout_remove. + Changed: + * Purple::timeout_add now returns a handle which can be used + to remove the timeout. + * Callbacks to Purple::Util::fetch_url and the + Purple::Request::* functions can now be specified as both + strings (the name of the callback function) and as coderefs. + version 2.4.0 (02/29/2008): libpurple: Added:
--- a/autogen.sh Thu Apr 17 07:12:45 2008 +0000 +++ b/autogen.sh Mon Apr 28 06:27:11 2008 +0000 @@ -49,13 +49,21 @@ PACKAGE="Pidgin" ARGS_FILE="autogen.args" +libtoolize="libtoolize" +case $(uname -s) in + Darwin*) + libtoolize="glibtoolize" + ;; + *) +esac + ############################################################################### # Some helper functions ############################################################################### check () { CMD=$1 - echo -n "checking for ${CMD}... " + printf "%s" "checking for ${CMD}... " BIN=`which ${CMD} 2> /dev/null` if [ x"${BIN}" = x"" ] ; then @@ -71,7 +79,7 @@ CMD=$1 shift - echo -n "running ${CMD} ${@}... " + printf "%s" "running ${CMD} ${@}... " OUTPUT=`${CMD} ${@} 2>&1` if [ $? != 0 ] ; then echo "failed." @@ -99,11 +107,11 @@ ############################################################################### # Look for our args file ############################################################################### -echo -n "checking for ${ARGS_FILE}: " +printf "%s" "checking for ${ARGS_FILE}: " if [ -f ${ARGS_FILE} ] ; then echo "found." - echo -n "sourcing ${ARGS_FILE}: " - . autogen.args + printf "%s" "sourcing ${ARGS_FILE}: " + . ${ARGS_FILE} echo "done." else echo "not found." @@ -112,7 +120,7 @@ ############################################################################### # Check for our required helpers ############################################################################### -check "libtoolize"; LIBTOOLIZE=${BIN}; +check "$libtoolize"; LIBTOOLIZE=${BIN}; check "glib-gettextize"; GLIB_GETTEXTIZE=${BIN}; check "intltoolize"; INTLTOOLIZE=${BIN}; check "aclocal"; ACLOCAL=${BIN};
--- a/finch/gntconv.c Thu Apr 17 07:12:45 2008 +0000 +++ b/finch/gntconv.c Mon Apr 28 06:27:11 2008 +0000 @@ -682,7 +682,7 @@ ggc->active_conv = conv; FINCH_SET_DATA(conv, ggc); - if (cc && FINCH_GET_DATA(cc)) { + if (cc && FINCH_GET_DATA(cc) && cc != conv) { finch_conversation_set_active(conv); return; }
--- a/finch/libgnt/Makefile.am Thu Apr 17 07:12:45 2008 +0000 +++ b/finch/libgnt/Makefile.am Mon Apr 28 06:27:11 2008 +0000 @@ -1,4 +1,4 @@ -EXTRA_DIST=genmarshal pygnt +EXTRA_DIST=genmarshal SUBDIRS = . wms pkgconfigdir = $(libdir)/pkgconfig
--- a/finch/libgnt/gntentry.c Thu Apr 17 07:12:45 2008 +0000 +++ b/finch/libgnt/gntentry.c Mon Apr 28 06:27:11 2008 +0000 @@ -238,8 +238,15 @@ destroy_suggest(entry); return FALSE; } else if (count == 1) { + char *store = g_strndup(entry->start, entry->end - entry->start); + gboolean ret; + destroy_suggest(entry); - return complete_suggest(entry, sgst); + complete_suggest(entry, sgst); + + ret = (strncmp(store, entry->start, entry->end - entry->start) != 0); + g_free(store); + return ret; } else { if (max > 0) { GntWidget *ddown = entry->ddown;
--- a/finch/libgnt/gntmain.c Thu Apr 17 07:12:45 2008 +0000 +++ b/finch/libgnt/gntmain.c Mon Apr 28 06:27:11 2008 +0000 @@ -245,8 +245,11 @@ } rd += HOLDING_ESCAPE; - if (HOLDING_ESCAPE) + if (HOLDING_ESCAPE) { keys[0] = '\033'; + g_source_remove(escape_stuff.timer); + escape_stuff.timer = 0; + } keys[rd] = 0; gnt_wm_set_event_stack(wm, TRUE); @@ -271,12 +274,6 @@ int p; if (k[0] == '\033' && rd == 1) { - if (escape_stuff.timer) { - gnt_wm_process_input(wm, "\033\033"); - g_source_remove(escape_stuff.timer); - escape_stuff.timer = 0; - break; - } escape_stuff.timer = g_timeout_add(250, escape_timeout, NULL); break; }
--- a/finch/libgnt/pygnt/Files.txt Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -gendef.sh -gnt.override -Makefile -test.py -dbus-gnt -gntmodule.c
--- a/finch/libgnt/pygnt/Makefile.am Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -EXTRA_DIST = gendef.sh - -pg_LTLIBRARIES = gnt.la - -pgdir = $(libdir) - -sources = \ - gnt.def \ - gnt.override \ - gntbox.override \ - gntfilesel.override \ - gnttree.override \ - gntwidget.override - -gnt_la_SOURCES = gnt.c common.c common.h gntmodule.c - -gnt_la_LDFLAGS = -module -avoid-version \ - `pkg-config --libs pygobject-2.0` - -gnt_la_LIBADD = \ - $(GLIB_LIBS) \ - ../libgnt.la - -AM_CPPFLAGS = \ - -I../ \ - $(GLIB_CFLAGS) \ - $(GNT_CFLAGS) \ - -I/usr/include/python2.4 \ - `pkg-config --cflags pygobject-2.0` - -CLEANFILES = gnt.def gnt.c gnt.defe - -gnt.def: $(srcdir)/../*.h - $(srcdir)/gendef.sh - -gnt.c: $(sources) - pygtk-codegen-2.0 --prefix gnt \ - --override gnt.override \ - gnt.def > $@ -
--- a/finch/libgnt/pygnt/Makefile.make Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -CC = gcc -CFLAGS = `pkg-config --cflags gtk+-2.0 pygtk-2.0` -I/usr/include/python2.4/ -I.. -g -O0 -LDFLAGS = `pkg-config --libs gtk+-2.0 pygtk-2.0 gnt` - -gnt.so: gnt.o gntmodule.o common.o - $(CC) $(LDFLAGS) -shared $^ -o $@ - -gnt.c: gnt.def *.override common.c common.h - pygtk-codegen-2.0 --prefix gnt \ - --override gnt.override \ - gnt.def > $@ - -#python codegen/codegen.py --prefix gnt \ - -clean: - @rm *.so *.o gnt.c
--- a/finch/libgnt/pygnt/README.txt Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -Run these in sequence: - -./gendef.sh -make -f Makefile.make gnt.so
--- a/finch/libgnt/pygnt/common.c Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -#include "common.h" - -PyObject * -create_pyobject_from_string_list(GList *list) -{ - PyObject *py_list; - if (list == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - if ((py_list = PyList_New(0)) == NULL) { - g_list_foreach(list, (GFunc)g_free, NULL); - g_list_free(list); - return NULL; - } - while (list) { - PyObject *obj = PyString_FromString(list->data); - PyList_Append(py_list, obj); - Py_DECREF(obj); - g_free(list->data); - list = g_list_delete_link(list, list); - } - return py_list; -}
--- a/finch/libgnt/pygnt/common.h Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -#include "Python.h" -#include "gnt.h" - -PyObject *create_pyobject_from_string_list(GList *list); -
--- a/finch/libgnt/pygnt/dbus-gnt Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -#!/usr/bin/env python - -# This script requires Python 2.4 and pygnt bindings -# -# Note that all function names are resolved dynamically, no -# purple-specific library is needed. - -import dbus -import dbus.glib -import dbus.decorators -import gobject -import os -import gnt -import sys - -import time - -convwins = {} - -def buddysignedon(buddy): - pass - -def conv_closed(conv): - key = get_dict_key(conv) - stuff = convwins[key] - stuff[0].destroy() - # if a conv window is closed, then reopened, this thing crashes - convwins[key] = None - -def add_message(conv, who, msg, flags, timestamp): - stuff = show_conversation(conv, False) - tv = stuff[1] - tv.append_text_with_flags("\n", 0) - if timestamp: - tv.append_text_with_flags(time.strftime("(%X) ", time.localtime(timestamp)), 8) - else: - tv.append_text_with_flags(time.strftime("(%X) "), 8) - if flags & 3: - tv.append_text_with_flags(who + ": ", 1) - msg = purple.PurpleMarkupStripHtml(msg) - tv.append_text_with_flags(msg, 0) - stuff[0].set_urgent() - else: - tv.append_text_with_flags(msg, 8) - tv.scroll(0) - -def wrote_msg(account, who, msg, conv, flags): - add_message(conv, who, msg, flags, None) - -bus = dbus.SessionBus() -obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject") -purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface") - -bus.add_signal_receiver(buddysignedon, - dbus_interface = "im.pidgin.purple.PurpleInterface", - signal_name = "BuddySignedOn") - -bus.add_signal_receiver(wrote_msg, - dbus_interface = "im.pidgin.purple.PurpleInterface", - signal_name = "WroteImMsg") - -bus.add_signal_receiver(wrote_msg, - dbus_interface = "im.pidgin.purple.PurpleInterface", - signal_name = "WroteChatMsg") - -bus.add_signal_receiver(conv_closed, - dbus_interface = "im.pidgin.purple.PurpleInterface", - signal_name = "DeletingConversation") - -def get_dict_key(conv): - val = purple.PurpleConversationGetName(conv) - return val - -def send_im_cb(entry, key, conv): - if key[0] == '\r': - # XXX: do something about the / commands - type = purple.PurpleConversationGetType(conv) - if type == 1: - imdata = purple.PurpleConversationGetImData(conv) - purple.PurpleConvImSend(imdata, entry.get_text()) - else: - chatdata = purple.PurpleConversationGetChatData(conv) - purple.PurpleConvChatSend(chatdata, entry.get_text()) - entry.clear() - -def conv_window_destroyed(win, key): - del convwins[key] - -def show_conversation(conv, history): - key = get_dict_key(conv) - if key in convwins: - return convwins[key] - win = gnt.Window() - vbox = gnt.Box(0, 1) - win.add_widget(vbox) - win.set_title(purple.PurpleConversationGetName(conv)) - win.set_pad(0) - vbox.set_pad(0) - tv = gnt.TextView() - entry = gnt.Entry("") - vbox.add_widget(tv) - entry.set_size(40, 1) - vbox.add_widget(entry) - entry.connect("key_pressed", send_im_cb, conv) - tv.clear() - tv.attach_scroll_widget(entry) - win.show() - convwins[key] = [win, tv, entry] - win.connect("destroy", conv_window_destroyed, key) - - if history: - msgs = purple.PurpleConversationGetMessageHistory(conv) - msgs.reverse() - for msg in msgs: - who = purple.PurpleConversationMessageGetSender(msg) - what = purple.PurpleConversationMessageGetMessage(msg) - flags = purple.PurpleConversationMessageGetFlags(msg) - when = purple.PurpleConversationMessageGetTimestamp(msg) - add_message(conv, who, what, flags, when) - - return convwins[key] - -def show_buddylist(): - win = gnt.Window() - tree = gnt.Tree() - tree.set_property("columns", 1) - win.add_widget(tree) - node = purple.PurpleBlistGetRoot() - while node: - if purple.PurpleBlistNodeIsGroup(node): - sys.stderr.write(str(node) + "\n") - tree.add_row_after(str(node), ["asd", ""], None, None) - #tree.add_row_after(node, [str(purple.PurpleGroupGetName(node)), ""], None, None) - #tree.add_row_after(node, ["aasd", ""], None, None) - elif purple.PurpleBlistNodeIsContact(node): - buddy = purple.PurpleContactGetPriorityBuddy(node) - group = purple.PurpleBuddyGetGroup(buddy) - #tree.add_row_after(node, [str(purple.PurpleBuddyGetName(buddy)), ""], group, None) - - node = purple.PurpleBlistNodeNext(node, False) - win.show() - -gnt.gnt_init() - -# show_buddylist() - -convs = purple.PurpleGetConversations() -for conv in convs: - show_conversation(conv, True) - -gnt.gnt_main() - -gnt.gnt_quit() -
--- a/finch/libgnt/pygnt/example/rss/gnthtml.py Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -#!/usr/bin/env python - -""" -gr - An RSS-reader built using libgnt and feedparser. - -Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - -This application is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This application 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this application; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 -USA -""" - -""" -This file defines GParser, which is a simple HTML parser to display HTML -in a GntTextView nicely. -""" - -import sgmllib -import gnt - -class GParser(sgmllib.SGMLParser): - def __init__(self, view): - sgmllib.SGMLParser.__init__(self, False) - self.link = None - self.view = view - self.flag = gnt.TEXT_FLAG_NORMAL - - def parse(self, s): - self.feed(s) - self.close() - - def unknown_starttag(self, tag, attrs): - if tag in ["b", "i", "blockquote", "strong"]: - self.flag = self.flag | gnt.TEXT_FLAG_BOLD - elif tag in ["p", "hr", "br"]: - self.view.append_text_with_flags("\n", self.flag) - else: - print tag - - def unknown_endtag(self, tag): - if tag in ["b", "i", "blockquote", "strong"]: - self.flag = self.flag & ~gnt.TEXT_FLAG_BOLD - elif tag in ["p", "hr", "br"]: - self.view.append_text_with_flags("\n", self.flag) - else: - print tag - - def start_u(self, attrs): - self.flag = self.flag | gnt.TEXT_FLAG_UNDERLINE - - def end_u(self): - self.flag = self.flag & ~gnt.TEXT_FLAG_UNDERLINE - - def start_a(self, attributes): - for name, value in attributes: - if name == "href": - self.link = value - - def do_img(self, attrs): - for name, value in attrs: - if name == 'src': - self.view.append_text_with_flags("[img:" + value + "]", self.flag) - - def end_a(self): - if not self.link: - return - self.view.append_text_with_flags(" (", self.flag) - self.view.append_text_with_flags(self.link, self.flag | gnt.TEXT_FLAG_UNDERLINE) - self.view.append_text_with_flags(")", self.flag) - self.link = None - - def handle_data(self, data): - if len(data.strip()) == 0: - return - self.view.append_text_with_flags(data, self.flag) -
--- a/finch/libgnt/pygnt/example/rss/gntrss-ui.py Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,400 +0,0 @@ -#!/usr/bin/env python - -""" -gr - An RSS-reader built using libgnt and feedparser. - -Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - -This application is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This application 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this application; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 -USA -""" - -""" -This file deals with the UI part (gnt) of the application - -TODO: - - Allow showing feeds of only selected 'category' and/or 'priority'. A different - window should be used to change such filtering. - - Display details of each item in its own window. - - Add search capability, and allow searching only in title/body. Also allow - filtering in the search results. - - Show the data and time for feed items (probably in a separate column .. perhaps not) - - Have a simple way to add a feed. - - Allow renaming a feed. -""" - -import gntrss -import gnthtml -import gnt -import gobject -import sys - -__version__ = "0.0.1alpha" -__author__ = "Sadrul Habib Chowdhury (sadrul@pidgin.im)" -__copyright__ = "Copyright 2007, Sadrul Habib Chowdhury" -__license__ = "GPL" # see full license statement above - -gnt.gnt_init() - -class RssTree(gnt.Tree): - __gsignals__ = { - 'active_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)) - } - - __gntbindings__ = { - 'jump-next-unread' : ('jump_next_unread', 'n') - } - - def jump_next_unread(self, null): - first = None - next = None - all = self.get_rows() - for item in all: - if item.unread: - if next: - first = item - break - elif not first and self.active != item: - first = item - if self.active == item: - next = item - if first: - self.set_active(first) - self.set_selected(first) - return True - - def __init__(self): - self.active = None - gnt.Tree.__init__(self) - gnt.set_flag(self, 8) # remove borders - self.connect('key_pressed', self.do_key_pressed) - - def set_active(self, active): - if self.active == active: - return - if self.active: - flag = gnt.TEXT_FLAG_NORMAL - if self.active.unread: - flag = flag | gnt.TEXT_FLAG_BOLD - self.set_row_flags(self.active, flag) - old = self.active - self.active = active - flag = gnt.TEXT_FLAG_UNDERLINE - if self.active.unread: - flag = flag | gnt.TEXT_FLAG_BOLD - self.set_row_flags(self.active, flag) - self.emit('active_changed', old) - - def do_key_pressed(self, null, text): - if text == '\r': - now = self.get_selection_data() - self.set_active(now) - return True - return False - -gobject.type_register(RssTree) -gnt.register_bindings(RssTree) - -win = gnt.Box(homo = False, vert = True) -win.set_toplevel(True) -win.set_title("GntRss") -win.set_pad(0) - -# -# [[[ Generic feed/item callbacks -# -def feed_item_added(feed, item): - add_feed_item(item) - -def add_feed(feed): - if not feed.get_data('gntrss-connected'): - feed.connect('added', feed_item_added) - feed.connect('notify', update_feed_title) - feed.set_data('gntrss-connected', True) - feeds.add_row_after(feed, [feed.title, str(feed.unread)], None, None) - -def remove_item(item, feed): - items.remove(item) - -def update_feed_item(item, property): - if property.name == 'unread': - if feeds.active == item.parent: - flag = 0 - if item == items.active: - flag = gnt.TEXT_FLAG_UNDERLINE - if item.unread: - flag = flag | gnt.TEXT_FLAG_BOLD - else: - flag = flag | gnt.TEXT_FLAG_NORMAL - items.set_row_flags(item, flag) - - unread = item.parent.unread - if item.unread: - unread = unread + 1 - else: - unread = unread - 1 - item.parent.set_property('unread', unread) - -def add_feed_item(item): - currentfeed = feeds.active - if item.parent != currentfeed: - return - months = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] - dt = str(item.date_parsed[2]) + "." + months[item.date_parsed[1]] + "." + str(item.date_parsed[0]) - items.add_row_after(item, [str(item.title), dt], None, None) - if item.unread: - items.set_row_flags(item, gnt.TEXT_FLAG_BOLD) - if not item.get_data('gntrss-connected'): - item.set_data('gntrss-connected', True) - # this needs to happen *without* having to add the item in the tree - item.connect('notify', update_feed_item) - item.connect('delete', remove_item) - -# -# ]]] Generic feed/item callbacks -# - - -#### -# [[[ The list of feeds -### - -# 'Add Feed' dialog -add_feed_win = None -def add_feed_win_closed(win): - global add_feed_win - add_feed_win = None - -def add_new_feed(): - global add_feed_win - - if add_feed_win: - gnt.gnt_window_present(add_feed_win) - return - win = gnt.Window() - win.set_title("New Feed") - - box = gnt.Box(False, False) - label = gnt.Label("Link") - box.add_widget(label) - entry = gnt.Entry("") - entry.set_size(40, 1) - box.add_widget(entry) - - win.add_widget(box) - win.show() - add_feed_win = win - add_feed_win.connect("destroy", add_feed_win_closed) - -# -# The active row in the feed-list has changed. Update the feed-item table. -def feed_active_changed(tree, old): - items.remove_all() - if not tree.active: - return - update_items_title() - for item in tree.active.items: - add_feed_item(item) - win.give_focus_to_child(items) - -# -# Check for the action keys and decide how to deal with them. -def feed_key_pressed(tree, text): - if tree.is_searching(): - return - if text == 'r': - feed = tree.get_selection_data() - tree.perform_action_key('j') - #tree.perform_action('move-down') - feed.refresh() - elif text == 'R': - feeds = tree.get_rows() - for feed in feeds: - feed.refresh() - elif text == 'm': - feed = tree.get_selection_data() - if feed: - feed.mark_read() - feed.set_property('unread', 0) - elif text == 'a': - add_new_feed() - else: - return False - return True - -feeds = RssTree() -feeds.set_property('columns', 2) -feeds.set_col_width(0, 20) -feeds.set_col_width(1, 6) -feeds.set_column_resizable(0, False) -feeds.set_column_resizable(1, False) -feeds.set_column_is_right_aligned(1, True) -feeds.set_show_separator(False) -feeds.set_column_title(0, "Feeds") -feeds.set_show_title(True) - -feeds.connect('active_changed', feed_active_changed) -feeds.connect('key_pressed', feed_key_pressed) -gnt.unset_flag(feeds, 256) # Fix the width - -#### -# ]]] The list of feeds -### - -#### -# [[[ The list of items in the feed -#### - -# -# The active item in the feed-item list has changed. Update the -# summary content. -def item_active_changed(tree, old): - details.clear() - if not tree.active: - return - item = tree.active - details.append_text_with_flags(str(item.title) + "\n", gnt.TEXT_FLAG_BOLD) - details.append_text_with_flags("Link: ", gnt.TEXT_FLAG_BOLD) - details.append_text_with_flags(str(item.link) + "\n", gnt.TEXT_FLAG_UNDERLINE) - details.append_text_with_flags("Date: ", gnt.TEXT_FLAG_BOLD) - details.append_text_with_flags(str(item.date) + "\n", gnt.TEXT_FLAG_NORMAL) - details.append_text_with_flags("\n", gnt.TEXT_FLAG_NORMAL) - parser = gnthtml.GParser(details) - parser.parse(str(item.summary)) - item.mark_unread(False) - - if old and old.unread: # If the last selected item is marked 'unread', then make sure it's bold - items.set_row_flags(old, gnt.TEXT_FLAG_BOLD) - -# -# Look for action keys in the feed-item list. -def item_key_pressed(tree, text): - if tree.is_searching(): - return - current = tree.get_selection_data() - if text == 'M': # Mark all of the items 'read' - feed = feeds.active - if feed: - feed.mark_read() - elif text == 'm': # Mark the current item 'read' - current.mark_unread(False) - tree.perform_action_key('j') - elif text == 'U': # Mark the current item 'unread' - current.mark_unread(True) - elif text == 'd': - current.remove() - tree.perform_action_key('j') - else: - return False - return True - -items = RssTree() -items.set_property('columns', 2) -items.set_col_width(0, 40) -items.set_col_width(1, 11) -items.set_column_resizable(1, False) -items.set_column_title(0, "Items") -items.set_column_title(1, "Date") -items.set_show_title(True) -items.connect('key_pressed', item_key_pressed) -items.connect('active_changed', item_active_changed) - -#### -# ]]] The list of items in the feed -#### - -# -# Update the title of the items list depending on the selection in the feed list -def update_items_title(): - feed = feeds.active - if feed: - items.set_column_title(0, str(feed.title) + ": " + str(feed.unread) + "(" + str(len(feed.items)) + ")") - else: - items.set_column_title(0, "Items") - items.draw() - -# The container on the top -line = gnt.Line(vertical = False) - -# The textview to show the details of a feed -details = gnt.TextView() -details.set_take_focus(True) -details.set_flag(gnt.TEXT_VIEW_TOP_ALIGN) -details.attach_scroll_widget(details) - -# Make it look nice -s = feeds.get_size() -size = gnt.screen_size() -size[0] = size[0] - s[0] -items.set_size(size[0], size[1] / 2) -details.set_size(size[0], size[1] / 2) - -# Category tree -cat = gnt.Tree() -cat.set_property('columns', 1) -cat.set_column_title(0, 'Category') -cat.set_show_title(True) -gnt.set_flag(cat, 8) # remove borders - -box = gnt.Box(homo = False, vert = False) -box.set_pad(0) - -vbox = gnt.Box(homo = False, vert = True) -vbox.set_pad(0) -vbox.add_widget(feeds) -vbox.add_widget(gnt.Line(False)) -vbox.add_widget(cat) -box.add_widget(vbox) - -box.add_widget(gnt.Line(True)) - -vbox = gnt.Box(homo = False, vert = True) -vbox.set_pad(0) -vbox.add_widget(items) -vbox.add_widget(gnt.Line(False)) -vbox.add_widget(details) -box.add_widget(vbox) - -win.add_widget(box) -win.show() - -def update_feed_title(feed, property): - if property.name == 'title': - if feed.customtitle: - title = feed.customtitle - else: - title = feed.title - feeds.change_text(feed, 0, title) - elif property.name == 'unread': - feeds.change_text(feed, 1, str(feed.unread) + "(" + str(len(feed.items)) + ")") - flag = 0 - if feeds.active == feed: - flag = gnt.TEXT_FLAG_UNDERLINE - update_items_title() - if feed.unread > 0: - flag = flag | gnt.TEXT_FLAG_BOLD - feeds.set_row_flags(feed, flag) - -# populate everything -for feed in gntrss.feeds: - feed.refresh() - feed.set_auto_refresh(True) - add_feed(feed) - -gnt.gnt_register_action("Stuff", add_new_feed) -gnt.gnt_main() - -gnt.gnt_quit() -
--- a/finch/libgnt/pygnt/example/rss/gntrss.py Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,256 +0,0 @@ -#!/usr/bin/env python - -""" -gr - An RSS-reader built using libgnt and feedparser. - -Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - -This application is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This application 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this application; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 -USA -""" - -""" -This file deals with the rss parsing part (feedparser) of the application -""" - -import os -import tempfile, urllib2 -import feedparser -import gobject -import sys -import time - -## -# The FeedItem class. It will update emit 'delete' signal when it's -# destroyed. -## -class FeedItem(gobject.GObject): - __gproperties__ = { - 'unread' : (gobject.TYPE_BOOLEAN, 'read', - 'The unread state of the item.', - False, gobject.PARAM_READWRITE) - } - __gsignals__ = { - 'delete' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)) - } - def __init__(self, item, parent): - self.__gobject_init__() - try: - "Apparently some feed items don't have any dates in them" - self.date = item['date'] - self.date_parsed = item['date_parsed'] - except: - item['date'] = self.date = time.ctime() - self.date_parsed = feedparser._parse_date(self.date) - - self.title = item['title'].encode('utf8') - self.summary = item['summary'].encode('utf8') - self.link = item['link'] - self.parent = parent - self.unread = True - - def __del__(self): - pass - - def remove(self): - self.emit('delete', self.parent) - if self.unread: - self.parent.set_property('unread', self.parent.unread - 1) - - def do_set_property(self, property, value): - if property.name == 'unread': - self.unread = value - - def mark_unread(self, unread): - if self.unread == unread: - return - self.set_property('unread', unread) - -gobject.type_register(FeedItem) - -def item_hash(item): - return str(item['title']) - -""" -The Feed class. It will update the 'link', 'title', 'desc' and 'items' -attributes if/when they are updated (triggering 'notify::<attr>' signal) - -TODO: - - Add a 'count' attribute - - Each feed will have a 'uidata', which will be its display window - - Look into 'category'. Is it something that feed defines, or the user? - - Have separate refresh times for each feed. - - Have 'priority' for each feed. (somewhat like category, perhaps?) -""" -class Feed(gobject.GObject): - __gproperties__ = { - 'link' : (gobject.TYPE_STRING, 'link', - 'The web page this feed is associated with.', - '...', gobject.PARAM_READWRITE), - 'title' : (gobject.TYPE_STRING, 'title', - 'The title of the feed.', - '...', gobject.PARAM_READWRITE), - 'desc' : (gobject.TYPE_STRING, 'description', - 'The description for the feed.', - '...', gobject.PARAM_READWRITE), - 'items' : (gobject.TYPE_POINTER, 'items', - 'The items in the feed.', gobject.PARAM_READWRITE), - 'unread' : (gobject.TYPE_INT, 'unread', - 'Number of unread items in the feed.', 0, 10000, 0, gobject.PARAM_READWRITE) - } - __gsignals__ = { - 'added' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)) - } - - def __init__(self, feed): - self.__gobject_init__() - url = feed['link'] - name = feed['name'] - self.url = url # The url of the feed itself - self.link = url # The web page associated with the feed - self.desc = url - self.title = (name, url)[not name] - self.customtitle = name - self.unread = 0 - self.items = [] - self.hash = {} - self.pending = False - self._refresh = {'time' : 30, 'id' : 0} - - def __del__(self): - pass - - def do_set_property(self, property, value): - if property.name == 'link': - self.link = value - elif property.name == 'desc': - self.desc = value - elif property.name == 'title': - self.title = value - elif property.name == 'unread': - self.unread = value - pass - - def set_result(self, result): - # XXX Look at result['bozo'] first, and emit some signal that the UI can use - # to indicate (dim the row?) that the feed has invalid XML format or something - - try: - channel = result['channel'] - self.set_property('link', channel['link']) - self.set_property('desc', channel['description']) - self.set_property('title', channel['title']) - items = result['items'] - except: - items = () - - tmp = {} - for item in self.items: - tmp[hash(item)] = item - - unread = self.unread - for item in items: - try: - exist = self.hash[item_hash(item)] - del tmp[hash(exist)] - except: - itm = FeedItem(item, self) - self.items.append(itm) - self.emit('added', itm) - self.hash[item_hash(item)] = itm - unread = unread + 1 - - if unread != self.unread: - self.set_property('unread', unread) - - for hv in tmp: - self.items.remove(tmp[hv]) - tmp[hv].remove() - "Also notify the UI about the count change" - - self.pending = False - return False - - def refresh(self): - if self.pending: - return - self.pending = True - FeedReader(self).run() - return True - - def mark_read(self): - for item in self.items: - item.mark_unread(False) - - def set_auto_refresh(self, auto): - if auto: - if self._refresh['id']: - return - if self._refresh['time'] < 1: - self._refresh['time'] = 1 - self.id = gobject.timeout_add(self._refresh['time'] * 1000 * 60, self.refresh) - else: - if not self._refresh['id']: - return - gobject.source_remove(self._refresh['id']) - self._refresh['id'] = 0 - -gobject.type_register(Feed) - -""" -The FeedReader updates a Feed. It fork()s off a child to avoid blocking. -""" -class FeedReader: - def __init__(self, feed): - self.feed = feed - - def reap_child(self, pid, status): - result = feedparser.parse(self.tmpfile.name) - self.tmpfile.close() - self.feed.set_result(result) - - def run(self): - self.tmpfile = tempfile.NamedTemporaryFile() - self.pid = os.fork() - if self.pid == 0: - tmp = urllib2.urlopen(self.feed.url) - content = tmp.read() - tmp.close() - self.tmpfile.write(content) - self.tmpfile.flush() - # Do NOT close tmpfile here - os._exit(os.EX_OK) - gobject.child_watch_add(self.pid, self.reap_child) - -feeds = [] -urls = ( - {'name': '/.', - 'link': "http://rss.slashdot.org/Slashdot/slashdot"}, - {'name': 'KernelTrap', - 'link': "http://kerneltrap.org/node/feed"}, - {'name': None, - 'link': "http://pidgin.im/rss.php"}, - {'name': "F1", - 'link': "http://www.formula1.com/rss/news/latest.rss"}, - {'name': "Freshmeat", - 'link': "http://www.pheedo.com/f/freshmeatnet_announcements_unix"}, - {'name': "Cricinfo", - 'link': "http://www.cricinfo.com/rss/livescores.xml"} -) - -for url in urls: - feed = Feed(url) - feeds.append(feed) -
--- a/finch/libgnt/pygnt/file.py Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -#!/usr/bin/env python - -import gnt, sys - -def file_selected(widget, path, file, null): - sys.stderr.write(path + " " + file) - list = widget.get_selected_multi_files() - for i in list: - sys.stderr.write(i) - -gnt.gnt_init() - -win = gnt.Window() - -files = gnt.FileSel() -files.set_multi_select(True) -files.set_title("Files") -files.connect("file_selected", file_selected, None) - -files.show() - -gnt.gnt_main() - -gnt.gnt_quit()
--- a/finch/libgnt/pygnt/gendef.sh Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#!/bin/sh -FILES=" - gntwidget.h - gntbindable.h - gntbox.h - gntbutton.h - gntcheckbox.h - gntclipboard.h - gntcolors.h - gntcombobox.h - gntentry.h - gntfilesel.h - gntkeys.h - gntlabel.h - gntline.h - gntmarshal.h - gntmenu.h - gntmenuitem.h - gntmenuitemcheck.h - gntslider.h - gntstyle.h - gnttextview.h - gnttree.h - gntutils.h - gntwindow.h - gntwm.h - gntws.h - gnt.h" - -# Generate the def file -rm -f gnt.def -for file in $FILES -do - echo -n "Generating definitions for ${file} ... " - python /usr/share/pygtk/2.0/codegen/h2def.py ../$file >> gnt.def - echo "Done" -done - -# Remove the definitions about the enums -ENUMS=" -GNT_TYPE_ALIGNMENT -GNT_TYPE_COLOR_TYPE -GNT_TYPE_MENU_TYPE -GNT_TYPE_STYLE -GNT_TYPE_KEY_PRESS_MODE -GNT_TYPE_ENTRY_FLAG -GNT_TYPE_TEXT_FORMAT_FLAGS -GNT_TYPE_TEXT_VIEW_FLAG -" - -for enum in $ENUMS -do - sed -ie s/^.*gtype-id\ \"$enum\".*$//g gnt.def -done - -
--- a/finch/libgnt/pygnt/gnt.override Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -%% -headers -#include <Python.h> -#include "pygobject.h" -#include "gnt.h" -#include "gntbindable.h" -#include "gntwidget.h" -#include "gntbox.h" -#include "gntbutton.h" -#include "gntcheckbox.h" -#include "gntcolors.h" -#include "gntcombobox.h" -#include "gntentry.h" -#include "gntfilesel.h" -#include "gntkeys.h" -#include "gntlabel.h" -#include "gntline.h" -#include "gntmenu.h" -#include "gntmenuitem.h" -#include "gntmenuitemcheck.h" -#include "gntslider.h" -#include "gntstyle.h" -#include "gnttextview.h" -#include "gnttree.h" -#include "gntutils.h" -#include "gntwindow.h" -#include "gntwm.h" -#include "gntws.h" -#include "common.h" -%% -include - gntbox.override - gntfilesel.override - gnttree.override - gntwidget.override -%% -modulename gnt -%% -import gobject.GObject as PyGObject_Type -%% -ignore-glob - *_get_gtype -%% -define set_flag -static PyObject * -_wrap_set_flag(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"flags", NULL}; - PyGObject *widget; - int flags; - - if (!PyArg_ParseTuple(args, "O!i:gnt.set_flag", &PyGntWidget_Type, &widget, - &flags)) { - return NULL; - } - - GNT_WIDGET_SET_FLAGS(widget->obj, flags); - - Py_INCREF(Py_None); - return Py_None; -} -%% -define unset_flag -static PyObject * -_wrap_unset_flag(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"flags", NULL}; - PyGObject *widget; - int flags; - - if (!PyArg_ParseTuple(args, "O!i:gnt.unset_flag", &PyGntWidget_Type, &widget, - &flags)) { - return NULL; - } - - GNT_WIDGET_UNSET_FLAGS(widget->obj, flags); - - Py_INCREF(Py_None); - return Py_None; -} -%% -define screen_size noargs -static PyObject * -_wrap_screen_size(PyObject *self) -{ - PyObject *list = PyList_New(0); - - if (list == NULL) - return NULL; - - PyList_Append(list, PyInt_FromLong((long)getmaxx(stdscr))); - PyList_Append(list, PyInt_FromLong((long)getmaxy(stdscr))); - - return list; -} -%% -override gnt_register_action -static GHashTable *actions; - - - -static PyObject * -_wrap_gnt_register_action(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"name", "callback", NULL}; - PyGObject *callback; - GClosure *closure; - char *name; - - if (!PyArg_ParseTuple(args, "sO:gnt.gnt_register_action", &name, &callback)) { - return NULL; - } - - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "the callback must be callable ... doh!"); - return NULL; - } - - gnt_register_action(name, callback->obj); - - Py_INCREF(Py_None); - return Py_None; -} -%% -define register_bindings - -static gboolean -pygnt_binding_callback(GntBindable *bindable, GList *list) -{ - PyObject *wrapper = pygobject_new(G_OBJECT(bindable)); - PyObject_CallMethod(wrapper, list->data, "O", Py_None); - Py_DECREF(wrapper); - return TRUE; -} - -static PyObject * -_wrap_register_bindings(PyObject *self, PyObject *args) -{ - PyTypeObject *class; - int pos = 0; - PyObject *key, *value, *gbindings; - GntBindableClass *bindable; - - if (!PyArg_ParseTuple(args, "O!:gnt.register_bindings", - &PyType_Type, &class)) { - /* Make sure it's a GntBindableClass subclass */ - PyErr_SetString(PyExc_TypeError, - "argument must be a GntBindable subclass"); - return NULL; - } - - gbindings = PyDict_GetItemString(class->tp_dict, "__gntbindings__"); - if (!gbindings) - goto end; - - if (!PyDict_Check(gbindings)) { - PyErr_SetString(PyExc_TypeError, - "__gntbindings__ attribute not a dict!"); - return NULL; - } - - bindable = g_type_class_ref(pyg_type_from_object((PyObject *)class)); - while (PyDict_Next(gbindings, &pos, &key, &value)) { - const char *trigger, *callback, *name; - GList *list = NULL; - - if (!PyString_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "__gntbindings__ keys must be strings"); - g_type_class_unref(bindable); - return NULL; - } - name = PyString_AsString(key); - - if (!PyTuple_Check(value) || - !PyArg_ParseTuple(value, "ss", &callback, &trigger)) { - PyErr_SetString(PyExc_TypeError, - "__gntbindings__ values must be (callback, trigger) tupples"); - g_type_class_unref(bindable); - return NULL; - } - - gnt_bindable_class_register_action(bindable, name, pygnt_binding_callback, - trigger, g_strdup(callback), NULL); - } - if (gbindings) - PyDict_DelItemString(class->tp_dict, "__gntbindings__"); - g_type_class_unref(bindable); - -end: - Py_INCREF(Py_None); - return Py_None; -} -
--- a/finch/libgnt/pygnt/gntbox.override Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/** - * pygnt- Python bindings for the GNT toolkit. - * Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - * - * gntbox.override: overrides for the box widget. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 - * USA - */ -%% -override gnt_box_add_widget kwargs -static PyObject * -_wrap_gnt_box_add_widget(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "widget", NULL }; - PyGObject *widget; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:GntBox.add_widget", kwlist, &PyGntWidget_Type, &widget)) - return NULL; - - gnt_box_add_widget(GNT_BOX(self->obj), GNT_WIDGET(widget->obj)); - Py_INCREF(widget); - - Py_INCREF(Py_None); - return Py_None; -}
--- a/finch/libgnt/pygnt/gntfilesel.override Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/** - * pygnt- Python bindings for the GNT toolkit. - * Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - * - * gntfilesel.override: overrides for the file selector. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 - * USA - */ -%% -headrs -#include "common.h" -%% -override gnt_file_sel_get_selected_multi_files noargs -static PyObject * -_wrap_gnt_file_sel_get_selected_multi_files(PyGObject *self) -{ - GList *list = gnt_file_sel_get_selected_multi_files(GNT_FILE_SEL(self->obj)); - return create_pyobject_from_string_list(list); -} -
--- a/finch/libgnt/pygnt/gntmodule.c Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -#include <pygobject.h> -#include "gnt.h" - -void gnt_register_classes (PyObject *d); -extern PyMethodDef gnt_functions[]; - -static void -gnt_add_string_constants(PyObject *module) -{ -#define define_key(x) if (GNT_KEY_##x && *(GNT_KEY_##x)) PyModule_AddStringConstant(module, "KEY_" #x, GNT_KEY_##x) - - define_key(POPUP); - - define_key(LEFT); - define_key(RIGHT); - define_key(UP); - define_key(DOWN); - - define_key(CTRL_UP); - define_key(CTRL_DOWN); - define_key(CTRL_RIGHT); - define_key(CTRL_LEFT); - - define_key(PGUP); - define_key(PGDOWN); - define_key(HOME); - define_key(END); - - define_key(ENTER); - - define_key(BACKSPACE); - define_key(DEL); - define_key(INS); - define_key(BACK_TAB); - - define_key(CTRL_A); - define_key(CTRL_B); - define_key(CTRL_D); - define_key(CTRL_E); - define_key(CTRL_F); - define_key(CTRL_G); - define_key(CTRL_H); - define_key(CTRL_I); - define_key(CTRL_J); - define_key(CTRL_K); - define_key(CTRL_L); - define_key(CTRL_M); - define_key(CTRL_N); - define_key(CTRL_O); - define_key(CTRL_P); - define_key(CTRL_R); - define_key(CTRL_T); - define_key(CTRL_U); - define_key(CTRL_V); - define_key(CTRL_W); - define_key(CTRL_X); - define_key(CTRL_Y); - - define_key(F1); - define_key(F2); - define_key(F3); - define_key(F4); - define_key(F5); - define_key(F6); - define_key(F7); - define_key(F8); - define_key(F9); - define_key(F10); - define_key(F11); - define_key(F12); -} - -DL_EXPORT(void) -initgnt(void) -{ - PyObject *m, *d; - - init_pygobject (); - - m = Py_InitModule ("gnt", gnt_functions); - d = PyModule_GetDict (m); - - gnt_register_classes (d); - gnt_add_constants(m, "GNT_"); - - if (PyErr_Occurred ()) { - Py_FatalError ("can't initialise module sad"); - } - - gnt_init(); - gnt_add_string_constants(m); -} -
--- a/finch/libgnt/pygnt/gnttree.override Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/** - * pygnt- Python bindings for the GNT toolkit. - * Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - * - * gnttree.override: overrides for the tree widget. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 - * USA - */ -%% -headers -#include "common.h" -%% -ignore -gnt_tree_create_row -gnt_tree_create_row_from_list -%% -override gnt_tree_get_selection_text_list noargs -static PyObject * -_wrap_gnt_tree_get_selection_text_list(PyGObject *self) -{ - GList *list = gnt_tree_get_selection_text_list(GNT_TREE(self->obj)); - return create_pyobject_from_string_list(list); -} -%% -override gnt_tree_get_rows noargs -static PyObject * -_wrap_gnt_tree_get_rows(PyGObject *self) -{ - GList *list = gnt_tree_get_rows(GNT_TREE(self->obj)); - PyObject *py_list; - if (list == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - if ((py_list = PyList_New(0)) == NULL) { - return NULL; - } - while (list) { - PyObject *obj = list->data; - PyList_Append(py_list, obj); - list = list->next; - } - return py_list; -} -%% -override gnt_tree_add_row_after -static PyObject * -_wrap_gnt_tree_add_row_after(PyGObject *self, PyObject *args) -{ - static char *kwlist[] = {"key", "row", "parent", "bigbro", NULL}; - PyObject *py_list; - gpointer key, parent, bigbro = NULL; - int len, i; - GList *list = NULL; - GntTreeRow *row; - gboolean insert_last = FALSE; - - if (!PyArg_ParseTuple(args, - "OOO|O:GntTree.add_row_after", - &key, - &py_list, - &parent, - &bigbro)) - return NULL; - - len = PySequence_Length(py_list); - for (i = 0; i < len; i++) { - PyObject *item = PySequence_GetItem(py_list, i); - if (!pygobject_check(item, &PyString_Type)) { - PyErr_SetString(PyExc_TypeError, - "column_list members must be strings"); - Py_DECREF(item); - return NULL; - } - list = g_list_prepend(list, PyString_AsString(item)); - Py_DECREF(item); - } - - if (parent == Py_None) - parent = NULL; - if (bigbro == Py_None) - bigbro = NULL; - else if (bigbro == NULL) - insert_last = TRUE; - - Py_INCREF((PyObject*)key); - - list = g_list_reverse(list); - row = gnt_tree_create_row_from_list(GNT_TREE(self->obj), list); - if (insert_last) - gnt_tree_add_row_last(GNT_TREE(self->obj), - key, row, parent); - else - gnt_tree_add_row_after(GNT_TREE(self->obj), - key, row, - parent, bigbro); - g_list_free(list); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override gnt_tree_get_selection_data noargs -static PyObject * -_wrap_gnt_tree_get_selection_data(PyGObject *self) -{ - PyObject *ret = gnt_tree_get_selection_data(GNT_TREE(self->obj)); - if (!ret) - ret = Py_None; - Py_INCREF(ret); - return ret; -} -%% -override gnt_tree_change_text -static PyObject * -_wrap_gnt_tree_change_text(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "key", "colno", "text", NULL }; - char *text; - int colno; - gpointer key; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"Ois:GntTree.change_text", kwlist, &key, &colno, &text)) - return NULL; - - gnt_tree_change_text(GNT_TREE(self->obj), key, colno, text); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override gnt_tree_set_row_flags -static PyObject * -_wrap_gnt_tree_set_row_flags(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "key", "flag", NULL }; - int flag; - gpointer key; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"Oi:GntTree.set_row_flags", kwlist, &key, &flag)) - return NULL; - - gnt_tree_set_row_flags(GNT_TREE(self->obj), key, flag); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override gnt_tree_remove -static PyObject * -_wrap_gnt_tree_remove(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "key", NULL }; - gpointer key; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:GntTree.remove", kwlist, &key)) - return NULL; - - gnt_tree_remove(GNT_TREE(self->obj), key); - - Py_INCREF(Py_None); - return Py_None; -} -%% -override gnt_tree_set_selected -static PyObject * -_wrap_gnt_tree_set_selected(PyGObject *self, PyObject *args) -{ - gpointer key; - if (!PyArg_ParseTuple(args, "O:GntTree.set_selected", &key)) { - return NULL; - } - gnt_tree_set_selected(GNT_TREE(self->obj), key); - Py_INCREF(Py_None); - return Py_None; -} -%% -override gnt_tree_set_compare_func -static PyObject * -_wrap_gnt_tree_set_compare_func(PyGObject *self, PyObject *args) -{ - static char *kwlist[] = {"compare_func", NULL}; - PyGObject *compare; - - if (!PyArg_ParseTuple(args, "O:GntTree.set_compare_func", &compare)) { - return NULL; - } - - if (!PyCallable_Check(compare)) { - PyErr_SetString(PyExc_TypeError, "the callback must be callable ... doh!"); - return NULL; - } - - Py_INCREF(compare); - gnt_tree_set_compare_func(GNT_TREE(self->obj), (GCompareFunc)compare->obj); - - Py_INCREF(Py_None); - return Py_None; -} -
--- a/finch/libgnt/pygnt/gntwidget.override Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/** - * pygnt- Python bindings for the GNT toolkit. - * Copyright (C) 2007 Sadrul Habib Chowdhury <sadrul@pidgin.im> - * - * gntwidget.override: overrides for generic widgets. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 - * USA - */ -%% -override gnt_widget_get_size args -static PyObject * -_wrap_gnt_widget_get_size(PyGObject *self) -{ - PyObject *list = PyList_New(0); - int x = 0, y = 0; - - gnt_widget_get_size(GNT_WIDGET(self->obj), &x, &y); - PyList_Append(list, PyInt_FromLong((long)x)); - PyList_Append(list, PyInt_FromLong((long)y)); - - return list; -} -
--- a/finch/libgnt/pygnt/test.py Thu Apr 17 07:12:45 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -#!/usr/bin/env python -import gobject -import gnt - -class MyObject(gobject.GObject): - __gproperties__ = { - 'mytype': (gobject.TYPE_INT, 'mytype', 'the type of the object', - 0, 10000, 0, gobject.PARAM_READWRITE), - 'string': (gobject.TYPE_STRING, 'string property', 'the string', - None, gobject.PARAM_READWRITE), - 'gobject': (gobject.TYPE_OBJECT, 'object property', 'the object', - gobject.PARAM_READWRITE), - } - - def __init__(self, type = 'string', value = None): - self.__gobject_init__() - self.set_property(type, value) - - def __del__(self): - pass - - def do_set_property(self, pspec, value): - if pspec.name == 'string': - self.string = value - self.type = gobject.TYPE_STRING - elif pspec.name == 'gobject': - self.gobject = value - self.type = gobject.TYPE_OBJECT - else: - raise AttributeError, 'unknown property %s' % pspec.name - def do_get_property(self, pspec): - if pspec.name == 'string': - return self.string - elif pspec.name == 'gobject': - return self.gobject - elif pspec.name == 'mytype': - return self.type - else: - raise AttributeError, 'unknown property %s' % pspec.name -gobject.type_register(MyObject) - -def button_activate(button, tree): - list = tree.get_selection_text_list() - ent = tree.get_selection_data() - if ent.type == gobject.TYPE_STRING: - str = "" - for i in list: - str = str + i - entry.set_text("clicked!!!" + str) - elif ent.type == gobject.TYPE_OBJECT: - ent.gobject.set_text("mwhahaha!!!") - -gnt.gnt_init() - -win = gnt.Window() - -entry = gnt.Entry("") -obj = MyObject() -obj.set_property('gobject', entry) - -win.add_widget(entry) -win.set_title("Entry") - -button = gnt.Button("Click!") -win.add_widget(button) - -tree = gnt.Tree() -tree.set_property("columns", 1) -win.add_widget(tree) - -# so random non-string values can be used as the key for a row in a GntTree! -last = None -for i in range(1, 100): - key = MyObject('string', str(i)) - tree.add_row_after(key, [str(i)], None, last) - last = key - -tree.add_row_after(MyObject('gobject', entry), ["asd"], None, None) -tree.add_row_after(MyObject('string', "b"), ["123"], MyObject('gobject', entry), None) - -button.connect("activate", button_activate, tree) - -tv = gnt.TextView() - -win.add_widget(tv) -tv.append_text_with_flags("What up!!", gnt.TEXT_FLAG_BOLD) - -win.show() - -gnt.gnt_main() - -gnt.gnt_quit() -
--- a/libpurple/account.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/account.c Mon Apr 28 06:27:11 2008 +0000 @@ -1359,8 +1359,12 @@ return; } - if (orig_pass == NULL || new_pass_1 == NULL || new_pass_2 == NULL || - *orig_pass == '\0' || *new_pass_1 == '\0' || *new_pass_2 == '\0') + if ((purple_request_fields_is_field_required(fields, "password") && + (orig_pass == NULL || *orig_pass == '\0')) || + (purple_request_fields_is_field_required(fields, "new_password_1") && + (new_pass_1 == NULL || *new_pass_1 == '\0')) || + (purple_request_fields_is_field_required(fields, "new_password_2") && + (new_pass_2 == NULL || *new_pass_2 == '\0'))) { purple_notify_error(account, NULL, _("Fill out all fields completely."), NULL); @@ -1376,11 +1380,20 @@ PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; + PurpleConnection *gc; + PurplePlugin *prpl = NULL; + PurplePluginProtocolInfo *prpl_info = NULL; char primary[256]; g_return_if_fail(account != NULL); g_return_if_fail(purple_account_is_connected(account)); + gc = purple_account_get_connection(account); + if (gc != NULL) + prpl = purple_connection_get_prpl(gc); + if (prpl != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); @@ -1389,21 +1402,24 @@ field = purple_request_field_string_new("password", _("Original password"), NULL, FALSE); purple_request_field_string_set_masked(field, TRUE); - purple_request_field_set_required(field, TRUE); + if (!(prpl_info && (prpl_info->options | OPT_PROTO_PASSWORD_OPTIONAL))) + purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("new_password_1", _("New password"), NULL, FALSE); purple_request_field_string_set_masked(field, TRUE); - purple_request_field_set_required(field, TRUE); + if (!(prpl_info && (prpl_info->options | OPT_PROTO_PASSWORD_OPTIONAL))) + purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("new_password_2", _("New password (again)"), NULL, FALSE); purple_request_field_string_set_masked(field, TRUE); - purple_request_field_set_required(field, TRUE); + if (!(prpl_info && (prpl_info->options | OPT_PROTO_PASSWORD_OPTIONAL))) + purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); g_snprintf(primary, sizeof(primary), _("Change password for %s"),
--- a/libpurple/blist.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/blist.c Mon Apr 28 06:27:11 2008 +0000 @@ -2238,6 +2238,8 @@ pce = parts->data; chat_name = g_hash_table_lookup(chat->components, pce->identifier); + g_list_foreach(parts, (GFunc)g_free, NULL); + g_list_free(parts); if (chat->account == account && chat_name != NULL && name != NULL && !strcmp(chat_name, name)) {
--- a/libpurple/core.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/core.c Mon Apr 28 06:27:11 2008 +0000 @@ -323,25 +323,6 @@ return remote_user_dir; } -static void purple_dbus_owner_show_buddy_list(void) -{ - DBusError dbus_error; - DBusMessage *msg = NULL, *reply = NULL; - DBusConnection *dbus_connection = NULL; - - if ((dbus_connection = purple_dbus_get_connection()) == NULL) - return; - - if ((msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleBlistShow")) == NULL) - return; - - dbus_error_init(&dbus_error); - if ((reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error)) != NULL) - { - dbus_message_unref(msg); - } - dbus_error_free(&dbus_error); -} #endif /* HAVE_DBUS */ gboolean @@ -366,9 +347,6 @@ else is_single_instance = strcmp(dbus_owner_user_dir, user_dir); - if (!is_single_instance) - purple_dbus_owner_show_buddy_list(); - g_free(dbus_owner_user_dir); } }
--- a/libpurple/dbus-server.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/dbus-server.h Mon Apr 28 06:27:11 2008 +0000 @@ -28,9 +28,9 @@ #ifndef _PURPLE_DBUS_SERVER_H_ #define _PURPLE_DBUS_SERVER_H_ +#include "dbus-purple.h" #include "value.h" - G_BEGIN_DECLS /** @@ -51,6 +51,8 @@ PurpleDBusType *parent; }; +#include "dbus-bindings.h" + /* By convention, the PurpleDBusType variable representing each structure PurpleSomeStructure has the name PURPLE_DBUS_TYPE_PurpleSomeStructure. The following macros facilitate defining such variables
--- a/libpurple/log.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/log.c Mon Apr 28 06:27:11 2008 +0000 @@ -1758,6 +1758,7 @@ lastoff = offset; g_snprintf(convostart, length, "%s", temp); + memset(&tm, 0, sizeof(tm)); sscanf(convostart, "%*s %s %d %d:%d:%d %d", month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year); /* Ugly hack, in case current locale is not English */
--- a/libpurple/plugin.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugin.c Mon Apr 28 06:27:11 2008 +0000 @@ -1212,7 +1212,7 @@ if (g_list_find_custom(search_paths, path, (GCompareFunc)strcmp)) return; - search_paths = g_list_append(search_paths, strdup(path)); + search_paths = g_list_append(search_paths, g_strdup(path)); } void @@ -1294,7 +1294,7 @@ /* Strip the extension */ if (basename) - basename = purple_plugin_get_basename(filename); + basename = purple_plugin_get_basename(basename); if (((plugin = purple_plugins_find_with_filename(filename)) != NULL) || (basename && (plugin = purple_plugins_find_with_basename(basename)) != NULL) ||
--- a/libpurple/plugins/perl/Makefile.am Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/Makefile.am Mon Apr 28 06:27:11 2008 +0000 @@ -90,7 +90,9 @@ common/Makefile: common/Makefile.PL @if test "x${top_srcdir}" != "x${top_builddir}"; then \ for f in ${common_sources}; do \ - ${LN_S} -f ../${srcdir}/$$f $$f; \ + srcloc=${srcdir}; \ + case $$srcloc in /*) ;; *) srcloc=../${srcdir} ;; esac; \ + ${LN_S} -f $$srcloc/$$f $$f; \ done; \ fi @cd common && $(perlpath) Makefile.PL $(PERL_MM_PARAMS) @@ -148,7 +150,9 @@ @if test "x${top_srcdir}" != "x${top_builddir}"; then \ for f in ${common_sources}; do \ - ${LN_S} -f ../${srcdir}/$$f $$f; \ + srcloc=${srcdir}; \ + case $$srcloc in /*) ;; *) srcloc=../${srcdir} ;; esac; \ + ${LN_S} -f $$srcloc/$$f $$f; \ done; \ fi
--- a/libpurple/plugins/perl/common/Notify.xs Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/common/Notify.xs Mon Apr 28 06:27:11 2008 +0000 @@ -172,10 +172,10 @@ void purple_notify_user_info_remove_last_item(user_info) Purple::NotifyUserInfo user_info -gchar * +const gchar * purple_notify_user_info_entry_get_label(user_info_entry) Purple::NotifyUserInfoEntry user_info_entry -gchar * +const gchar * purple_notify_user_info_entry_get_value(user_info_entry) Purple::NotifyUserInfoEntry user_info_entry
--- a/libpurple/plugins/perl/common/Prefs.xs Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/common/Prefs.xs Mon Apr 28 06:27:11 2008 +0000 @@ -167,6 +167,17 @@ const char *name void +purple_prefs_get_children_names(name) + const char *name +PREINIT: + GList *l; +PPCODE: + for (l = purple_prefs_get_children_names(name); l != NULL; l = g_list_delete_link(l, l)) { + XPUSHs(sv_2mortal(newSVpv(l->data, 0))); + g_free(l->data); + } + +void purple_prefs_uninit() void
--- a/libpurple/plugins/perl/common/Purple.xs Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/common/Purple.xs Mon Apr 28 06:27:11 2008 +0000 @@ -74,14 +74,24 @@ PURPLE_PERL_BOOT(Util); PURPLE_PERL_BOOT(XMLNode); -void +guint timeout_add(plugin, seconds, callback, data = 0) Purple::Plugin plugin int seconds SV *callback SV *data CODE: - purple_perl_timeout_add(plugin, seconds, callback, data); + RETVAL = purple_perl_timeout_add(plugin, seconds, callback, data); +OUTPUT: + RETVAL + +gboolean +timeout_remove(handle) + guint handle +CODE: + RETVAL = purple_perl_timeout_remove(handle); +OUTPUT: + RETVAL void deinit()
--- a/libpurple/plugins/perl/common/Request.xs Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/common/Request.xs Mon Apr 28 06:27:11 2008 +0000 @@ -15,10 +15,20 @@ typedef struct { - char *cancel_cb; - char *ok_cb; + SV *ok_fun; + SV *cancel_fun; } PurplePerlRequestData; +static void +purple_perl_request_data_free(PurplePerlRequestData *ppr) +{ + if (ppr->ok_fun) + SvREFCNT_dec(ppr->ok_fun); + if (ppr->cancel_fun) + SvREFCNT_dec(ppr->cancel_fun); + g_free(ppr); +} + /********************************************************/ /* */ /* Callback function that calls a perl subroutine */ @@ -39,23 +49,19 @@ XPUSHs(purple_perl_bless_object(fields, "Purple::Request::Fields")); PUTBACK; - - call_pv(gpr->ok_cb, G_EVAL | G_SCALAR); + call_sv(gpr->ok_fun, G_EVAL | G_SCALAR); SPAGAIN; PUTBACK; FREETMPS; LEAVE; - g_free(gpr->ok_cb); - g_free(gpr->cancel_cb); - g_free(gpr); + purple_perl_request_data_free(gpr); } static void purple_perl_request_cancel_cb(void * data, PurpleRequestFields *fields) { - PurplePerlRequestData *gpr = (PurplePerlRequestData *)data; dSP; @@ -65,16 +71,14 @@ XPUSHs(purple_perl_bless_object(fields, "Purple::Request::Fields")); PUTBACK; - call_pv(gpr->cancel_cb, G_EVAL | G_SCALAR); + call_sv(gpr->cancel_fun, G_EVAL | G_SCALAR); SPAGAIN; PUTBACK; FREETMPS; LEAVE; - g_free(gpr->ok_cb); - g_free(gpr->cancel_cb); - g_free(gpr); + purple_perl_request_data_free(gpr); } MODULE = Purple::Request PACKAGE = Purple::Request PREFIX = purple_request_ @@ -131,14 +135,13 @@ SV * cancel_cb CODE: PurplePerlRequestData *gpr; - STRLEN len; char *basename; basename = g_path_get_basename(handle->path); purple_perl_normalize_script_name(basename); gpr = g_new(PurplePerlRequestData, 1); - gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len)); - gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len)); + gpr->ok_fun = purple_perl_sv_from_fun(handle, ok_cb); + gpr->cancel_fun = purple_perl_sv_from_fun(handle, cancel_cb); g_free(basename); RETVAL = purple_request_input(handle, title, primary, secondary, default_value, multiline, masked, hint, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr); @@ -155,14 +158,13 @@ SV * cancel_cb CODE: PurplePerlRequestData *gpr; - STRLEN len; char *basename; basename = g_path_get_basename(handle->path); purple_perl_normalize_script_name(basename); gpr = g_new(PurplePerlRequestData, 1); - gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len)); - gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len)); + gpr->ok_fun = purple_perl_sv_from_fun(handle, ok_cb); + gpr->cancel_fun = purple_perl_sv_from_fun(handle, cancel_cb); g_free(basename); RETVAL = purple_request_file(handle, title, filename, savedialog, G_CALLBACK(purple_perl_request_ok_cb), G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr); @@ -182,14 +184,13 @@ SV * cancel_cb CODE: PurplePerlRequestData *gpr; - STRLEN len; char *basename; basename = g_path_get_basename(handle->path); purple_perl_normalize_script_name(basename); gpr = g_new(PurplePerlRequestData, 1); - gpr->ok_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(ok_cb, len)); - gpr->cancel_cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cancel_cb, len)); + gpr->ok_fun = purple_perl_sv_from_fun(handle, ok_cb); + gpr->cancel_fun = purple_perl_sv_from_fun(handle, cancel_cb); g_free(basename); RETVAL = purple_request_fields(handle, title, primary, secondary, fields, ok_text, G_CALLBACK(purple_perl_request_ok_cb), cancel_text, G_CALLBACK(purple_perl_request_cancel_cb), NULL, NULL, NULL, gpr);
--- a/libpurple/plugins/perl/common/Util.xs Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/common/Util.xs Mon Apr 28 06:27:11 2008 +0000 @@ -1,11 +1,11 @@ #include "module.h" -typedef struct { - char *cb; -} PurplePerlUrlData; - -static void purple_perl_util_url_cb(PurpleUtilFetchUrlData *url_data, void *user_data, const gchar *url_text, size_t size, const gchar *error_message) { - PurplePerlUrlData *gpr = (PurplePerlUrlData *)user_data; +static void +purple_perl_util_url_cb(PurpleUtilFetchUrlData *url_data, void *user_data, + const gchar *url_text, size_t size, + const gchar *error_message) +{ + SV *sv = (SV *)user_data; dSP; ENTER; SAVETMPS; @@ -14,11 +14,12 @@ XPUSHs(sv_2mortal(newSVpvn(url_text, size))); PUTBACK; - call_pv(gpr->cb, G_EVAL | G_SCALAR); + call_sv(sv, G_EVAL | G_SCALAR); SPAGAIN; - g_free(gpr->cb); - g_free(gpr); + /* XXX Make sure this destroys it correctly and that we don't want + * something like sv_2mortal(sv) or something else here instead. */ + SvREFCNT_dec(sv); PUTBACK; FREETMPS; @@ -248,25 +249,22 @@ PROTOTYPES: ENABLE void -purple_util_fetch_url(handle, url, full, user_agent, http11, cb) - Purple::Plugin handle +purple_util_fetch_url(plugin, url, full, user_agent, http11, cb) + Purple::Plugin plugin const char *url gboolean full const char *user_agent gboolean http11 SV * cb CODE: - PurplePerlUrlData *gpr; - STRLEN len; - char *basename; + SV *sv = purple_perl_sv_from_fun(plugin, cb); - basename = g_path_get_basename(handle->path); - purple_perl_normalize_script_name(basename); - gpr = g_new(PurplePerlUrlData, 1); - - gpr->cb = g_strdup_printf("Purple::Script::%s::%s", basename, SvPV(cb, len)); - g_free(basename); - purple_util_fetch_url(url, full, user_agent, http11, purple_perl_util_url_cb, gpr); + if (sv != NULL) { + purple_util_fetch_url(url, full, user_agent, http11, + purple_perl_util_url_cb, sv); + } else { + purple_debug_warning("perl", "Callback not a valid type, only strings and coderefs allowed in purple_util_fetch_url.\n"); + } void purple_util_set_user_dir(dir)
--- a/libpurple/plugins/perl/perl-common.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/perl-common.c Mon Apr 28 06:27:11 2008 +0000 @@ -616,3 +616,26 @@ return NULL; } + +SV *purple_perl_sv_from_fun(PurplePlugin *plugin, SV *callback) +{ + SV *sv = NULL; + + if (SvTYPE(callback) == SVt_RV) { + SV *cbsv = SvRV(callback); + + if (SvTYPE(cbsv) == SVt_PVCV) { + sv = newSVsv(callback); + } + } else if (SvTYPE(callback) == SVt_PV) { + PurplePerlScript *gps; + + gps = (PurplePerlScript *)PURPLE_PLUGIN_LOADER_INFO(plugin); + sv = newSVpvf("%s::%s", gps->package, SvPV_nolen(callback)); + } else { + purple_debug_warning("perl", "Callback not a valid type, only strings and coderefs allowed.\n"); + } + + return sv; +} +
--- a/libpurple/plugins/perl/perl-common.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/perl-common.h Mon Apr 28 06:27:11 2008 +0000 @@ -67,5 +67,5 @@ void *purple_perl_data_from_sv(PurpleValue *value, SV *sv); SV *purple_perl_sv_from_vargs(const PurpleValue *value, va_list *args, void ***copy_arg); - +SV *purple_perl_sv_from_fun(PurplePlugin *plugin, SV *callback); #endif /* _PURPLE_PERL_COMMON_H_ */
--- a/libpurple/plugins/perl/perl-handlers.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/perl-handlers.c Mon Apr 28 06:27:11 2008 +0000 @@ -207,13 +207,15 @@ return ret_frame; } -static void +static gboolean destroy_timeout_handler(PurplePerlTimeoutHandler *handler) { + gboolean ret = FALSE; + timeout_handlers = g_list_remove(timeout_handlers, handler); if (handler->iotag > 0) - purple_timeout_remove(handler->iotag); + ret = purple_timeout_remove(handler->iotag); if (handler->callback != NULL) SvREFCNT_dec(handler->callback); @@ -222,6 +224,8 @@ SvREFCNT_dec(handler->data); g_free(handler); + + return ret; } static void @@ -301,8 +305,8 @@ for (i = 0; i < value_count; i++) { sv_args[i] = purple_perl_sv_from_vargs(values[i], - (va_list*)&args, - ©_args[i]); + (va_list*)&args, + ©_args[i]); XPUSHs(sv_args[i]); } @@ -422,14 +426,14 @@ return NULL; } -void +guint purple_perl_timeout_add(PurplePlugin *plugin, int seconds, SV *callback, SV *data) { PurplePerlTimeoutHandler *handler; if (plugin == NULL) { croak("Invalid handle in adding perl timeout handler.\n"); - return; + return 0; } handler = g_new0(PurplePerlTimeoutHandler, 1); @@ -443,15 +447,39 @@ timeout_handlers = g_list_append(timeout_handlers, handler); handler->iotag = purple_timeout_add(seconds * 1000, perl_timeout_cb, handler); + + return handler->iotag; +} + +gboolean +purple_perl_timeout_remove(guint handle) +{ + GList *l, *l_next; + + for (l = timeout_handlers; l != NULL; l = l_next) { + PurplePerlTimeoutHandler *handler; + + l_next = l->next; + + handler = (PurplePerlTimeoutHandler *)l->data; + + if (handler->iotag == handle) + return destroy_timeout_handler(handler); + } + + purple_debug_info("perl", "No timeout handler found with handle %u.\n", + handle); + return FALSE; } void purple_perl_timeout_clear_for_plugin(PurplePlugin *plugin) { - PurplePerlTimeoutHandler *handler; GList *l, *l_next; for (l = timeout_handlers; l != NULL; l = l_next) { + PurplePerlTimeoutHandler *handler; + l_next = l->next; handler = (PurplePerlTimeoutHandler *)l->data;
--- a/libpurple/plugins/perl/perl-handlers.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/perl/perl-handlers.h Mon Apr 28 06:27:11 2008 +0000 @@ -48,8 +48,9 @@ GtkWidget *purple_perl_gtk_get_plugin_frame(PurplePlugin *plugin); #endif -void purple_perl_timeout_add(PurplePlugin *plugin, int seconds, SV *callback, - SV *data); +guint purple_perl_timeout_add(PurplePlugin *plugin, int seconds, SV *callback, + SV *data); +gboolean purple_perl_timeout_remove(guint handle); void purple_perl_timeout_clear_for_plugin(PurplePlugin *plugin); void purple_perl_timeout_clear(void);
--- a/libpurple/plugins/statenotify.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/plugins/statenotify.c Mon Apr 28 06:27:11 2008 +0000 @@ -42,6 +42,10 @@ { gboolean available, old_available; + if (!purple_status_is_exclusive(status) || + !purple_status_is_exclusive(old_status)) + return; + available = purple_status_is_available(status); old_available = purple_status_is_available(old_status);
--- a/libpurple/protocols/irc/msgs.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/irc/msgs.c Mon Apr 28 06:27:11 2008 +0000 @@ -706,16 +706,16 @@ void irc_msg_invite(struct irc_conn *irc, const char *name, const char *from, char **args) { PurpleConnection *gc = purple_account_get_connection(irc->account); - GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - char *nick = irc_mask_nick(from); + GHashTable *components; + gchar *nick; - if (!args || !args[1] || !gc) { - g_free(nick); - g_hash_table_destroy(components); + if (!args || !args[1] || !gc) return; - } - g_hash_table_insert(components, strdup("channel"), strdup(args[1])); + components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + nick = irc_mask_nick(from); + + g_hash_table_insert(components, g_strdup("channel"), g_strdup(args[1])); serv_got_chat_invite(gc, args[1], nick, NULL, components); g_free(nick); @@ -980,7 +980,7 @@ if (!args || !args[1]) return; - newnick = strdup(args[1]); + newnick = g_strdup(args[1]); end = newnick + strlen(newnick) - 1; /* try fallbacks */ if((*end < '9') && (*end >= '1')) {
--- a/libpurple/protocols/msnp9/nexus.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/msnp9/nexus.c Mon Apr 28 06:27:11 2008 +0000 @@ -337,7 +337,8 @@ username = g_strdup(purple_url_encode(purple_account_get_username(session->account))); - password = g_strndup(purple_connection_get_password(session->account->gc), 16); + password = g_utf8_strncpy(g_strdup(purple_connection_get_password(session->account->gc)), + purple_connection_get_password(session->account->gc), 16); encpass = g_strdup(purple_url_encode(password)); g_free(password);
--- a/libpurple/protocols/msnp9/slplink.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/msnp9/slplink.c Mon Apr 28 06:27:11 2008 +0000 @@ -118,6 +118,8 @@ while (slplink->slp_calls != NULL) msn_slp_call_destroy(slplink->slp_calls->data); + g_queue_free(slplink->slp_msg_queue); + session->slplinks = g_list_remove(session->slplinks, slplink);
--- a/libpurple/protocols/msnp9/switchboard.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/msnp9/switchboard.c Mon Apr 28 06:27:11 2008 +0000 @@ -111,6 +111,9 @@ for (l = swboard->users; l != NULL; l = l->next) g_free(l->data); + if (swboard->users != NULL) + g_list_free(swboard->users); + session = swboard->session; session->switches = g_list_remove(session->switches, swboard);
--- a/libpurple/protocols/oscar/bstream.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/bstream.c Mon Apr 28 06:27:11 2008 +0000 @@ -45,6 +45,11 @@ return 0; } +void byte_stream_destroy(ByteStream *bs) +{ + g_free(bs->data); +} + int byte_stream_empty(ByteStream *bs) { return bs->len - bs->offset;
--- a/libpurple/protocols/oscar/family_admin.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_admin.c Mon Apr 28 06:27:11 2008 +0000 @@ -40,18 +40,18 @@ int aim_admin_getinfo(OscarData *od, FlapConnection *conn, guint16 info) { - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; - fr = flap_frame_new(od, 0x02, 14); + byte_stream_new(&bs, 4); - snacid = aim_cachesnac(od, 0x0007, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0007, 0x0002, 0x0000, snacid); + byte_stream_put16(&bs, info); + byte_stream_put16(&bs, 0x0000); - byte_stream_put16(&fr->data, info); - byte_stream_put16(&fr->data, 0x0000); + snacid = aim_cachesnac(od, 0x0007, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0007, 0x0002, 0x0000, snacid, &bs); - flap_connection_send(conn, fr); + byte_stream_destroy(&bs); return 0; } @@ -120,25 +120,28 @@ * Subtype 0x0004 - Set screenname formatting. * */ +/* + * Subtype 0x0004 - Set screenname formatting. + * + */ int aim_admin_setnick(OscarData *od, FlapConnection *conn, const char *newnick) { - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; 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); + byte_stream_new(&bs, 2+2+strlen(newnick)); aim_tlvlist_add_str(&tlvlist, 0x0001, newnick); - aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); return 0; } @@ -150,14 +153,11 @@ int aim_admin_changepasswd(OscarData *od, FlapConnection *conn, const char *newpw, const char *curpw) { - FlapFrame *fr; + ByteStream bs; GSList *tlvlist = NULL; aim_snacid_t snacid; - fr = flap_frame_new(od, 0x02, 10+4+strlen(curpw)+4+strlen(newpw)); - - snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid); + byte_stream_new(&bs, 4+strlen(curpw)+4+strlen(newpw)); /* new password TLV t(0002) */ aim_tlvlist_add_str(&tlvlist, 0x0002, newpw); @@ -165,10 +165,11 @@ /* current password TLV t(0012) */ aim_tlvlist_add_str(&tlvlist, 0x0012, curpw); - aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs); return 0; } @@ -180,21 +181,21 @@ int aim_admin_setemail(OscarData *od, FlapConnection *conn, const char *newemail) { - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; 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); + byte_stream_new(&bs, 2+2+strlen(newemail)); aim_tlvlist_add_str(&tlvlist, 0x0011, newemail); - aim_tlvlist_write(&fr->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0007, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0007, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_alert.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_alert.c Mon Apr 28 06:27:11 2008 +0000 @@ -41,40 +41,41 @@ aim_email_sendcookies(OscarData *od) { FlapConnection *conn; - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ALERT))) return -EINVAL; - fr = flap_frame_new(od, 0x02, 10+2+16+16); - snacid = aim_cachesnac(od, 0x0018, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0018, 0x0006, 0x0000, snacid); + byte_stream_new(&bs, 2+16+16); /* Number of cookies to follow */ - byte_stream_put16(&fr->data, 0x0002); + byte_stream_put16(&bs, 0x0002); /* Cookie */ - byte_stream_put16(&fr->data, 0x5d5e); - byte_stream_put16(&fr->data, 0x1708); - byte_stream_put16(&fr->data, 0x55aa); - byte_stream_put16(&fr->data, 0x11d3); - byte_stream_put16(&fr->data, 0xb143); - byte_stream_put16(&fr->data, 0x0060); - byte_stream_put16(&fr->data, 0xb0fb); - byte_stream_put16(&fr->data, 0x1ecb); + byte_stream_put16(&bs, 0x5d5e); + byte_stream_put16(&bs, 0x1708); + byte_stream_put16(&bs, 0x55aa); + byte_stream_put16(&bs, 0x11d3); + byte_stream_put16(&bs, 0xb143); + byte_stream_put16(&bs, 0x0060); + byte_stream_put16(&bs, 0xb0fb); + byte_stream_put16(&bs, 0x1ecb); /* Cookie */ - byte_stream_put16(&fr->data, 0xb380); - byte_stream_put16(&fr->data, 0x9ad8); - byte_stream_put16(&fr->data, 0x0dba); - byte_stream_put16(&fr->data, 0x11d5); - byte_stream_put16(&fr->data, 0x9f8a); - byte_stream_put16(&fr->data, 0x0060); - byte_stream_put16(&fr->data, 0xb0ee); - byte_stream_put16(&fr->data, 0x0631); + byte_stream_put16(&bs, 0xb380); + byte_stream_put16(&bs, 0x9ad8); + byte_stream_put16(&bs, 0x0dba); + byte_stream_put16(&bs, 0x11d5); + byte_stream_put16(&bs, 0x9f8a); + byte_stream_put16(&bs, 0x0060); + byte_stream_put16(&bs, 0xb0ee); + byte_stream_put16(&bs, 0x0631); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0018, 0x0006, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -171,25 +172,26 @@ aim_email_activate(OscarData *od) { FlapConnection *conn; - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ALERT))) return -EINVAL; - fr = flap_frame_new(od, 0x02, 10+1+16); - snacid = aim_cachesnac(od, 0x0018, 0x0016, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0018, 0x0016, 0x0000, snacid); + byte_stream_new(&bs, 1+16); /* I would guess this tells AIM that you want updates for your mail accounts */ /* ...but I really have no idea */ - byte_stream_put8(&fr->data, 0x02); - byte_stream_put32(&fr->data, 0x04000000); - byte_stream_put32(&fr->data, 0x04000000); - byte_stream_put32(&fr->data, 0x04000000); - byte_stream_put32(&fr->data, 0x00000000); + byte_stream_put8(&bs, 0x02); + byte_stream_put32(&bs, 0x04000000); + byte_stream_put32(&bs, 0x04000000); + byte_stream_put32(&bs, 0x04000000); + byte_stream_put32(&bs, 0x00000000); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0018, 0x0016, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0018, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_bart.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_bart.c Mon Apr 28 06:27:11 2008 +0000 @@ -40,25 +40,26 @@ aim_bart_upload(OscarData *od, const guint8 *icon, guint16 iconlen) { FlapConnection *conn; - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !icon || !iconlen) return -EINVAL; - fr = flap_frame_new(od, 0x02, 10 + 2 + 2+iconlen); - snacid = aim_cachesnac(od, 0x0010, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0010, 0x0002, 0x0000, snacid); + byte_stream_new(&bs, 2 + 2 + iconlen); /* The reference number for the icon */ - byte_stream_put16(&fr->data, 1); + byte_stream_put16(&bs, 1); /* The icon */ - byte_stream_put16(&fr->data, iconlen); - byte_stream_putraw(&fr->data, icon, iconlen); + byte_stream_put16(&bs, iconlen); + byte_stream_putraw(&bs, icon, iconlen); - flap_connection_send(conn, fr); - + snacid = aim_cachesnac(od, 0x0010, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0010, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -98,30 +99,31 @@ aim_bart_request(OscarData *od, const char *sn, guint8 iconcsumtype, const guint8 *iconcsum, guint16 iconcsumlen) { FlapConnection *conn; - FlapFrame *fr; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, 0x0010)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen) return -EINVAL; - fr = flap_frame_new(od, 0x02, 10 + 1+strlen(sn) + 4 + 1+iconcsumlen); - snacid = aim_cachesnac(od, 0x0010, 0x0004, 0x0000, NULL, 0); - aim_putsnac(&fr->data, 0x0010, 0x0004, 0x0000, snacid); + byte_stream_new(&bs, 1+strlen(sn) + 4 + 1+iconcsumlen); /* Screen name */ - byte_stream_put8(&fr->data, strlen(sn)); - byte_stream_putstr(&fr->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); /* Some numbers. You like numbers, right? */ - byte_stream_put8(&fr->data, 0x01); - byte_stream_put16(&fr->data, 0x0001); - byte_stream_put8(&fr->data, iconcsumtype); + byte_stream_put8(&bs, 0x01); + byte_stream_put16(&bs, 0x0001); + byte_stream_put8(&bs, iconcsumtype); /* Icon string */ - byte_stream_put8(&fr->data, iconcsumlen); - byte_stream_putraw(&fr->data, iconcsum, iconcsumlen); + byte_stream_put8(&bs, iconcsumlen); + byte_stream_putraw(&bs, iconcsum, iconcsumlen); - flap_connection_send(conn, fr); + snacid = aim_cachesnac(od, 0x0010, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0010, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_bos.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_bos.c Mon Apr 28 06:27:11 2008 +0000 @@ -114,7 +114,7 @@ */ int aim_bos_changevisibility(OscarData *od, FlapConnection *conn, int changetype, const char *denylist) { - FlapFrame *frame; + ByteStream bs; int packlen = 0; guint16 subtype; char *localcpy = NULL, *tmpptr = NULL; @@ -139,24 +139,24 @@ localcpy = g_strdup(denylist); listcount = aimutil_itemcnt(localcpy, '&'); - packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9; + packlen = aimutil_tokslen(localcpy, 99, '&') + listcount-1; - frame = flap_frame_new(od, 0x02, packlen); - - snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0009, subtype, 0x00, snacid); + byte_stream_new(&bs, packlen); for (i = 0; (i < (listcount - 1)) && (i < 99); i++) { tmpptr = aimutil_itemindex(localcpy, i, '&'); - byte_stream_put8(&frame->data, strlen(tmpptr)); - byte_stream_putstr(&frame->data, tmpptr); + byte_stream_put8(&bs, strlen(tmpptr)); + byte_stream_putstr(&bs, tmpptr); g_free(tmpptr); } g_free(localcpy); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0009, subtype, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_buddy.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Mon Apr 28 06:27:11 2008 +0000 @@ -97,21 +97,21 @@ int aim_buddylist_addbuddy(OscarData *od, FlapConnection *conn, const char *sn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!sn || !strlen(sn)) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)); + byte_stream_new(&bs, 1+strlen(sn)); + + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1); - aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid); + flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs); - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); - - flap_connection_send(conn, frame); + byte_stream_destroy(&bs); return 0; } @@ -129,7 +129,7 @@ int aim_buddylist_set(OscarData *od, FlapConnection *conn, const char *buddy_list) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int len = 0; char *localcpy = NULL; @@ -145,10 +145,7 @@ tmpptr = strtok(NULL, "&"); } - frame = flap_frame_new(od, 0x02, 10+len); - - snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0003, 0x0004, 0x0000, snacid); + byte_stream_new(&bs, len); strncpy(localcpy, buddy_list, strlen(buddy_list) + 1); @@ -157,12 +154,15 @@ purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT ")\n", tmpptr, strlen(tmpptr)); - byte_stream_put8(&frame->data, strlen(tmpptr)); - byte_stream_putstr(&frame->data, tmpptr); + byte_stream_put8(&bs, strlen(tmpptr)); + byte_stream_putstr(&bs, tmpptr); tmpptr = strtok(NULL, "&"); } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0003, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0003, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); g_free(localcpy); @@ -179,21 +179,21 @@ int aim_buddylist_removebuddy(OscarData *od, FlapConnection *conn, const char *sn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!sn || !strlen(sn)) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)); + byte_stream_new(&bs, 1 + strlen(sn)); + + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); snacid = aim_cachesnac(od, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1); - aim_putsnac(&frame->data, 0x0003, 0x0005, 0x0000, snacid); + flap_connection_send_snac(od, conn, 0x0003, 0x0005, 0x0000, snacid, &bs); - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); - - flap_connection_send(conn, frame); + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_chat.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_chat.c Mon Apr 28 06:27:11 2008 +0000 @@ -353,7 +353,7 @@ aim_chat_send_im(OscarData *od, FlapConnection *conn, guint16 flags, const gchar *msg, int msglen, const char *encoding, const char *language) { int i; - FlapFrame *frame; + ByteStream bs; IcbmCookie *cookie; aim_snacid_t snacid; guint8 ckstr[8]; @@ -362,10 +362,9 @@ if (!od || !conn || !msg || (msglen <= 0)) return 0; - frame = flap_frame_new(od, 0x02, 1152); + byte_stream_new(&bs, 1142); snacid = aim_cachesnac(od, 0x000e, 0x0005, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x000e, 0x0005, 0x0000, snacid); /* * Cookie @@ -382,8 +381,8 @@ aim_cachecookie(od, cookie); /* ICBM Header */ - byte_stream_putraw(&frame->data, ckstr, 8); /* Cookie */ - byte_stream_put16(&frame->data, 0x0003); /* Channel */ + byte_stream_putraw(&bs, ckstr, 8); /* Cookie */ + byte_stream_put16(&bs, 0x0003); /* Channel */ /* * Type 1: Flag meaning this message is destined to the room. @@ -428,13 +427,15 @@ */ aim_tlvlist_add_frozentlvlist(&tlvlist, 0x0005, &inner_tlvlist); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x000e, 0x0005, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/family_chatnav.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_chatnav.c Mon Apr 28 06:27:11 2008 +0000 @@ -91,17 +91,16 @@ static const char ck[] = {"create"}; static const char lang[] = {"en"}; static const char charset[] = {"us-ascii"}; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; - frame = flap_frame_new(od, 0x02, 1152); + byte_stream_new(&bs, 1142); snacid = aim_cachesnac(od, 0x000d, 0x0008, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x000d, 0x0008, 0x0000, snacid); /* exchange */ - byte_stream_put16(&frame->data, exchange); + byte_stream_put16(&bs, exchange); /* * This looks to be a big hack. You'll note that this entire @@ -114,8 +113,8 @@ * AOL style, I'm going to guess that it is the latter, and that * the value of the room name in create requests is ignored. */ - byte_stream_put8(&frame->data, strlen(ck)); - byte_stream_putstr(&frame->data, ck); + byte_stream_put8(&bs, strlen(ck)); + byte_stream_putstr(&bs, ck); /* * instance @@ -123,22 +122,24 @@ * Setting this to 0xffff apparently assigns the last instance. * */ - byte_stream_put16(&frame->data, 0xffff); + byte_stream_put16(&bs, 0xffff); /* detail level */ - byte_stream_put8(&frame->data, 0x01); + byte_stream_put8(&bs, 0x01); 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(tlvlist)); - aim_tlvlist_write(&frame->data, &tlvlist); + byte_stream_put16(&bs, aim_tlvlist_count(tlvlist)); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x000d, 0x0008, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_feedbag.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Mon Apr 28 06:27:11 2008 +0000 @@ -1241,21 +1241,21 @@ int aim_ssi_reqifchanged(OscarData *od, time_t timestamp, guint16 numitems) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG))) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+4+2); + byte_stream_new(&bs, 4+2); + + byte_stream_put32(&bs, timestamp); + byte_stream_put16(&bs, numitems); snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, snacid, &bs); - aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_REQIFCHANGED, 0x0000, snacid); - byte_stream_put32(&frame->data, timestamp); - byte_stream_put16(&frame->data, numitems); - - flap_connection_send(conn, frame); + byte_stream_destroy(&bs); /* Free any current data, just in case */ aim_ssi_freelist(od); @@ -1343,42 +1343,42 @@ static int aim_ssi_addmoddel(OscarData *od) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; - int snaclen; + int bslen; struct aim_ssi_tmp *cur; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !od->ssi.pending || !od->ssi.pending->item) return -EINVAL; /* Calculate total SNAC size */ - snaclen = 10; /* For family, subtype, flags, and SNAC ID */ + bslen = 0; for (cur=od->ssi.pending; cur; cur=cur->next) { - snaclen += 10; /* For length, GID, BID, type, and length */ + bslen += 10; /* For length, GID, BID, type, and length */ if (cur->item->name) - snaclen += strlen(cur->item->name); + bslen += strlen(cur->item->name); if (cur->item->data) - snaclen += aim_tlvlist_size(cur->item->data); + bslen += aim_tlvlist_size(cur->item->data); } - frame = flap_frame_new(od, 0x02, snaclen); + byte_stream_new(&bs, bslen); + + for (cur=od->ssi.pending; cur; cur=cur->next) { + byte_stream_put16(&bs, cur->item->name ? strlen(cur->item->name) : 0); + if (cur->item->name) + byte_stream_putstr(&bs, cur->item->name); + byte_stream_put16(&bs, cur->item->gid); + byte_stream_put16(&bs, cur->item->bid); + byte_stream_put16(&bs, cur->item->type); + byte_stream_put16(&bs, cur->item->data ? aim_tlvlist_size(cur->item->data) : 0); + if (cur->item->data) + aim_tlvlist_write(&bs, &cur->item->data); + } snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0); - aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid); + flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid, &bs); - for (cur=od->ssi.pending; cur; cur=cur->next) { - byte_stream_put16(&frame->data, cur->item->name ? strlen(cur->item->name) : 0); - if (cur->item->name) - byte_stream_putstr(&frame->data, cur->item->name); - 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); - if (cur->item->data) - aim_tlvlist_write(&frame->data, &cur->item->data); - } - - flap_connection_send(conn, frame); + byte_stream_destroy(&bs); return 0; } @@ -1684,32 +1684,32 @@ int aim_ssi_sendauth(OscarData *od, char *sn, char *msg) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2); - - snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, NULL, 0); - aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, snacid); + byte_stream_new(&bs, 1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2); /* Screen name */ - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); /* Message (null terminated) */ - byte_stream_put16(&frame->data, msg ? strlen(msg) : 0); + byte_stream_put16(&bs, msg ? strlen(msg) : 0); if (msg) { - byte_stream_putstr(&frame->data, msg); - byte_stream_put8(&frame->data, 0x00); + byte_stream_putstr(&bs, msg); + byte_stream_put8(&bs, 0x00); } /* Unknown */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTH, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1758,32 +1758,32 @@ int aim_ssi_sendauthrequest(OscarData *od, char *sn, const char *msg) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2); - - snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, NULL, 0); - aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, snacid); + byte_stream_new(&bs, 1+strlen(sn) + 2+(msg ? (strlen(msg)+1) : 0) + 2); /* Screen name */ - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); /* Message (null terminated) */ - byte_stream_put16(&frame->data, msg ? strlen(msg) : 0); + byte_stream_put16(&bs, msg ? strlen(msg) : 0); if (msg) { - byte_stream_putstr(&frame->data, msg); - byte_stream_put8(&frame->data, 0x00); + byte_stream_putstr(&bs, msg); + byte_stream_put8(&bs, 0x00); } /* Unknown */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1835,36 +1835,36 @@ int aim_ssi_sendauthreply(OscarData *od, char *sn, guint8 reply, const char *msg) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2); - - snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, NULL, 0); - aim_putsnac(&frame->data, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, snacid); + byte_stream_new(&bs, 1+strlen(sn) + 1 + 2+(msg ? (strlen(msg)+1) : 0) + 2); /* Screen name */ - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); /* Grant or deny */ - byte_stream_put8(&frame->data, reply); + byte_stream_put8(&bs, reply); /* Message (null terminated) */ - byte_stream_put16(&frame->data, msg ? (strlen(msg)+1) : 0); + byte_stream_put16(&bs, msg ? (strlen(msg)+1) : 0); if (msg) { - byte_stream_putstr(&frame->data, msg); - byte_stream_put8(&frame->data, 0x00); + byte_stream_putstr(&bs, msg); + byte_stream_put8(&bs, 0x00); } /* Unknown */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/family_icbm.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Mon Apr 28 06:27:11 2008 +0000 @@ -161,7 +161,7 @@ int aim_im_setparams(OscarData *od, struct aim_icbmparameters *params) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) @@ -170,23 +170,23 @@ if (!params) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+16); - - snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0002, 0x0000, snacid); + byte_stream_new(&bs, 16); /* This is read-only (see Parameter Reply). Must be set to zero here. */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); /* These are all read-write */ - byte_stream_put32(&frame->data, params->flags); - byte_stream_put16(&frame->data, params->maxmsglen); - byte_stream_put16(&frame->data, params->maxsenderwarn); - byte_stream_put16(&frame->data, params->maxrecverwarn); - byte_stream_put32(&frame->data, params->minmsginterval); - - flap_connection_send(conn, frame); - + byte_stream_put32(&bs, params->flags); + byte_stream_put16(&bs, params->maxmsglen); + byte_stream_put16(&bs, params->maxsenderwarn); + byte_stream_put16(&bs, params->maxrecverwarn); + byte_stream_put32(&bs, params->minmsginterval); + + snacid = aim_cachesnac(od, 0x0004, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0004, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -413,7 +413,7 @@ snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1); flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &data); - g_free(data.data); + byte_stream_destroy(&data); /* clean out SNACs over 60sec old */ aim_cleansnacs(od, 60); @@ -454,7 +454,7 @@ int aim_im_sendch2_chatinvite(OscarData *od, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; IcbmCookie *msgcookie; struct aim_invite_priv *priv; @@ -470,10 +470,9 @@ aim_icbm_makecookie(cookie); - frame = flap_frame_new(od, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg)); + byte_stream_new(&bs, 1142+strlen(sn)+strlen(roomname)+strlen(msg)); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* XXX should be uncached by an unwritten 'invite accept' handler */ priv = g_malloc(sizeof(struct aim_invite_priv)); @@ -488,7 +487,7 @@ g_free(priv); /* ICBM Header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); /* * TLV t(0005) @@ -513,14 +512,16 @@ 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, &outer_tlvlist); + byte_stream_destroy(&hdrbs); + + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -534,7 +535,7 @@ int aim_im_sendch2_icon(OscarData *od, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; guchar cookie[8]; @@ -546,51 +547,52 @@ aim_icbm_makecookie(cookie); - frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2); + byte_stream_new(&bs, 8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); /* * TLV t(0005) * * Encompasses everything below. */ - byte_stream_put16(&frame->data, 0x0005); - byte_stream_put16(&frame->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT)); - - byte_stream_put16(&frame->data, 0x0000); - byte_stream_putraw(&frame->data, cookie, 8); - byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_BUDDYICON); + byte_stream_put16(&bs, 0x0005); + byte_stream_put16(&bs, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT)); + + byte_stream_put16(&bs, 0x0000); + byte_stream_putraw(&bs, cookie, 8); + byte_stream_putcaps(&bs, OSCAR_CAPABILITY_BUDDYICON); /* TLV t(000a) */ - byte_stream_put16(&frame->data, 0x000a); - byte_stream_put16(&frame->data, 0x0002); - byte_stream_put16(&frame->data, 0x0001); + byte_stream_put16(&bs, 0x000a); + byte_stream_put16(&bs, 0x0002); + byte_stream_put16(&bs, 0x0001); /* TLV t(000f) */ - byte_stream_put16(&frame->data, 0x000f); - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x000f); + byte_stream_put16(&bs, 0x0000); /* TLV t(2711) */ - byte_stream_put16(&frame->data, 0x2711); - byte_stream_put16(&frame->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT)); - byte_stream_put16(&frame->data, 0x0000); - byte_stream_put16(&frame->data, iconsum); - byte_stream_put32(&frame->data, iconlen); - byte_stream_put32(&frame->data, stamp); - byte_stream_putraw(&frame->data, icon, iconlen); - byte_stream_putstr(&frame->data, AIM_ICONIDENT); + byte_stream_put16(&bs, 0x2711); + byte_stream_put16(&bs, 4+4+4+iconlen+strlen(AIM_ICONIDENT)); + byte_stream_put16(&bs, 0x0000); + byte_stream_put16(&bs, iconsum); + byte_stream_put32(&bs, iconlen); + byte_stream_put32(&bs, stamp); + byte_stream_putraw(&bs, icon, iconlen); + byte_stream_putstr(&bs, AIM_ICONIDENT); /* TLV t(0003) */ - byte_stream_put16(&frame->data, 0x0003); - byte_stream_put16(&frame->data, 0x0000); - - flap_connection_send(conn, frame); - + byte_stream_put16(&bs, 0x0003); + byte_stream_put16(&bs, 0x0000); + + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -612,7 +614,7 @@ int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; guchar cookie[8]; const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* OSCAR_CAPABILITY_ICQRTF capability in string form */ @@ -628,61 +630,62 @@ aim_icbm_makecookie(cookie); - frame = flap_frame_new(od, 0x02, 10+128+servdatalen); + byte_stream_new(&bs, 128+servdatalen); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, args->destsn); + aim_im_puticbm(&bs, cookie, 0x0002, args->destsn); /* TLV t(0005) - Encompasses everything below. */ - byte_stream_put16(&frame->data, 0x0005); - byte_stream_put16(&frame->data, 2+8+16 + 2+2+2 + 2+2 + 2+2+servdatalen); - - byte_stream_put16(&frame->data, 0x0000); - byte_stream_putraw(&frame->data, cookie, 8); - byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY); + byte_stream_put16(&bs, 0x0005); + byte_stream_put16(&bs, 2+8+16 + 2+2+2 + 2+2 + 2+2+servdatalen); + + byte_stream_put16(&bs, 0x0000); + byte_stream_putraw(&bs, cookie, 8); + byte_stream_putcaps(&bs, OSCAR_CAPABILITY_ICQSERVERRELAY); /* t(000a) l(0002) v(0001) */ - byte_stream_put16(&frame->data, 0x000a); - byte_stream_put16(&frame->data, 0x0002); - byte_stream_put16(&frame->data, 0x0001); + byte_stream_put16(&bs, 0x000a); + byte_stream_put16(&bs, 0x0002); + byte_stream_put16(&bs, 0x0001); /* t(000f) l(0000) v() */ - byte_stream_put16(&frame->data, 0x000f); - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x000f); + byte_stream_put16(&bs, 0x0000); /* Service Data TLV */ - byte_stream_put16(&frame->data, 0x2711); - byte_stream_put16(&frame->data, servdatalen); - - byte_stream_putle16(&frame->data, 11 + 16 /* 11 + (sizeof CLSID) */); - byte_stream_putle16(&frame->data, 9); - byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY); - byte_stream_putle16(&frame->data, 0); - byte_stream_putle32(&frame->data, 0); - byte_stream_putle8(&frame->data, 0); - byte_stream_putle16(&frame->data, 0x03ea); /* trid1 */ - - byte_stream_putle16(&frame->data, 14); - byte_stream_putle16(&frame->data, 0x03eb); /* trid2 */ - byte_stream_putle32(&frame->data, 0); - byte_stream_putle32(&frame->data, 0); - byte_stream_putle32(&frame->data, 0); - - byte_stream_putle16(&frame->data, 0x0001); - byte_stream_putle32(&frame->data, 0); - byte_stream_putle16(&frame->data, strlen(args->rtfmsg)+1); - byte_stream_putraw(&frame->data, (const guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1); - - byte_stream_putle32(&frame->data, args->fgcolor); - byte_stream_putle32(&frame->data, args->bgcolor); - byte_stream_putle32(&frame->data, strlen(rtfcap)+1); - byte_stream_putraw(&frame->data, (const guint8 *)rtfcap, strlen(rtfcap)+1); - - flap_connection_send(conn, frame); - + byte_stream_put16(&bs, 0x2711); + byte_stream_put16(&bs, servdatalen); + + byte_stream_putle16(&bs, 11 + 16 /* 11 + (sizeof CLSID) */); + byte_stream_putle16(&bs, 9); + byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY); + byte_stream_putle16(&bs, 0); + byte_stream_putle32(&bs, 0); + byte_stream_putle8(&bs, 0); + byte_stream_putle16(&bs, 0x03ea); /* trid1 */ + + byte_stream_putle16(&bs, 14); + byte_stream_putle16(&bs, 0x03eb); /* trid2 */ + byte_stream_putle32(&bs, 0); + byte_stream_putle32(&bs, 0); + byte_stream_putle32(&bs, 0); + + byte_stream_putle16(&bs, 0x0001); + byte_stream_putle32(&bs, 0); + byte_stream_putle16(&bs, strlen(args->rtfmsg)+1); + byte_stream_putraw(&bs, (const guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1); + + byte_stream_putle32(&bs, args->fgcolor); + byte_stream_putle32(&bs, args->bgcolor); + byte_stream_putle32(&bs, strlen(rtfcap)+1); + byte_stream_putraw(&bs, (const guint8 *)rtfcap, strlen(rtfcap)+1); + + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -695,7 +698,7 @@ { OscarData *od; FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; @@ -705,13 +708,12 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 128+strlen(peer_conn->sn)); + byte_stream_new(&bs, 118+strlen(peer_conn->sn)); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn); + aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -728,12 +730,14 @@ aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data); g_free(hdrbs.data); - aim_tlvlist_write(&frame->data, &outer_tlvlist); + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -745,7 +749,7 @@ { OscarData *od; FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; od = peer_conn->od; @@ -753,21 +757,22 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 10 + 11+strlen(peer_conn->sn) + 4+2+8+16); + byte_stream_new(&bs, 11+strlen(peer_conn->sn) + 4+2+8+16); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn); - - byte_stream_put16(&frame->data, 0x0005); - byte_stream_put16(&frame->data, 0x001a); - byte_stream_put16(&frame->data, AIM_RENDEZVOUS_CONNECTED); - byte_stream_putraw(&frame->data, peer_conn->cookie, 8); - byte_stream_putcaps(&frame->data, peer_conn->type); - - flap_connection_send(conn, frame); + aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn); + + byte_stream_put16(&bs, 0x0005); + byte_stream_put16(&bs, 0x001a); + byte_stream_put16(&bs, AIM_RENDEZVOUS_CONNECTED); + byte_stream_putraw(&bs, peer_conn->cookie, 8); + byte_stream_putcaps(&bs, peer_conn->type); + + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -781,7 +786,7 @@ aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; @@ -790,13 +795,12 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 256+strlen(sn)); + byte_stream_new(&bs, 246+strlen(sn)); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -814,14 +818,16 @@ 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, &outer_tlvlist); + byte_stream_destroy(&hdrbs); + + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -832,7 +838,7 @@ aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; @@ -842,13 +848,12 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 256+strlen(sn)); + byte_stream_new(&bs, 246+strlen(sn)); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -876,14 +881,16 @@ 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, &outer_tlvlist); + byte_stream_destroy(&hdrbs); + + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -894,7 +901,7 @@ aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; @@ -903,13 +910,12 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 1024); + byte_stream_new(&bs, 1014); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -952,20 +958,22 @@ byte_stream_put8(&bs, 0x00); aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data); - g_free(bs.data); + byte_stream_destroy(&bs); /* End TLV t(2711) */ } 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, &outer_tlvlist); + byte_stream_destroy(&hdrbs); + + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -976,7 +984,7 @@ aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; @@ -986,13 +994,12 @@ if (conn == NULL) return; - frame = flap_frame_new(od, 0x02, 1024); + byte_stream_new(&bs, 1014); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -1030,34 +1037,36 @@ if (filename != NULL) { - ByteStream bs; + ByteStream filename_bs; /* Begin TLV t(2711) */ - byte_stream_new(&bs, 2+2+4+strlen(filename)+1); - byte_stream_put16(&bs, (numfiles > 1) ? 0x0002 : 0x0001); - byte_stream_put16(&bs, numfiles); - byte_stream_put32(&bs, size); + byte_stream_new(&filename_bs, 2+2+4+strlen(filename)+1); + byte_stream_put16(&filename_bs, (numfiles > 1) ? 0x0002 : 0x0001); + byte_stream_put16(&filename_bs, numfiles); + byte_stream_put32(&filename_bs, size); /* Filename - NULL terminated, for some odd reason */ - byte_stream_putstr(&bs, filename); - byte_stream_put8(&bs, 0x00); - - aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data); - g_free(bs.data); + byte_stream_putstr(&filename_bs, filename); + byte_stream_put8(&filename_bs, 0x00); + + aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, filename_bs.len, filename_bs.data); + byte_stream_destroy(&filename_bs); /* End TLV t(2711) */ } 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, &outer_tlvlist); + byte_stream_destroy(&hdrbs); + + aim_tlvlist_write(&bs, &outer_tlvlist); aim_tlvlist_free(inner_tlvlist); aim_tlvlist_free(outer_tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /** @@ -1072,7 +1081,7 @@ int aim_im_sendch2_geticqaway(OscarData *od, const char *sn, int type) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; guchar cookie[8]; @@ -1081,79 +1090,80 @@ aim_icbm_makecookie(cookie); - frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4); + byte_stream_new(&bs, 8+2+1+strlen(sn) + 4+0x5e + 4); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, sn); /* TLV t(0005) - Encompasses almost everything below. */ - byte_stream_put16(&frame->data, 0x0005); /* T */ - byte_stream_put16(&frame->data, 0x005e); /* L */ + byte_stream_put16(&bs, 0x0005); /* T */ + byte_stream_put16(&bs, 0x005e); /* L */ { /* V */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); /* Cookie */ - byte_stream_putraw(&frame->data, cookie, 8); + byte_stream_putraw(&bs, cookie, 8); /* Put the 16 byte server relay capability */ - byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY); + byte_stream_putcaps(&bs, OSCAR_CAPABILITY_ICQSERVERRELAY); /* TLV t(000a) */ - byte_stream_put16(&frame->data, 0x000a); - byte_stream_put16(&frame->data, 0x0002); - byte_stream_put16(&frame->data, 0x0001); + byte_stream_put16(&bs, 0x000a); + byte_stream_put16(&bs, 0x0002); + byte_stream_put16(&bs, 0x0001); /* TLV t(000f) */ - byte_stream_put16(&frame->data, 0x000f); - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x000f); + byte_stream_put16(&bs, 0x0000); /* TLV t(2711) */ - byte_stream_put16(&frame->data, 0x2711); - byte_stream_put16(&frame->data, 0x0036); + byte_stream_put16(&bs, 0x2711); + byte_stream_put16(&bs, 0x0036); { /* V */ - byte_stream_putle16(&frame->data, 0x001b); /* L */ - byte_stream_putle16(&frame->data, 0x0009); /* Protocol version */ - byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY); - byte_stream_putle16(&frame->data, 0x0000); /* Unknown */ - byte_stream_putle16(&frame->data, 0x0001); /* Client features? */ - byte_stream_putle16(&frame->data, 0x0000); /* Unknown */ - byte_stream_putle8(&frame->data, 0x00); /* Unkizown */ - byte_stream_putle16(&frame->data, 0xffff); /* Sequence number? XXX - This should decrement by 1 with each request */ - - byte_stream_putle16(&frame->data, 0x000e); /* L */ - byte_stream_putle16(&frame->data, 0xffff); /* Sequence number? XXX - This should decrement by 1 with each request */ - byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */ - byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */ - byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */ + byte_stream_putle16(&bs, 0x001b); /* L */ + byte_stream_putle16(&bs, 0x0009); /* Protocol version */ + byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY); + byte_stream_putle16(&bs, 0x0000); /* Unknown */ + byte_stream_putle16(&bs, 0x0001); /* Client features? */ + byte_stream_putle16(&bs, 0x0000); /* Unknown */ + byte_stream_putle8(&bs, 0x00); /* Unkizown */ + byte_stream_putle16(&bs, 0xffff); /* Sequence number? XXX - This should decrement by 1 with each request */ + + byte_stream_putle16(&bs, 0x000e); /* L */ + byte_stream_putle16(&bs, 0xffff); /* Sequence number? XXX - This should decrement by 1 with each request */ + byte_stream_putle32(&bs, 0x00000000); /* Unknown */ + byte_stream_putle32(&bs, 0x00000000); /* Unknown */ + byte_stream_putle32(&bs, 0x00000000); /* Unknown */ /* The type of status message being requested */ if (type & AIM_ICQ_STATE_CHAT) - byte_stream_putle16(&frame->data, 0x03ec); + byte_stream_putle16(&bs, 0x03ec); else if(type & AIM_ICQ_STATE_DND) - byte_stream_putle16(&frame->data, 0x03eb); + byte_stream_putle16(&bs, 0x03eb); else if(type & AIM_ICQ_STATE_OUT) - byte_stream_putle16(&frame->data, 0x03ea); + byte_stream_putle16(&bs, 0x03ea); else if(type & AIM_ICQ_STATE_BUSY) - byte_stream_putle16(&frame->data, 0x03e9); + byte_stream_putle16(&bs, 0x03e9); else if(type & AIM_ICQ_STATE_AWAY) - byte_stream_putle16(&frame->data, 0x03e8); - - byte_stream_putle16(&frame->data, 0x0001); /* Status? */ - byte_stream_putle16(&frame->data, 0x0001); /* Priority of this message? */ - byte_stream_putle16(&frame->data, 0x0001); /* L */ - byte_stream_putle8(&frame->data, 0x00); /* String of length L */ + byte_stream_putle16(&bs, 0x03e8); + + byte_stream_putle16(&bs, 0x0001); /* Status? */ + byte_stream_putle16(&bs, 0x0001); /* Priority of this message? */ + byte_stream_putle16(&bs, 0x0001); /* L */ + byte_stream_putle8(&bs, 0x00); /* String of length L */ } /* End TLV t(2711) */ } /* End TLV t(0005) */ /* TLV t(0003) */ - byte_stream_put16(&frame->data, 0x0003); - byte_stream_put16(&frame->data, 0x0000); - - flap_connection_send(conn, frame); - + byte_stream_put16(&bs, 0x0003); + byte_stream_put16(&bs, 0x0000); + + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -1174,7 +1184,7 @@ int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; guchar cookie[8]; @@ -1184,44 +1194,45 @@ if (!sn || !type || !message) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+8+3+strlen(sn)+12+strlen(message)+1+4); + byte_stream_new(&bs, 8+3+strlen(sn)+12+strlen(message)+1+4); snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); aim_icbm_makecookie(cookie); /* ICBM header */ - aim_im_puticbm(&frame->data, cookie, 0x0004, sn); + aim_im_puticbm(&bs, cookie, 0x0004, sn); /* * TLV t(0005) * * ICQ data (the UIN and the message). */ - byte_stream_put16(&frame->data, 0x0005); - byte_stream_put16(&frame->data, 4 + 2+2+strlen(message)+1); + byte_stream_put16(&bs, 0x0005); + byte_stream_put16(&bs, 4 + 2+2+strlen(message)+1); /* * Your UIN */ - byte_stream_putle32(&frame->data, atoi(od->sn)); + byte_stream_putle32(&bs, atoi(od->sn)); /* * TLV t(type) l(strlen(message)+1) v(message+NULL) */ - byte_stream_putle16(&frame->data, type); - byte_stream_putle16(&frame->data, strlen(message)+1); - byte_stream_putraw(&frame->data, (const guint8 *)message, strlen(message)+1); + byte_stream_putle16(&bs, type); + byte_stream_putle16(&bs, strlen(message)+1); + byte_stream_putraw(&bs, (const guint8 *)message, strlen(message)+1); /* * TLV t(0006) l(0000) v() */ - byte_stream_put16(&frame->data, 0x0006); - byte_stream_put16(&frame->data, 0x0000); - - flap_connection_send(conn, frame); - + byte_stream_put16(&bs, 0x0006); + byte_stream_put16(&bs, 0x0000); + + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } @@ -2249,22 +2260,23 @@ */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *sn, guint32 flags) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !conn || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, strlen(sn)+13); + byte_stream_new(&bs, strlen(sn)+3); snacid = aim_cachesnac(od, 0x0004, 0x0008, 0x0000, sn, strlen(sn)+1); - aim_putsnac(&frame->data, 0x0004, 0x0008, 0x0000, snacid); - - byte_stream_put16(&frame->data, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000); - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); - - flap_connection_send(conn, frame); + + byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); + + flap_connection_send_snac(od, conn, 0x0004, 0x0008, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -2305,29 +2317,30 @@ int aim_im_denytransfer(OscarData *od, const char *sn, const guchar *cookie, guint16 code) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn)+6); + byte_stream_new(&bs, 8+2+1+strlen(sn)+6); snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x000b, 0x0000, snacid); - - byte_stream_putraw(&frame->data, cookie, 8); - - byte_stream_put16(&frame->data, 0x0002); /* channel */ - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + + byte_stream_putraw(&bs, cookie, 8); + + byte_stream_put16(&bs, 0x0002); /* channel */ + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); aim_tlvlist_add_16(&tlvlist, 0x0003, code); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -2662,7 +2675,7 @@ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *sn, guint16 type2) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, 0x0002))) @@ -2671,38 +2684,39 @@ if (!sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+11+strlen(sn)+2); + byte_stream_new(&bs, 11+strlen(sn)+2); snacid = aim_cachesnac(od, 0x0004, 0x0014, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0014, 0x0000, snacid); /* * 8 days of light * Er, that is to say, 8 bytes of 0's */ - byte_stream_put16(&frame->data, 0x0000); - byte_stream_put16(&frame->data, 0x0000); - byte_stream_put16(&frame->data, 0x0000); - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0000); + byte_stream_put16(&bs, 0x0000); + byte_stream_put16(&bs, 0x0000); + byte_stream_put16(&bs, 0x0000); /* * Type 1 (should be 0x0001 for mtn) */ - byte_stream_put16(&frame->data, type1); + byte_stream_put16(&bs, type1); /* * Dest sn */ - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); /* * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn) */ - byte_stream_put16(&frame->data, type2); - - flap_connection_send(conn, frame); - + byte_stream_put16(&bs, type2); + + flap_connection_send_snac(od, conn, 0x0004, 0x0014, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/family_icq.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_icq.c Mon Apr 28 06:27:11 2008 +0000 @@ -29,7 +29,7 @@ int aim_icq_reqofflinemsgs(OscarData *od) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; @@ -38,28 +38,29 @@ bslen = 2 + 4 + 2 + 2; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x003c); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x003c); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } int aim_icq_ackofflinemsgs(OscarData *od) { - FlapConnection *conn; + ByteStream bs; FlapFrame *frame; aim_snacid_t snacid; int bslen; @@ -69,21 +70,22 @@ bslen = 2 + 4 + 2 + 2; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x003e); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x003e); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -93,7 +95,7 @@ aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; @@ -102,30 +104,31 @@ bslen = 2+4+2+2+2+2+2+1+1+1+1+1+1; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x0c3a); /* shrug. */ - byte_stream_putle16(&frame->data, 0x030c); - byte_stream_putle16(&frame->data, 0x0001); - byte_stream_putle8(&frame->data, webaware); - byte_stream_putle8(&frame->data, 0xf8); - byte_stream_putle8(&frame->data, 0x02); - byte_stream_putle8(&frame->data, 0x01); - byte_stream_putle8(&frame->data, 0x00); - byte_stream_putle8(&frame->data, !auth_required); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x0c3a); /* shrug. */ + byte_stream_putle16(&bs, 0x030c); + byte_stream_putle16(&bs, 0x0001); + byte_stream_putle8(&bs, webaware); + byte_stream_putle8(&bs, 0xf8); + byte_stream_putle8(&bs, 0x02); + byte_stream_putle8(&bs, 0x01); + byte_stream_putle8(&bs, 0x00); + byte_stream_putle8(&bs, !auth_required); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -141,7 +144,7 @@ int aim_icq_changepasswd(OscarData *od, const char *passwd) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen, passwdlen; @@ -156,25 +159,26 @@ passwdlen = MAXICQPASSLEN; bslen = 2+4+2+2+2+2+passwdlen+1; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x042e); /* shrug. */ - byte_stream_putle16(&frame->data, passwdlen+1); - byte_stream_putstr(&frame->data, passwd); - byte_stream_putle8(&frame->data, '\0'); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x042e); /* shrug. */ + byte_stream_putle16(&bs, passwdlen+1); + byte_stream_putstr(&bs, passwd); + byte_stream_putle8(&bs, '\0'); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -182,7 +186,7 @@ int aim_icq_getallinfo(OscarData *od, const char *uin) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; struct aim_icq_info *info; @@ -195,23 +199,24 @@ bslen = 2 + 4 + 2 + 2 + 2 + 4; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x04b2); /* shrug. */ - byte_stream_putle32(&frame->data, atoi(uin)); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x04b2); /* shrug. */ + byte_stream_putle32(&bs, atoi(uin)); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); /* Keep track of this request and the ICQ number and request ID */ info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1); @@ -226,7 +231,7 @@ int aim_icq_getalias(OscarData *od, const char *uin) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; struct aim_icq_info *info; @@ -239,24 +244,25 @@ bslen = 2 + 4 + 2 + 2 + 2 + 4; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x04ba); /* shrug. */ - byte_stream_putle32(&frame->data, atoi(uin)); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x04ba); /* shrug. */ + byte_stream_putle32(&bs, atoi(uin)); - flap_connection_send(conn, frame); - + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + /* Keep track of this request and the ICQ number and request ID */ info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1); info->reqid = snacid; @@ -270,7 +276,7 @@ int aim_icq_getsimpleinfo(OscarData *od, const char *uin) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; @@ -282,23 +288,24 @@ bslen = 2 + 4 + 2 + 2 + 2 + 4; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x051f); /* shrug. */ - byte_stream_putle32(&frame->data, atoi(uin)); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x051f); /* shrug. */ + byte_stream_putle32(&bs, atoi(uin)); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -307,7 +314,7 @@ int aim_icq_sendxmlreq(OscarData *od, const char *xml) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; @@ -319,25 +326,26 @@ bslen = 2 + 10 + 2 + strlen(xml) + 1; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x0998); /* shrug. */ - byte_stream_putle16(&frame->data, strlen(xml) + 1); - byte_stream_putraw(&frame->data, (guint8 *)xml, strlen(xml) + 1); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x0998); /* shrug. */ + byte_stream_putle16(&bs, strlen(xml) + 1); + byte_stream_putraw(&bs, (guint8 *)xml, strlen(xml) + 1); - flap_connection_send(conn, frame); - + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; } #endif @@ -363,7 +371,7 @@ int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen, xmllen; char *xml; @@ -401,35 +409,36 @@ bslen = 36 + xmllen; - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ /* From libicq200-0.3.2/src/SNAC-SRV.cpp */ - byte_stream_putle16(&frame->data, 0x1482); - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, 0x0016); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000000); + byte_stream_putle16(&bs, 0x1482); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, 0x0016); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000000); - byte_stream_put16(&frame->data, 0x0000); - byte_stream_put16(&frame->data, xmllen); - byte_stream_putstr(&frame->data, xml); - byte_stream_put8(&frame->data, 0x00); + byte_stream_put16(&bs, 0x0000); + byte_stream_put16(&bs, xmllen); + byte_stream_putstr(&bs, xml); + byte_stream_put8(&bs, 0x00); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); g_free(xml); g_free(stripped); @@ -445,7 +454,7 @@ int aim_icq_getstatusnote(OscarData *od, const char *uin, guint8 *note_hash, guint16 note_hash_len) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; int bslen; @@ -458,40 +467,39 @@ } bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin); - - frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + byte_stream_new(&bs, 4 + bslen); snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); - /* For simplicity, don't bother using a tlvlist */ - byte_stream_put16(&frame->data, 0x0001); - byte_stream_put16(&frame->data, bslen); + byte_stream_put16(&bs, 0x0001); + byte_stream_put16(&bs, bslen); - byte_stream_putle16(&frame->data, bslen - 2); - byte_stream_putle32(&frame->data, atoi(od->sn)); - byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ - byte_stream_putle16(&frame->data, snacid); /* eh. */ - byte_stream_putle16(&frame->data, 0x0fa0); /* shrug. */ - byte_stream_putle16(&frame->data, 58 + strlen(uin)); + byte_stream_putle16(&bs, bslen - 2); + byte_stream_putle32(&bs, atoi(od->sn)); + byte_stream_putle16(&bs, 0x07d0); /* I command thee. */ + byte_stream_putle16(&bs, snacid); /* eh. */ + byte_stream_putle16(&bs, 0x0fa0); /* shrug. */ + byte_stream_putle16(&bs, 58 + strlen(uin)); - byte_stream_put32(&frame->data, 0x05b90002); /* don't ask */ - byte_stream_put32(&frame->data, 0x80000000); - byte_stream_put32(&frame->data, 0x00000006); - byte_stream_put32(&frame->data, 0x00010002); - byte_stream_put32(&frame->data, 0x00020000); - byte_stream_put32(&frame->data, 0x04e30000); - byte_stream_put32(&frame->data, 0x00020002); - byte_stream_put32(&frame->data, 0x00000001); + byte_stream_put32(&bs, 0x05b90002); /* don't ask */ + byte_stream_put32(&bs, 0x80000000); + byte_stream_put32(&bs, 0x00000006); + byte_stream_put32(&bs, 0x00010002); + byte_stream_put32(&bs, 0x00020000); + byte_stream_put32(&bs, 0x04e30000); + byte_stream_put32(&bs, 0x00020002); + byte_stream_put32(&bs, 0x00000001); - byte_stream_put16(&frame->data, 24 + strlen(uin)); - byte_stream_put32(&frame->data, 0x003c0010); - byte_stream_putraw(&frame->data, note_hash, 16); /* status note hash */ - byte_stream_put16(&frame->data, 0x0032); /* buddy uin */ - byte_stream_put16(&frame->data, strlen(uin)); - byte_stream_putstr(&frame->data, uin); + byte_stream_put16(&bs, 24 + strlen(uin)); + byte_stream_put32(&bs, 0x003c0010); + byte_stream_putraw(&bs, note_hash, 16); /* status note hash */ + byte_stream_put16(&bs, 0x0032); /* buddy uin */ + byte_stream_put16(&bs, strlen(uin)); + byte_stream_putstr(&bs, uin); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0015, 0x0002, 0x000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -768,8 +776,8 @@ else { struct aim_icq_info *info; - guint32 data_len; - FlapFrame *frame; + ByteStream bs; + guint32 bslen; aim_snacid_t snacid; guchar cookie[8]; @@ -783,84 +791,83 @@ break; } - data_len = 13 + strlen(uin) + 30 + 6 + 4 + 55 + 85 + 4; - frame = flap_frame_new(od, 0x0002, 10 + 4 + data_len); + bslen = 13 + strlen(uin) + 30 + 6 + 4 + 55 + 85 + 4; + byte_stream_new(&bs, 4 + bslen); + snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); - aim_icbm_makecookie(cookie); - byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */ - byte_stream_put16(&frame->data, 0x0002); /* message channel */ - byte_stream_put8(&frame->data, strlen(uin)); /* uin */ - byte_stream_putstr(&frame->data, uin); + byte_stream_putraw(&bs, cookie, 8); /* ICBM cookie */ + byte_stream_put16(&bs, 0x0002); /* message channel */ + byte_stream_put8(&bs, strlen(uin)); /* uin */ + byte_stream_putstr(&bs, uin); - byte_stream_put16(&frame->data, 0x0005); /* rendez vous data */ - byte_stream_put16(&frame->data, 0x00b2); - byte_stream_put16(&frame->data, 0x0000); /* request */ - byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */ - byte_stream_put32(&frame->data, 0x09461349); /* ICQ server relaying */ - byte_stream_put16(&frame->data, 0x4c7f); - byte_stream_put16(&frame->data, 0x11d1); - byte_stream_put32(&frame->data, 0x82224445); - byte_stream_put32(&frame->data, 0x53540000); + byte_stream_put16(&bs, 0x0005); /* rendez vous data */ + byte_stream_put16(&bs, 0x00b2); + byte_stream_put16(&bs, 0x0000); /* request */ + byte_stream_putraw(&bs, cookie, 8); /* ICBM cookie */ + byte_stream_put32(&bs, 0x09461349); /* ICQ server relaying */ + byte_stream_put16(&bs, 0x4c7f); + byte_stream_put16(&bs, 0x11d1); + byte_stream_put32(&bs, 0x82224445); + byte_stream_put32(&bs, 0x53540000); - byte_stream_put16(&frame->data, 0x000a); /* unknown TLV */ - byte_stream_put16(&frame->data, 0x0002); - byte_stream_put16(&frame->data, 0x0001); + byte_stream_put16(&bs, 0x000a); /* unknown TLV */ + byte_stream_put16(&bs, 0x0002); + byte_stream_put16(&bs, 0x0001); - byte_stream_put16(&frame->data, 0x000f); /* unknown TLV */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x000f); /* unknown TLV */ + byte_stream_put16(&bs, 0x0000); - byte_stream_put16(&frame->data, 0x2711); /* extended data */ - byte_stream_put16(&frame->data, 0x008a); - byte_stream_putle16(&frame->data, 0x001b); /* length */ - byte_stream_putle16(&frame->data, 0x0009); /* version */ - byte_stream_putle32(&frame->data, 0x00000000); /* plugin: none */ - byte_stream_putle32(&frame->data, 0x00000000); - byte_stream_putle32(&frame->data, 0x00000000); - byte_stream_putle32(&frame->data, 0x00000000); - byte_stream_putle16(&frame->data, 0x0000); /* unknown */ - byte_stream_putle32(&frame->data, 0x00000000); /* client capabilities flags */ - byte_stream_put8(&frame->data, 0x00); /* unknown */ - byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */ - byte_stream_putle16(&frame->data, 0x000e); /* length */ - byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */ - byte_stream_putle32(&frame->data, 0x00000000); /* unknown */ - byte_stream_putle32(&frame->data, 0x00000000); - byte_stream_putle32(&frame->data, 0x00000000); - byte_stream_put8(&frame->data, 0x1a); /* message type: plugin message descibed by text string */ - byte_stream_put8(&frame->data, 0x00); /* message flags */ - byte_stream_putle16(&frame->data, 0x0000); /* status code */ - byte_stream_putle16(&frame->data, 0x0001); /* priority code */ - byte_stream_putle16(&frame->data, 0x0000); /* text length */ + byte_stream_put16(&bs, 0x2711); /* extended data */ + byte_stream_put16(&bs, 0x008a); + byte_stream_putle16(&bs, 0x001b); /* length */ + byte_stream_putle16(&bs, 0x0009); /* version */ + byte_stream_putle32(&bs, 0x00000000); /* plugin: none */ + byte_stream_putle32(&bs, 0x00000000); + byte_stream_putle32(&bs, 0x00000000); + byte_stream_putle32(&bs, 0x00000000); + byte_stream_putle16(&bs, 0x0000); /* unknown */ + byte_stream_putle32(&bs, 0x00000000); /* client capabilities flags */ + byte_stream_put8(&bs, 0x00); /* unknown */ + byte_stream_putle16(&bs, 0x0064); /* downcounter? */ + byte_stream_putle16(&bs, 0x000e); /* length */ + byte_stream_putle16(&bs, 0x0064); /* downcounter? */ + byte_stream_putle32(&bs, 0x00000000); /* unknown */ + byte_stream_putle32(&bs, 0x00000000); + byte_stream_putle32(&bs, 0x00000000); + byte_stream_put8(&bs, 0x1a); /* message type: plugin message descibed by text string */ + byte_stream_put8(&bs, 0x00); /* message flags */ + byte_stream_putle16(&bs, 0x0000); /* status code */ + byte_stream_putle16(&bs, 0x0001); /* priority code */ + byte_stream_putle16(&bs, 0x0000); /* text length */ - byte_stream_put8(&frame->data, 0x3a); /* message dump */ - byte_stream_put32(&frame->data, 0x00811a18); - byte_stream_put32(&frame->data, 0xbc0e6c18); - byte_stream_put32(&frame->data, 0x47a5916f); - byte_stream_put32(&frame->data, 0x18dcc76f); - byte_stream_put32(&frame->data, 0x1a010013); - byte_stream_put32(&frame->data, 0x00000041); - byte_stream_put32(&frame->data, 0x77617920); - byte_stream_put32(&frame->data, 0x53746174); - byte_stream_put32(&frame->data, 0x7573204d); - byte_stream_put32(&frame->data, 0x65737361); - byte_stream_put32(&frame->data, 0x67650100); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x00000015); - byte_stream_put32(&frame->data, 0x00000000); - byte_stream_put32(&frame->data, 0x0000000d); - byte_stream_put32(&frame->data, 0x00000074); - byte_stream_put32(&frame->data, 0x6578742f); - byte_stream_put32(&frame->data, 0x782d616f); - byte_stream_put32(&frame->data, 0x6c727466); + byte_stream_put8(&bs, 0x3a); /* message dump */ + byte_stream_put32(&bs, 0x00811a18); + byte_stream_put32(&bs, 0xbc0e6c18); + byte_stream_put32(&bs, 0x47a5916f); + byte_stream_put32(&bs, 0x18dcc76f); + byte_stream_put32(&bs, 0x1a010013); + byte_stream_put32(&bs, 0x00000041); + byte_stream_put32(&bs, 0x77617920); + byte_stream_put32(&bs, 0x53746174); + byte_stream_put32(&bs, 0x7573204d); + byte_stream_put32(&bs, 0x65737361); + byte_stream_put32(&bs, 0x67650100); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x00000015); + byte_stream_put32(&bs, 0x00000000); + byte_stream_put32(&bs, 0x0000000d); + byte_stream_put32(&bs, 0x00000074); + byte_stream_put32(&bs, 0x6578742f); + byte_stream_put32(&bs, 0x782d616f); + byte_stream_put32(&bs, 0x6c727466); - byte_stream_put16(&frame->data, 0x0003); /* server ACK requested */ - byte_stream_put16(&frame->data, 0x0000); + byte_stream_put16(&bs, 0x0003); /* server ACK requested */ + byte_stream_put16(&bs, 0x0000); info->uin = atoi(uin); info->status_note_title = status_note_title; @@ -870,7 +877,9 @@ info->next = od->icq_info; od->icq_info = info; - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } g_free(uin);
--- a/libpurple/protocols/oscar/family_locate.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Mon Apr 28 06:27:11 2008 +0000 @@ -1047,7 +1047,7 @@ const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; char *encoding; @@ -1092,15 +1092,16 @@ aim_tlvlist_add_noval(&tlvlist, 0x0004); } - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); + byte_stream_new(&bs, 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, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1112,7 +1113,7 @@ aim_locate_setcaps(OscarData *od, guint32 caps) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -1121,15 +1122,16 @@ aim_tlvlist_add_caps(&tlvlist, 0x0005, caps); - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); + byte_stream_new(&bs, 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, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0002, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1147,22 +1149,23 @@ aim_locate_getinfo(OscarData *od, const char *sn, guint16 infotype) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 12+1+strlen(sn)); + byte_stream_new(&bs, 2+1+strlen(sn)); snacid = aim_cachesnac(od, 0x0002, 0x0005, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0002, 0x0005, 0x0000, snacid); - byte_stream_put16(&frame->data, infotype); - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put16(&bs, infotype); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0002, 0x0005, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1238,7 +1241,7 @@ int aim_locate_setdirinfo(OscarData *od, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -1269,15 +1272,16 @@ if (street) aim_tlvlist_add_str(&tlvlist, 0x0021, street); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); + byte_stream_new(&bs, 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, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0002, 0x0009, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1288,7 +1292,7 @@ int aim_locate_000b(OscarData *od, const char *sn) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; return -EINVAL; @@ -1296,15 +1300,16 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+1+strlen(sn)); + byte_stream_new(&bs, 1+strlen(sn)); snacid = aim_cachesnac(od, 0x0002, 0x000b, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0002, 0x000b, 0x0000, snacid); - byte_stream_put8(&frame->data, strlen(sn)); - byte_stream_putstr(&frame->data, sn); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, 0x0002, 0x000b, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1319,7 +1324,7 @@ aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -1340,16 +1345,16 @@ if (interest5) aim_tlvlist_add_str(&tlvlist, 0x0000b, interest5); - frame = flap_frame_new(od, 0x02, 10+aim_tlvlist_size(tlvlist)); + byte_stream_new(&bs, 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, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); - + flap_connection_send_snac(od, conn, 0x0002, 0x000f, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -1369,21 +1374,21 @@ aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags) { FlapConnection *conn; - ByteStream data; + ByteStream bs; aim_snacid_t snacid; if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) return -EINVAL; - byte_stream_new(&data, 4 + 1 + strlen(sn)); - byte_stream_put32(&data, flags); - byte_stream_put8(&data, strlen(sn)); - byte_stream_putstr(&data, sn); + byte_stream_new(&bs, 4 + 1 + strlen(sn)); + byte_stream_put32(&bs, flags); + byte_stream_put8(&bs, strlen(sn)); + byte_stream_putstr(&bs, sn); snacid = aim_cachesnac(od, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1); - flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &data); + flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &bs); - g_free(data.data); + byte_stream_destroy(&bs); return 0; }
--- a/libpurple/protocols/oscar/family_odir.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_odir.c Mon Apr 28 06:27:11 2008 +0000 @@ -41,7 +41,7 @@ int aim_odir_email(OscarData *od, const char *region, const char *email) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -53,14 +53,15 @@ 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(tlvlist)); - snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x000f, 0x0002, 0x0000, snacid); + byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); return 0; } @@ -89,7 +90,7 @@ int aim_odir_name(OscarData *od, const char *region, const char *first, const char *middle, const char *last, const char *maiden, const char *nick, const char *city, const char *state, const char *country, const char *zip, const char *address) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -120,15 +121,16 @@ if (address) aim_tlvlist_add_str(&tlvlist, 0x0021, address); - 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); + byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); + return 0; } @@ -143,7 +145,7 @@ int aim_odir_interest(OscarData *od, const char *region, const char *interest) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -156,15 +158,16 @@ if (interest) aim_tlvlist_add_str(&tlvlist, 0x0001, interest); - 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); + byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); - + snacid = aim_cachesnac(od, 0x000f, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x000f, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/family_oservice.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_oservice.c Mon Apr 28 06:27:11 2008 +0000 @@ -31,14 +31,11 @@ void aim_clientready(OscarData *od, FlapConnection *conn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *cur; - frame = flap_frame_new(od, 0x02, 1152); - - snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x0002, 0x0000, snacid); + byte_stream_new(&bs, 1142); /* * Send only the tool versions that the server cares about (that it @@ -50,14 +47,17 @@ if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data)))) { - byte_stream_put16(&frame->data, mod->family); - byte_stream_put16(&frame->data, mod->version); - byte_stream_put16(&frame->data, mod->toolid); - byte_stream_put16(&frame->data, mod->toolversion); + byte_stream_put16(&bs, mod->family); + byte_stream_put16(&bs, mod->version); + byte_stream_put16(&bs, mod->toolid); + byte_stream_put16(&bs, mod->toolversion); } } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x0002, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* @@ -121,7 +121,7 @@ aim_chat_join(OscarData *od, guint16 exchange, const char *roomname, guint16 instance) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; struct chatsnacinfo csi; @@ -130,27 +130,27 @@ if (!conn || !roomname || !strlen(roomname)) return -EINVAL; - frame = flap_frame_new(od, 0x02, 512); + byte_stream_new(&bs, 502); memset(&csi, 0, sizeof(csi)); csi.exchange = exchange; strncpy(csi.name, roomname, sizeof(csi.name)); csi.instance = instance; - snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi)); - aim_putsnac(&frame->data, 0x0001, 0x0004, 0x0000, snacid); - /* * Requesting service chat (0x000e) */ - byte_stream_put16(&frame->data, 0x000e); + byte_stream_put16(&bs, 0x000e); aim_tlvlist_add_chatroom(&tlvlist, 0x0001, exchange, roomname, instance); - aim_tlvlist_write(&frame->data, &tlvlist); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi)); + flap_connection_send_snac(od, conn, 0x0001, 0x0004, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); + return 0; } @@ -376,46 +376,46 @@ void aim_srv_rates_addparam(OscarData *od, FlapConnection *conn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tmp; - frame = flap_frame_new(od, 0x02, 512); - - snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x0008, 0x0000, snacid); + byte_stream_new(&bs, 502); for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next) { struct rateclass *rateclass; rateclass = tmp->data; - byte_stream_put16(&frame->data, rateclass->classid); + byte_stream_put16(&bs, rateclass->classid); } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x0008, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* Subtype 0x0009 - Delete Rate Parameter */ void aim_srv_rates_delparam(OscarData *od, FlapConnection *conn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tmp; - frame = flap_frame_new(od, 0x02, 512); - - snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x0009, 0x0000, snacid); + byte_stream_new(&bs, 502); for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next) { struct rateclass *rateclass; rateclass = tmp->data; - byte_stream_put16(&frame->data, rateclass->classid); + byte_stream_put16(&bs, rateclass->classid); } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x0009, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* Subtype 0x000a - Rate Change */ @@ -489,14 +489,11 @@ void aim_srv_sendpauseack(OscarData *od, FlapConnection *conn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *cur; - frame = flap_frame_new(od, 0x02, 1024); - - snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x000c, 0x0000, snacid); + byte_stream_new(&bs, 1014); /* * This list should have all the groups that the original @@ -504,9 +501,12 @@ * we want them all back after the migration. */ for (cur = conn->groups; cur != NULL; cur = cur->next) - byte_stream_put16(&frame->data, GPOINTER_TO_UINT(cur->data)); + byte_stream_put16(&bs, GPOINTER_TO_UINT(cur->data)); - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x000c, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* Subtype 0x000d - Service Resume */ @@ -732,14 +732,11 @@ void aim_srv_setversions(OscarData *od, FlapConnection *conn) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *cur; - frame = flap_frame_new(od, 0x02, 1152); - - snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x0017, 0x0000, snacid); + byte_stream_new(&bs, 1142); /* * Send only the versions that the server cares about (that it @@ -751,12 +748,15 @@ if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data)))) { - byte_stream_put16(&frame->data, mod->family); - byte_stream_put16(&frame->data, mod->version); + byte_stream_put16(&bs, mod->family); + byte_stream_put16(&bs, mod->version); } } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x0017, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* Subtype 0x0018 - Host versions */ @@ -803,7 +803,7 @@ gboolean setavailmsg, const char *availmsg, const char *itmsurl) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; GSList *tlvlist = NULL; @@ -853,19 +853,19 @@ aim_tlvlist_add_raw(&tlvlist, 0x001d, byte_stream_curpos(&tmpbs), tmpbs.data); - g_free(tmpbs.data); + byte_stream_destroy(&tmpbs); } - frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist)); + byte_stream_new(&bs, aim_tlvlist_size(tlvlist)); + + aim_tlvlist_write(&bs, &tlvlist); + aim_tlvlist_free(tlvlist); snacid = aim_cachesnac(od, 0x0001, 0x001e, 0x0000, NULL, 0); - aim_putsnac(&frame->data, 0x0001, 0x001e, 0x0000, snacid); + flap_connection_send_snac(od, conn, 0x0001, 0x001e, 0x0000, snacid, &bs); - aim_tlvlist_write(&frame->data, &tlvlist); - aim_tlvlist_free(tlvlist); - - flap_connection_send(conn, frame); - + byte_stream_destroy(&bs); + return 0; } @@ -937,22 +937,19 @@ int aim_sendmemblock(OscarData *od, FlapConnection *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!od || !conn) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+2+16); + byte_stream_new(&bs, 2+16); - snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0); - - aim_putsnac(&frame->data, 0x0001, 0x0020, 0x0000, snacid); - byte_stream_put16(&frame->data, 0x0010); /* md5 is always 16 bytes */ + byte_stream_put16(&bs, 0x0010); /* md5 is always 16 bytes */ if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */ - byte_stream_putraw(&frame->data, buf, 0x10); + byte_stream_putraw(&bs, buf, 0x10); } else if (buf && (len > 0)) { /* use input buffer */ PurpleCipher *cipher; @@ -966,7 +963,7 @@ purple_cipher_context_digest(context, 16, digest, NULL); purple_cipher_context_destroy(context); - byte_stream_putraw(&frame->data, digest, 0x10); + byte_stream_putraw(&bs, digest, 0x10); } else if (len == 0) { /* no length, just hash NULL (buf is optional) */ PurpleCipher *cipher; @@ -985,7 +982,7 @@ purple_cipher_context_digest(context, 16, digest, NULL); purple_cipher_context_destroy(context); - byte_stream_putraw(&frame->data, digest, 0x10); + byte_stream_putraw(&bs, digest, 0x10); } else { @@ -999,15 +996,15 @@ if ((offset == 0x03ffffff) && (len == 0x03ffffff)) { #if 1 /* with "AnrbnrAqhfzcd" */ - byte_stream_put32(&frame->data, 0x44a95d26); - byte_stream_put32(&frame->data, 0xd2490423); - byte_stream_put32(&frame->data, 0x93b8821f); - byte_stream_put32(&frame->data, 0x51c54b01); + byte_stream_put32(&bs, 0x44a95d26); + byte_stream_put32(&bs, 0xd2490423); + byte_stream_put32(&bs, 0x93b8821f); + byte_stream_put32(&bs, 0x51c54b01); #else /* no filename */ - byte_stream_put32(&frame->data, 0x1df8cbae); - byte_stream_put32(&frame->data, 0x5523b839); - byte_stream_put32(&frame->data, 0xa0e10db3); - byte_stream_put32(&frame->data, 0xa46d3b39); + byte_stream_put32(&bs, 0x1df8cbae); + byte_stream_put32(&bs, 0x5523b839); + byte_stream_put32(&bs, 0xa0e10db3); + byte_stream_put32(&bs, 0xa46d3b39); #endif } else @@ -1015,8 +1012,11 @@ } - flap_connection_send(conn, frame); + snacid = aim_cachesnac(od, 0x0001, 0x0020, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, 0x0001, 0x0020, 0x0000, snacid, &bs); + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/family_userlookup.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/family_userlookup.c Mon Apr 28 06:27:11 2008 +0000 @@ -62,7 +62,7 @@ int aim_search_address(OscarData *od, const char *address) { FlapConnection *conn; - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; conn = flap_connection_findbygroup(od, SNAC_FAMILY_USERLOOKUP); @@ -70,15 +70,15 @@ if (!conn || !address) return -EINVAL; - frame = flap_frame_new(od, 0x02, 10+strlen(address)); + byte_stream_new(&bs, strlen(address)); + + byte_stream_putstr(&bs, address); snacid = aim_cachesnac(od, 0x000a, 0x0002, 0x0000, address, strlen(address)+1); - aim_putsnac(&frame->data, 0x000a, 0x0002, 0x0000, snacid); + flap_connection_send_snac(od, conn, 0x000a, 0x0002, 0x0000, snacid, &bs); - byte_stream_putstr(&frame->data, address); - - flap_connection_send(conn, frame); - + byte_stream_destroy(&bs); + return 0; }
--- a/libpurple/protocols/oscar/flap_connection.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Mon Apr 28 06:27:11 2008 +0000 @@ -115,6 +115,7 @@ conn = data; gettimeofday(&now, NULL); + purple_debug_info("oscar", "Attempting to send %i queued SNACs for %p\n", g_queue_get_length(conn->queued_snacs), conn); while (!g_queue_is_empty(conn->queued_snacs)) { QueuedSnac *queued_snac; @@ -189,6 +190,8 @@ /* (Add 100ms padding to account for inaccuracies in the calculation) */ if (new_current < rateclass->alert + 100) { + purple_debug_info("oscar", "Current rate for conn %p would be %u, but we alert at %u; enqueueing\n", conn, new_current, (rateclass->alert + 100)); + enqueue = TRUE; } else @@ -197,6 +200,8 @@ rateclass->last.tv_sec = now.tv_sec; rateclass->last.tv_usec = now.tv_usec; } + } else { + purple_debug_warning("oscar", "No rate class found for family %u subtype %u\n", family, subtype); } if (enqueue) @@ -983,7 +988,7 @@ byte_stream_rewind(&bs); flap_connection_send_byte_stream(&bs, conn, bslen); - g_free(bs.data); /* XXX byte_stream_free */ + byte_stream_destroy(&bs); } void
--- a/libpurple/protocols/oscar/misc.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/misc.c Mon Apr 28 06:27:11 2008 +0000 @@ -42,11 +42,7 @@ FlapFrame *frame; aim_snacid_t snacid = 0x00000000; - frame = flap_frame_new(od, 0x02, 10); - - aim_putsnac(&frame->data, family, subtype, 0x0000, snacid); - - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL); } void @@ -55,18 +51,15 @@ FlapFrame *frame; aim_snacid_t snacid; - frame = flap_frame_new(od, 0x02, 10); + snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0); - snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0); - aim_putsnac(&frame->data, family, subtype, 0x0000, snacid); - - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL); } void aim_genericreq_l(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint32 *longdata) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!longdata) @@ -75,20 +68,21 @@ return; } - frame = flap_frame_new(od, 0x02, 10+4); + byte_stream_new(&bs, 4); snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0); - aim_putsnac(&frame->data, family, subtype, 0x0000, snacid); - byte_stream_put32(&frame->data, *longdata); + byte_stream_put32(&bs, *longdata); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL); + + byte_stream_destroy(&bs); } void aim_genericreq_s(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint16 *shortdata) { - FlapFrame *frame; + ByteStream bs; aim_snacid_t snacid; if (!shortdata) @@ -97,14 +91,15 @@ return; } - frame = flap_frame_new(od, 0x02, 10+2); + byte_stream_new(&bs, 2); snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0); - aim_putsnac(&frame->data, family, subtype, 0x0000, snacid); - byte_stream_put16(&frame->data, *shortdata); + byte_stream_put16(&bs, *shortdata); - flap_connection_send(conn, frame); + flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL); + + byte_stream_destroy(&bs); } /*
--- a/libpurple/protocols/oscar/odc.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/odc.c Mon Apr 28 06:27:11 2008 +0000 @@ -121,7 +121,7 @@ peer_connection_send(conn, &bs); - g_free(bs.data); + byte_stream_destroy(&bs); } /**
--- a/libpurple/protocols/oscar/oft.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/oft.c Mon Apr 28 06:27:11 2008 +0000 @@ -304,7 +304,7 @@ peer_connection_send(conn, &bs); - g_free(bs.data); + byte_stream_destroy(&bs); } void
--- a/libpurple/protocols/oscar/oscar.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.h Mon Apr 28 06:27:11 2008 +0000 @@ -1549,6 +1549,7 @@ /* bstream.c */ int byte_stream_new(ByteStream *bs, guint32 len); int byte_stream_init(ByteStream *bs, guint8 *data, int len); +void byte_stream_destroy(ByteStream *bs); int byte_stream_empty(ByteStream *bs); int byte_stream_curpos(ByteStream *bs); int byte_stream_setpos(ByteStream *bs, unsigned int off);
--- a/libpurple/protocols/oscar/peer_proxy.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/peer_proxy.c Mon Apr 28 06:27:11 2008 +0000 @@ -48,7 +48,7 @@ peer_connection_send(conn, &bs); - g_free(bs.data); + byte_stream_destroy(&bs); } /**
--- a/libpurple/protocols/oscar/tlv.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/oscar/tlv.c Mon Apr 28 06:27:11 2008 +0000 @@ -231,13 +231,13 @@ aim_tlvlist_write(&bs2, &two); if (memcmp(bs1.data, bs2.data, bs1.len)) { - g_free(bs1.data); - g_free(bs2.data); + byte_stream_destroy(&bs1); + byte_stream_destroy(&bs2); return 1; } - g_free(bs1.data); - g_free(bs2.data); + byte_stream_destroy(&bs1); + byte_stream_destroy(&bs2); return 0; } @@ -445,7 +445,7 @@ len = aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), bs.data); - g_free(bs.data); + byte_stream_destroy(&bs); return len; } @@ -494,7 +494,7 @@ aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), bs.data); - g_free(bs.data); + byte_stream_destroy(&bs); return buflen; }
--- a/libpurple/protocols/silc/silc.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/silc/silc.c Mon Apr 28 06:27:11 2008 +0000 @@ -380,14 +380,6 @@ client = sg->client; - /* Progress */ - if (params.detach_data) { - purple_connection_update_progress(gc, _("Resuming session"), 2, 5); - sg->resuming = TRUE; - } else { - purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5); - } - /* Get session detachment data, if available */ memset(¶ms, 0, sizeof(params)); dfile = silcpurple_session_file(purple_account_get_username(sg->account)); @@ -397,6 +389,14 @@ params.ignore_requested_attributes = FALSE; params.pfs = purple_account_get_bool(sg->account, "pfs", FALSE); + /* Progress */ + if (params.detach_data) { + purple_connection_update_progress(gc, _("Resuming session"), 2, 5); + sg->resuming = TRUE; + } else { + purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5); + } + /* Perform SILC Key Exchange. */ silc_client_key_exchange(sg->client, ¶ms, sg->public_key, sg->private_key, stream, SILC_CONN_SERVER, @@ -433,6 +433,83 @@ silcpurple_stream_created, gc); } +static void silcpurple_continue_running(SilcPurple sg) +{ + PurpleConnection *gc = sg->gc; + PurpleAccount *account = purple_connection_get_account(gc); + + /* Connect to the SILC server */ + if (purple_proxy_connect(gc, account, + purple_account_get_string(account, "server", + "silc.silcnet.org"), + purple_account_get_int(account, "port", 706), + silcpurple_login_connected, gc) == NULL) + { + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Unable to create connection")); + gc->proto_data = NULL; + silc_free(sg); + return; + } +} + +static void silcpurple_got_password_cb(PurpleConnection *gc, PurpleRequestFields *fields) +{ + SilcPurple sg = (SilcPurple)gc->proto_data; + PurpleAccount *account = purple_connection_get_account(gc); + char pkd[256], prd[256]; + const char *password; + gboolean remember; + + /* The password prompt dialog doesn't get disposed if the account disconnects */ + if (!PURPLE_CONNECTION_IS_VALID(gc)) + return; + + password = purple_request_fields_get_string(fields, "password"); + remember = purple_request_fields_get_bool(fields, "remember"); + + if (!password || !*password) + { + purple_notify_error(gc, NULL, _("Password is required to sign on."), NULL); + gc->proto_data = NULL; + silc_free(sg); + return; + } + + if (remember) + purple_account_set_remember_password(account, TRUE); + + purple_account_set_password(account, password); + + /* Load SILC key pair */ + g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir()); + g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir()); + if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd), + (char *)purple_account_get_string(account, "private-key", prd), + password, + &sg->public_key, &sg->private_key)) { + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + _("Could not load SILC key pair")); + gc->proto_data = NULL; + silc_free(sg); + return; + } + silcpurple_continue_running(sg); +} + +static void silcpurple_no_password_cb(PurpleConnection *gc, PurpleRequestFields *fields) +{ + SilcPurple sg; + /* The password prompt dialog doesn't get disposed if the account disconnects */ + if (!PURPLE_CONNECTION_IS_VALID(gc)) + return; + sg = gc->proto_data; + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + _("Could not load SILC key pair")); + gc->proto_data = NULL; + silc_free(sg); +} + static void silcpurple_running(SilcClient client, void *context) { SilcPurple sg = context; @@ -451,26 +528,18 @@ (char *)purple_account_get_string(account, "private-key", prd), (gc->password == NULL) ? "" : gc->password, &sg->public_key, &sg->private_key)) { + if (!purple_account_get_password(account)) { + purple_account_request_password(account, G_CALLBACK(silcpurple_got_password_cb), + G_CALLBACK(silcpurple_no_password_cb), gc); + return; + } purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Could not load SILC key pair")); gc->proto_data = NULL; silc_free(sg); return; } - - /* Connect to the SILC server */ - if (purple_proxy_connect(gc, account, - purple_account_get_string(account, "server", - "silc.silcnet.org"), - purple_account_get_int(account, "port", 706), - silcpurple_login_connected, gc) == NULL) - { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Unable to create connection")); - gc->proto_data = NULL; - silc_free(sg); - return; - } + silcpurple_continue_running(sg); } static void @@ -550,8 +619,12 @@ _("Cannot initialize SILC protocol")); gc->proto_data = NULL; silc_free(sg); + free(hostname); + free(username); return; } + free(hostname); + free(username); /* Check the ~/.silc dir and create it, and new key pair if necessary. */ if (!silcpurple_check_silc_dir(gc)) { @@ -1188,11 +1261,11 @@ static void silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new) { - char prd[256]; + char prd[256]; g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir()); silc_change_private_key_passphrase(purple_account_get_string(gc->account, "private-key", - prd), old, new); + prd), old ? old : "", new ? new : ""); } static void
--- a/libpurple/protocols/silc10/silc.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/silc10/silc.c Mon Apr 28 06:27:11 2008 +0000 @@ -962,11 +962,11 @@ static void silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new) { - char prd[256]; + char prd[256]; g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir()); silc_change_private_key_passphrase(purple_account_get_string(gc->account, "private-key", - prd), old, new); + prd), old ? old : "", new ? new : ""); } static void
--- a/libpurple/protocols/yahoo/yahoo.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Mon Apr 28 06:27:11 2008 +0000 @@ -518,7 +518,7 @@ } else { /* This buddy is on the ignore list (and therefore in no group) */ - purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found", + purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n", account->username, norm_bud); purple_privacy_deny_add(account, norm_bud, 1); }
--- a/libpurple/protocols/yahoo/yahoo.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.h Mon Apr 28 06:27:11 2008 +0000 @@ -76,14 +76,9 @@ #define YAHOO_CLIENT_VERSION_ID "2097087" #define YAHOO_CLIENT_VERSION "8.1.0.421" -#define YAHOOJP_CLIENT_VERSION "6,0,0,1710" -#if 0 -/* The following were observed with the Yahoo Japan client current as of January - * 2008, but appear not to work correctly for file transfer. Here as reference */ -# define YAHOOJP_CLIENT_VERSION_ID "524223" -# define YAHOOJP_CLIENT_VERSION "7,0,1,1" -#endif +#define YAHOOJP_CLIENT_VERSION_ID "524223" +#define YAHOOJP_CLIENT_VERSION "7,0,1,1" /* Index into attention types list. */
--- a/libpurple/protocols/yahoo/yahoo_packet.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.h Mon Apr 28 06:27:11 2008 +0000 @@ -123,7 +123,7 @@ #define YAHOO_WEBMESSENGER_PROTO_VER 0x0065 #define YAHOO_PROTO_VER 0x000f -#define YAHOO_PROTO_VER_JAPAN 0x000c +#define YAHOO_PROTO_VER_JAPAN 0x000f #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4)
--- a/libpurple/savedstatuses.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/savedstatuses.c Mon Apr 28 06:27:11 2008 +0000 @@ -1128,10 +1128,12 @@ g_list_free(accounts); - purple_savedstatus_set_idleaway(FALSE); - - purple_signal_emit(purple_savedstatuses_get_handle(), "savedstatus-changed", - saved_status, old); + if (purple_savedstatus_is_idleaway()) { + purple_savedstatus_set_idleaway(FALSE); + } else { + purple_signal_emit(purple_savedstatuses_get_handle(), "savedstatus-changed", + saved_status, old); + } } void @@ -1250,6 +1252,7 @@ } g_hash_table_destroy(creation_times); + creation_times = NULL; purple_signals_unregister_by_instance(purple_savedstatuses_get_handle()); }
--- a/libpurple/win32/giowin32.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/win32/giowin32.c Mon Apr 28 06:27:11 2008 +0000 @@ -37,8 +37,8 @@ #include <glib.h> #include <stdlib.h> +#include <winsock2.h> #include <windows.h> -#include <winsock.h> /* Not everybody has winsock2 */ #include <fcntl.h> #include <io.h> #include <process.h> @@ -541,7 +541,7 @@ g_io_channel_unref (watch->channel); } -GSourceFuncs g_io_watch_funcs = { +static GSourceFuncs wp_g_io_watch_funcs = { g_io_win32_prepare, g_io_win32_check, g_io_win32_dispatch, @@ -559,7 +559,7 @@ GSource *source; char send_buffer[] = "c"; - source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch)); + source = g_source_new (&wp_g_io_watch_funcs, sizeof (GIOWin32Watch)); watch = (GIOWin32Watch *)source; watch->channel = channel;
--- a/libpurple/win32/libc_interface.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/win32/libc_interface.c Mon Apr 28 06:27:11 2008 +0000 @@ -319,23 +319,23 @@ if (errornum > WSABASEERR) { switch(errornum) { case WSAECONNABORTED: /* 10053 */ - snprintf(errbuf, sizeof(errbuf), _("Connection interrupted by other software on your computer.")); + g_snprintf(errbuf, sizeof(errbuf), _("Connection interrupted by other software on your computer.")); break; case WSAECONNRESET: /* 10054 */ - snprintf(errbuf, sizeof(errbuf), _("Remote host closed connection.")); + g_snprintf(errbuf, sizeof(errbuf), _("Remote host closed connection.")); break; case WSAETIMEDOUT: /* 10060 */ - snprintf(errbuf, sizeof(errbuf), _("Connection timed out.")); + g_snprintf(errbuf, sizeof(errbuf), _("Connection timed out.")); break; case WSAECONNREFUSED: /*10061 */ - snprintf(errbuf, sizeof(errbuf), _("Connection refused.")); + g_snprintf(errbuf, sizeof(errbuf), _("Connection refused.")); break; default: - snprintf(errbuf, sizeof(errbuf), "Windows socket error #%d", errornum); + g_snprintf(errbuf, sizeof(errbuf), "Windows socket error #%d", errornum); } } else { const char *tmp = g_strerror(errornum); - snprintf(errbuf, sizeof(errbuf), tmp); + g_snprintf(errbuf, sizeof(errbuf), tmp); } return errbuf; } @@ -368,7 +368,7 @@ } } else { /* fd is not a socket handle.. pass it off to read */ - return read(fd, buf, size); + return _read(fd, buf, size); } } @@ -391,7 +391,7 @@ if(wpurple_is_socket(fd)) return wpurple_send(fd, buf, size, 0); else - return write(fd, buf, size); + return _write(fd, buf, size); } int wpurple_recv(int fd, void *buf, size_t len, int flags) { @@ -419,7 +419,7 @@ return 0; } else - return close(fd); + return _close(fd); } int wpurple_gethostname(char *name, size_t size) { @@ -454,6 +454,14 @@ /* stdio.h */ int wpurple_rename (const char *oldname, const char *newname) { + +#if GLIB_CHECK_VERSION(2,8,5) + + return g_rename(oldname, newname); + +#else + + /* This is a ugly, but we still compile with 2.6.10 but use newer runtimes */ struct stat oldstat, newstat; /* As of Glib 2.8.5, g_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING to behave more sanely */ @@ -503,6 +511,8 @@ return -1; } +#endif + } /* time.h */ @@ -1080,7 +1090,6 @@ return ""; } -#if !GLIB_CHECK_VERSION(2,8,0) /** * g_access: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) @@ -1105,6 +1114,12 @@ wpurple_g_access (const gchar *filename, int mode) { +#if GLIB_CHECK_VERSION(2,8,0) + + return g_access(filename, mode); + +#else + if (G_WIN32_HAVE_WIDECHAR_API ()) { wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); @@ -1145,7 +1160,8 @@ errno = save_errno; return retval; } + +#endif } -#endif
--- a/libpurple/win32/win32dep.c Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/win32/win32dep.c Mon Apr 28 06:27:11 2008 +0000 @@ -23,23 +23,12 @@ * */ #define _WIN32_IE 0x500 -#include <windows.h> -#include <io.h> -#include <stdlib.h> -#include <stdio.h> +#include "internal.h" #include <winuser.h> -#include <glib.h> -#include <glib/gstdio.h> - -#include "internal.h" #include "debug.h" #include "notify.h" -#include <libintl.h> - -#include "win32dep.h" - /* * DEFINES & MACROS */
--- a/libpurple/win32/win32dep.h Thu Apr 17 07:12:45 2008 +0000 +++ b/libpurple/win32/win32dep.h Mon Apr 28 06:27:11 2008 +0000 @@ -22,8 +22,9 @@ */ #ifndef _WIN32DEP_H_ #define _WIN32DEP_H_ +#include <winsock2.h> +#include <windows.h> #include <shlobj.h> -#include <winsock2.h> #include <process.h> #include "wpurpleerror.h" #include "libc_interface.h"
--- a/pidgin/gtkblist.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkblist.c Mon Apr 28 06:27:11 2008 +0000 @@ -695,6 +695,7 @@ { purple_blist_node_set_bool(node, "show_offline", !purple_blist_node_get_bool(node, "show_offline")); + pidgin_blist_update(purple_get_blist(), node); } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { @@ -704,6 +705,7 @@ purple_blist_node_set_bool(node, "show_offline", setting); for (bnode = node->child; bnode != NULL; bnode = bnode->next) { purple_blist_node_set_bool(bnode, "show_offline", setting); + pidgin_blist_update(purple_get_blist(), bnode); } } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { PurpleBlistNode *cnode, *bnode; @@ -714,10 +716,10 @@ purple_blist_node_set_bool(cnode, "show_offline", setting); for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { purple_blist_node_set_bool(bnode, "show_offline", setting); + pidgin_blist_update(purple_get_blist(), bnode); } } } - pidgin_blist_update(purple_get_blist(), node); } static void gtk_blist_show_systemlog_cb(void)
--- a/pidgin/gtkconv.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkconv.c Mon Apr 28 06:27:11 2008 +0000 @@ -101,6 +101,9 @@ #define DEFAULT_HIGHLIGHT_COLOR "#AF7F00" #define DEFAULT_ACTION_COLOR "#062585" +#define BUDDYICON_SIZE_MIN 32 +#define BUDDYICON_SIZE_MAX 96 + /* Undef this to turn off "custom-smiley" debug messages */ #define DEBUG_CUSTOM_SMILEY @@ -2507,14 +2510,18 @@ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL); - gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), + } else { + emblem = NULL; + } + + gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), &(gtkconv->infopane_iter), CONV_PROTOCOL_ICON_COLUMN, emblem, -1); - if (emblem) - g_object_unref(emblem); - } + if (emblem) + g_object_unref(emblem); /* XXX seanegan Why do I have to do this? */ + gtk_widget_queue_resize(gtkconv->infopane); gtk_widget_queue_draw(gtkconv->infopane); if (status != NULL) @@ -2557,6 +2564,7 @@ GdkPixbuf *scale; gint delay; int scale_width, scale_height; + int size; gtkconv = PIDGIN_CONVERSATION(conv); account = purple_conversation_get_account(conv); @@ -2571,17 +2579,22 @@ gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); - scale_width = gdk_pixbuf_get_width(buf); - scale_height = gdk_pixbuf_get_height(buf); - if (scale_width == scale_height) { - scale_width = scale_height = 32; + scale_width = gdk_pixbuf_get_width(buf); + scale_height = gdk_pixbuf_get_height(buf); + + gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size); + size = MIN(size, MIN(scale_width, scale_height)); + size = CLAMP(size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX); + + if (scale_width == scale_height) { + scale_width = scale_height = size; } else if (scale_height > scale_width) { - scale_width = 32 * scale_width / scale_height; - scale_height = 32; - } else { - scale_height = 32 * scale_height / scale_width; - scale_width = 32; - } + scale_width = size * scale_width / scale_height; + scale_height = size; + } else { + scale_height = size * scale_height / scale_width; + scale_width = size; + } scale = gdk_pixbuf_scale_simple(buf, scale_width, scale_height, GDK_INTERP_BILINEAR); @@ -2701,6 +2714,33 @@ } static void +change_size_cb(GtkWidget *widget, PidginConversation *gtkconv) +{ + int size = 0; + PurpleConversation *conv = gtkconv->active_conv; + GSList *buddies; + + gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size); + + if (size == BUDDYICON_SIZE_MAX) { + size = BUDDYICON_SIZE_MIN; + } else { + size = BUDDYICON_SIZE_MAX; + } + + gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, size); + pidgin_conv_update_buddy_icon(conv); + + buddies = purple_find_buddies(purple_conversation_get_account(conv), + purple_conversation_get_name(conv)); + for (; buddies; buddies = g_slist_delete_link(buddies, buddies)) { + PurpleBuddy *buddy = buddies->data; + PurpleContact *contact = purple_buddy_get_contact(buddy); + purple_blist_node_set_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize", size); + } +} + +static void remove_custom_icon_cb(GtkWidget *widget, PidginConversation *gtkconv) { PurpleConversation *conv; @@ -2761,8 +2801,14 @@ PurpleConversation *conv; PurpleBuddy *buddy; - if (e->button != 3 || e->type != GDK_BUTTON_PRESS) + if (e->button == 1 && e->type == GDK_BUTTON_PRESS) { + change_size_cb(NULL, gtkconv); + return TRUE; + } + + if (e->button != 3 || e->type != GDK_BUTTON_PRESS) { return FALSE; + } /* * If a menu already exists, destroy it before creating a new one, @@ -2792,6 +2838,10 @@ G_CALLBACK(set_custom_icon_cb), gtkconv, 0, 0, NULL); + pidgin_new_item_from_stock(menu, _("Change Size"), NULL, + G_CALLBACK(change_size_cb), gtkconv, + 0, 0, NULL); + /* Is there a custom icon for this person? */ conv = gtkconv->active_conv; buddy = purple_find_buddy(purple_conversation_get_account(conv), @@ -3636,6 +3686,20 @@ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); } +static gboolean +compare_buddy_presence(PurplePresence *p1, PurplePresence *p2) +{ + /* This is necessary because multiple PurpleBuddy's don't share the same + * PurplePresence anymore. + */ + PurpleBuddy *b1 = purple_presence_get_buddy(p1); + PurpleBuddy *b2 = purple_presence_get_buddy(p2); + if (purple_buddy_get_account(b1) == purple_buddy_get_account(b2) && + strcmp(purple_buddy_get_name(b1), purple_buddy_get_name(b2)) == 0) + return FALSE; + return TRUE; +} + static void generate_send_to_items(PidginWindow *win) { @@ -3670,8 +3734,7 @@ if (buds == NULL) { - /* The user isn't on the buddy list. */ - create_sendto_item(menu, sg, &group, NULL, gtkconv->active_conv->account, gtkconv->active_conv->name); + /* The user isn't on the buddy list. So we don't create any sendto menu. */ } else { @@ -3695,20 +3758,22 @@ { /* Use the PurplePresence to get unique buddies. */ PurplePresence *presence = purple_buddy_get_presence(buddy); - if (!g_list_find(list, presence)) + if (!g_list_find_custom(list, presence, (GCompareFunc)compare_buddy_presence)) list = g_list_prepend(list, presence); } } } - /* Loop over the list backwards so we get the items in the right order, - * since we did a g_list_prepend() earlier. */ - for (iter = g_list_last(list); iter != NULL; iter = iter->prev) - { - PurplePresence *pre = iter->data; - PurpleBuddy *buddy = purple_presence_get_buddy(pre); - create_sendto_item(menu, sg, &group, buddy, + /* Create the sendto menu only if it has more than one item to show */ + if (list && list->next) { + /* Loop over the list backwards so we get the items in the right order, + * since we did a g_list_prepend() earlier. */ + for (iter = g_list_last(list); iter != NULL; iter = iter->prev) { + PurplePresence *pre = iter->data; + PurpleBuddy *buddy = purple_presence_get_buddy(pre); + create_sendto_item(menu, sg, &group, buddy, purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)); + } } g_list_free(list); g_slist_free(buds); @@ -4618,8 +4683,10 @@ GtkCellRenderer *rend; GtkTreePath *path; PurpleConversation *conv = gtkconv->active_conv; + PurpleBuddy *buddy; gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); GtkPolicyType imhtml_sw_hscroll; + int buddyicon_size = 0; /* Setup the top part of the pane */ vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); @@ -4647,12 +4714,22 @@ gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), GTK_TREE_MODEL(gtkconv->infopane_model)); + g_object_unref(gtkconv->infopane_model); gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter)); gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), gtkconv->infopane, TRUE, TRUE, 0); path = gtk_tree_path_new_from_string("0"); gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(gtkconv->infopane), path); gtk_tree_path_free(path); - gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, 32); + + if ((buddy = purple_find_buddy(purple_conversation_get_account(conv), + purple_conversation_get_name(conv))) != NULL) { + PurpleContact *contact = purple_buddy_get_contact(buddy); + if (contact) { + buddyicon_size = purple_blist_node_get_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize"); + } + } + buddyicon_size = CLAMP(buddyicon_size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX); + gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, buddyicon_size); gtk_widget_show(gtkconv->infopane); rend = gtk_cell_renderer_pixbuf_new(); @@ -6763,6 +6840,7 @@ GtkWidget *event; GdkPixbuf *scale; int scale_width, scale_height; + int size = 0; PurpleAccount *account; PurplePluginProtocolInfo *prpl_info = NULL; @@ -6875,14 +6953,20 @@ scale_width = gdk_pixbuf_get_width(buf); scale_height = gdk_pixbuf_get_height(buf); + + gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size); + size = MIN(size, MIN(scale_width, scale_height)); + + /* Some sanity checks */ + size = CLAMP(size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX); if (scale_width == scale_height) { - scale_width = scale_height = 32; + scale_width = scale_height = size; } else if (scale_height > scale_width) { - scale_width = 32 * scale_width / scale_height; - scale_height = 32; + scale_width = size * scale_width / scale_height; + scale_height = size; } else { - scale_height = 32 * scale_height / scale_width; - scale_width = 32; + scale_height = size * scale_height / scale_width; + scale_width = size; } scale = gdk_pixbuf_scale_simple(buf, scale_width, scale_height, GDK_INTERP_BILINEAR); @@ -7722,7 +7806,7 @@ animate_buddy_icons_pref_cb, NULL); purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", show_buddy_icons_pref_cb, NULL); - purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_protocol_icons", + purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons", show_protocol_icons_pref_cb, NULL); purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", hide_new_pref_cb, NULL); @@ -8265,7 +8349,7 @@ } else { page_num = 0; to_right = pidgin_conv_xy_to_right_infopane(dest_win, e->x_root, e->y_root); - tab = pidgin_conv_window_get_gtkconv_at_index(dest_win, page_num)->infopane; + tab = pidgin_conv_window_get_gtkconv_at_index(dest_win, page_num)->infopane_hbox; } if (gtk_notebook_get_tab_pos(dest_notebook) == GTK_POS_TOP || @@ -8575,7 +8659,7 @@ gtk_window_get_size(GTK_WINDOW(dest_win->window), &win_width, &win_height); -#ifdef WIN32 /* only override window manager placement on Windows */ +#ifdef _WIN32 /* only override window manager placement on Windows */ gtk_window_move(GTK_WINDOW(dest_win->window), e->x_root - (win_width / 2), e->y_root - (win_height / 2)); @@ -9011,7 +9095,9 @@ conv_y = 100; /* ...and move it back. */ +#ifdef _WIN32 /* only override window manager placement on Windows */ gtk_window_move(GTK_WINDOW(win->window), conv_x, conv_y); +#endif gtk_window_resize(GTK_WINDOW(win->window), conv_width, conv_height); } } @@ -9046,7 +9132,13 @@ if (!gtk_get_current_event_state(&state)) gtk_window_set_focus_on_map(GTK_WINDOW(win->window), FALSE); #endif + /* Etan: I really think this entire function call should happen only + * when we are on Windows but I was informed that back before we used + * to save the window position we stored the window size, so I'm + * leaving it for now. */ +#if TRUE || defined(_WIN32) pidgin_conv_restore_position(win); +#endif if (available_list == NULL) { create_icon_lists(win->window);
--- a/pidgin/gtkimhtml.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkimhtml.c Mon Apr 28 06:27:11 2008 +0000 @@ -758,6 +758,7 @@ rect.height = tag_area.y + tag_area.height - rect.y + + gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget)) + gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)); color = tag->name + 11; @@ -1201,16 +1202,20 @@ } static void -gtk_imhtml_undo(GtkIMHtml *imhtml) { +gtk_imhtml_undo(GtkIMHtml *imhtml) +{ g_return_if_fail(GTK_IS_IMHTML(imhtml)); - if (imhtml->editable) + if (imhtml->editable && + gtk_source_undo_manager_can_undo(imhtml->undo_manager)) gtk_source_undo_manager_undo(imhtml->undo_manager); } static void -gtk_imhtml_redo(GtkIMHtml *imhtml) { +gtk_imhtml_redo(GtkIMHtml *imhtml) +{ g_return_if_fail(GTK_IS_IMHTML(imhtml)); - if (imhtml->editable) + if (imhtml->editable && + gtk_source_undo_manager_can_redo(imhtml->undo_manager)) gtk_source_undo_manager_redo(imhtml->undo_manager); } @@ -1459,7 +1464,8 @@ gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); - gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 5); + gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(imhtml), 2); + gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 3); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(imhtml), 2); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(imhtml), 2); /*gtk_text_view_set_indent(GTK_TEXT_VIEW(imhtml), -15);*/ @@ -2425,6 +2431,7 @@ ws = g_malloc(len + 1); ws[0] = 0; + gtk_text_buffer_begin_user_action(imhtml->text_buffer); while (pos < len) { if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { c++; @@ -2697,8 +2704,11 @@ if (sml) font->sml = sml; - else if (oldfont && oldfont->sml) - font->sml = g_strdup(oldfont->sml); + else { + g_free(sml); + if (oldfont && oldfont->sml) + font->sml = g_strdup(oldfont->sml); + } if (size && !(options & GTK_IMHTML_NO_SIZES) && (imhtml->format_functions & (GTK_IMHTML_GROW|GTK_IMHTML_SHRINK))) { if (*size == '+') { @@ -2750,7 +2760,7 @@ case 46: /* IMG (opt) */ case 59: /* IMG */ { - const char *id; + char *id; gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); ws[0] = '\0'; wpos = 0; @@ -2762,6 +2772,7 @@ if (!id) break; gtk_imhtml_insert_image_at_iter(imhtml, atoi(id), iter); + g_free(id); break; } case 47: /* P (opt) */ @@ -3149,6 +3160,7 @@ g_signal_emit(object, signals[UPDATE_FORMAT], 0); g_object_unref(object); + gtk_text_buffer_end_user_action(imhtml->text_buffer); } void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml)
--- a/pidgin/gtkmain.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkmain.c Mon Apr 28 06:27:11 2008 +0000 @@ -27,6 +27,7 @@ #include "account.h" #include "conversation.h" #include "core.h" +#include "dbus-maybe.h" #include "debug.h" #include "eventloop.h" #include "ft.h" @@ -783,6 +784,15 @@ } if (opt_si && !purple_core_ensure_single_instance()) { +#ifdef HAVE_DBUS + DBusConnection *conn = purple_dbus_get_connection(); + DBusMessage *message = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, + DBUS_INTERFACE_PURPLE, "PurpleBlistSetVisible"); + gboolean tr = TRUE; + dbus_message_append_args(message, DBUS_TYPE_UINT32, &tr, DBUS_TYPE_INVALID); + dbus_connection_send_with_reply_and_block(conn, message, -1, NULL); + dbus_message_unref(message); +#endif purple_debug_info("main", "exiting because another libpurple client is already running\n"); purple_core_quit(); #ifdef HAVE_SIGNAL_H
--- a/pidgin/gtkmenutray.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkmenutray.c Mon Apr 28 06:27:11 2008 +0000 @@ -134,8 +134,6 @@ if(!GTK_IS_WIDGET(menu_tray->tray)) menu_tray->tray = gtk_hbox_new(FALSE, 0); - menu_tray->tooltips = gtk_tooltips_new(); - #if GTK_CHECK_VERSION(2,2,0) settings = gtk_settings_get_for_screen(gtk_widget_get_screen(widget)); @@ -235,7 +233,7 @@ pidgin_menu_tray_set_tooltip(PidginMenuTray *menu_tray, GtkWidget *widget, const char *tooltip) { if (!menu_tray->tooltips) - return; + menu_tray->tooltips = gtk_tooltips_new(); /* Should we check whether widget is a child of menu_tray? */
--- a/pidgin/gtksourceundomanager.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtksourceundomanager.c Mon Apr 28 06:27:11 2008 +0000 @@ -41,10 +41,12 @@ typedef struct _GtkSourceUndoAction GtkSourceUndoAction; typedef struct _GtkSourceUndoInsertAction GtkSourceUndoInsertAction; typedef struct _GtkSourceUndoDeleteAction GtkSourceUndoDeleteAction; +typedef struct _GtkSourceUndoInsertAnchorAction GtkSourceUndoInsertAnchorAction; typedef enum { GTK_SOURCE_UNDO_ACTION_INSERT, - GTK_SOURCE_UNDO_ACTION_DELETE + GTK_SOURCE_UNDO_ACTION_DELETE, + GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR, } GtkSourceUndoActionType; /* @@ -68,6 +70,12 @@ gboolean forward; }; +struct _GtkSourceUndoInsertAnchorAction +{ + gint pos; + GtkTextChildAnchor *anchor; +}; + struct _GtkSourceUndoAction { GtkSourceUndoActionType action_type; @@ -75,6 +83,7 @@ union { GtkSourceUndoInsertAction insert; GtkSourceUndoDeleteAction delete; + GtkSourceUndoInsertAnchorAction insert_anchor; } action; gint order_in_group; @@ -139,6 +148,10 @@ const gchar *text, gint length, GtkSourceUndoManager *um); +static void gtk_source_undo_manager_insert_anchor_handler (GtkTextBuffer *buffer, + GtkTextIter *pos, + GtkTextChildAnchor *anchor, + GtkSourceUndoManager *um); static void gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, @@ -275,6 +288,10 @@ um); g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), + G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), + um); + + g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler), um); @@ -297,6 +314,10 @@ G_CALLBACK (gtk_source_undo_manager_insert_text_handler), um); + g_signal_connect (G_OBJECT (buffer), "insert_child_anchor", + G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), + um); + g_signal_connect (G_OBJECT (buffer), "delete_range", G_CALLBACK (gtk_source_undo_manager_delete_range_handler), um); @@ -403,6 +424,15 @@ } static void +insert_anchor (GtkTextBuffer *buffer, gint pos, GtkTextChildAnchor *anchor) +{ + GtkTextIter iter; + + gtk_text_buffer_get_iter_at_offset (buffer, &iter, pos); + gtk_text_buffer_insert_child_anchor (buffer, &iter, anchor); +} + +static void delete_text (GtkTextBuffer *buffer, gint start, gint end) { GtkTextIter start_iter; @@ -497,6 +527,13 @@ undo_action->action.insert.pos); break; + case GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR: + delete_text ( + um->priv->document, + undo_action->action.insert_anchor.pos, + undo_action->action.insert_anchor.pos + 1); + undo_action->action.insert_anchor.anchor->segment = NULL; /* XXX: This may be a bug in GTK+ */ + break; default: /* Unknown action type. */ g_return_if_reached (); @@ -588,6 +625,17 @@ break; + case GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR: + set_cursor ( + um->priv->document, + undo_action->action.insert_anchor.pos); + + insert_anchor ( + um->priv->document, + undo_action->action.insert_anchor.pos, + undo_action->action.insert_anchor.anchor); + break; + default: /* Unknown action type */ ++um->priv->next_redo; @@ -633,6 +681,8 @@ g_free (action->action.insert.text); else if (action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE) g_free (action->action.delete.text); + else if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR) + g_object_unref(action->action.insert_anchor.anchor); else g_return_if_reached (); @@ -695,6 +745,27 @@ gtk_source_undo_manager_add_action (um, &undo_action); } +static void gtk_source_undo_manager_insert_anchor_handler (GtkTextBuffer *buffer, + GtkTextIter *pos, + GtkTextChildAnchor *anchor, + GtkSourceUndoManager *um) +{ + GtkSourceUndoAction undo_action; + + if (um->priv->running_not_undoable_actions > 0) + return; + + undo_action.action_type = GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR; + + undo_action.action.insert_anchor.pos = gtk_text_iter_get_offset (pos); + undo_action.action.insert_anchor.anchor = g_object_ref (anchor); + + undo_action.mergeable = FALSE; + undo_action.modified = FALSE; + + gtk_source_undo_manager_add_action (um, &undo_action); +} + static void gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, GtkTextIter *start, @@ -775,6 +846,10 @@ action->action.insert.text = g_strndup (undo_action->action.insert.text, undo_action->action.insert.length); else if (action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE) action->action.delete.text = g_strdup (undo_action->action.delete.text); + else if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR) + { + /* Nothing needs to be done */ + } else { g_free (action); @@ -998,6 +1073,10 @@ last_action->action.insert.chars += undo_action->action.insert.chars; } + else if (undo_action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR) + { + /* Nothing needs to be done */ + } else /* Unknown action inside undo merge encountered */ g_return_val_if_reached (TRUE);
--- a/pidgin/gtkstatusbox.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/gtkstatusbox.c Mon Apr 28 06:27:11 2008 +0000 @@ -74,6 +74,7 @@ static void remove_typing_cb(PidginStatusBox *box); static void update_size (PidginStatusBox *box); static gint get_statusbox_index(PidginStatusBox *box, PurpleSavedStatus *saved_status); +static PurpleAccount* check_active_accounts_for_identical_statuses(void); static void pidgin_status_box_pulse_typing(PidginStatusBox *status_box); static void pidgin_status_box_refresh(PidginStatusBox *status_box); @@ -497,6 +498,10 @@ break; case PROP_ACCOUNT: statusbox->account = g_value_get_pointer(value); + if (statusbox->account) + statusbox->token_status_account = NULL; + else + statusbox->token_status_account = check_active_accounts_for_identical_statuses(); pidgin_status_box_regenerate(statusbox); @@ -628,7 +633,7 @@ GdkPixbuf *pixbuf, *emblem = NULL; GtkTreePath *path; gboolean account_status = FALSE; - PurpleAccount *acct = (status_box->token_status_account) ? status_box->token_status_account : status_box->account; + PurpleAccount *acct = (status_box->account) ? status_box->account : status_box->token_status_account; icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL); @@ -1135,7 +1140,7 @@ GTK_DIR_TAB_BACKWARD: GTK_DIR_TAB_FORWARD); return TRUE; } - if (!status_box->typing != 0) + if (status_box->typing == 0) return FALSE; /* Reset the status if Escape was pressed */ @@ -1228,9 +1233,13 @@ icon_size, "PidginStatusBox"); } -static void account_enabled_cb(PurpleAccount *acct, PidginStatusBox *status_box) { +static void account_enabled_cb(PurpleAccount *acct, PidginStatusBox *status_box) +{ PurpleAccount *initial_token_acct = status_box->token_status_account; + if (status_box->account) + return; + status_box->token_status_account = check_active_accounts_for_identical_statuses(); /* Regenerate the list if it has changed */ @@ -1686,6 +1695,17 @@ } static void +imhtml_cursor_moved_cb(gpointer data, GtkMovementStep step, gint count, gboolean extend, + GtkWidget *widget) +{ + /* Restart the typing timeout if arrow keys are pressed while editing the message */ + PidginStatusBox *status_box = data; + if (status_box->typing == 0) + return; + imhtml_changed_cb(NULL, status_box); +} + +static void pidgin_status_box_init (PidginStatusBox *status_box) { GtkCellRenderer *text_rend; @@ -1714,6 +1734,8 @@ gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); gtk_list_store_append(status_box->store, &(status_box->iter)); + atk_object_set_name(gtk_widget_get_accessible(status_box->toggle_button), _("Status Selector")); + gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, FALSE, 0); @@ -1825,6 +1847,8 @@ g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box); g_signal_connect(G_OBJECT(status_box->imhtml), "format_function_toggle", G_CALLBACK(imhtml_format_changed_cb), status_box); + g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "move_cursor", + G_CALLBACK(imhtml_cursor_moved_cb), status_box); g_signal_connect(G_OBJECT(status_box->imhtml), "key_press_event", G_CALLBACK(imhtml_remove_focus), status_box); g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box);
--- a/pidgin/minidialog.c Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/minidialog.c Mon Apr 28 06:27:11 2008 +0000 @@ -406,6 +406,7 @@ priv->title = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(priv->title), label_width, -1); gtk_label_set_line_wrap(priv->title, TRUE); + gtk_label_set_selectable(priv->title, TRUE); gtk_misc_set_alignment(GTK_MISC(priv->title), 0, 0); gtk_box_pack_start(priv->title_box, GTK_WIDGET(priv->icon), FALSE, FALSE, 0); @@ -415,6 +416,7 @@ gtk_widget_set_size_request(GTK_WIDGET(priv->desc), label_width, -1); gtk_label_set_line_wrap(priv->desc, TRUE); gtk_misc_set_alignment(GTK_MISC(priv->desc), 0, 0); + gtk_label_set_selectable(priv->desc, TRUE); /* make calling show_all() on the minidialog not affect desc even though * it's packed inside it. */
--- a/pidgin/plugins/Makefile.am Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/plugins/Makefile.am Mon Apr 28 06:27:11 2008 +0000 @@ -41,6 +41,7 @@ notify_la_LDFLAGS = -module -avoid-version pidginrc_la_LDFLAGS = -module -avoid-version relnot_la_LDFLAGS = -module -avoid-version +sendbutton_la_LDFLAGS = -module -avoid-version spellchk_la_LDFLAGS = -module -avoid-version timestamp_la_LDFLAGS = -module -avoid-version timestamp_format_la_LDFLAGS = -module -avoid-version @@ -58,6 +59,7 @@ notify.la \ pidginrc.la \ relnot.la \ + sendbutton.la \ spellchk.la \ timestamp.la \ timestamp_format.la \ @@ -78,6 +80,7 @@ notify_la_SOURCES = notify.c pidginrc_la_SOURCES = pidginrc.c relnot_la_SOURCES = relnot.c +sendbutton_la_SOURCES = sendbutton.c spellchk_la_SOURCES = spellchk.c timestamp_la_SOURCES = timestamp.c timestamp_format_la_SOURCES = timestamp_format.c @@ -94,6 +97,7 @@ notify_la_LIBADD = $(GTK_LIBS) pidginrc_la_LIBADD = $(GTK_LIBS) relnot_la_LIBADD = $(GLIB_LIBS) +sendbutton_la_LIBADD = $(GTK_LIBS) spellchk_la_LIBADD = $(GTK_LIBS) timestamp_la_LIBADD = $(GTK_LIBS) timestamp_format_la_LIBADD = $(GTK_LIBS)
--- a/pidgin/plugins/perl/Makefile.am Thu Apr 17 07:12:45 2008 +0000 +++ b/pidgin/plugins/perl/Makefile.am Mon Apr 28 06:27:11 2008 +0000 @@ -39,7 +39,9 @@ common/Makefile: common/Makefile.PL @if test "x${top_srcdir}" != "x${top_builddir}"; then \ for f in ${common_sources}; do \ - ${LN_S} -f ../${srcdir}/$$f $$f; \ + srcloc=${srcdir}; \ + case $$srcloc in /*) ;; *) srcloc=../${srcdir} ;; esac; \ + ${LN_S} -f $$srcloc/$$f $$f; \ done; \ fi @cd common && $(perlpath) Makefile.PL $(PERL_MM_PARAMS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/plugins/sendbutton.c Mon Apr 28 06:27:11 2008 +0000 @@ -0,0 +1,166 @@ +/* + * SendButton - Add a Send button to the conversation window entry area. + * Copyright (C) 2008 Etan Reisner <deryni@pidgin.im> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "internal.h" + +#include "version.h" + +#include "pidgin.h" + +#include "gtkconv.h" +#include "gtkplugin.h" + +static void +send_button_cb(GtkButton *button, PidginConversation *gtkconv) +{ + g_signal_emit_by_name(gtkconv->entry, "message_send"); +} + +static void +create_send_button_pidgin(PidginConversation *gtkconv) +{ + GtkWidget *send_button; + + send_button = gtk_button_new_with_mnemonic(_("_Send")); + g_signal_connect(G_OBJECT(send_button), "clicked", + G_CALLBACK(send_button_cb), gtkconv); + gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), send_button, FALSE, + FALSE, 0); + gtk_widget_show(send_button); + + g_object_set_data(G_OBJECT(gtkconv->lower_hbox), "send_button", + send_button); +} + +static void +remove_send_button_pidgin(PidginConversation *gtkconv) +{ + GtkWidget *send_button = NULL; + + send_button = g_object_get_data(G_OBJECT(gtkconv->lower_hbox), + "send_button"); + if (send_button != NULL) { + gtk_widget_destroy(send_button); + } +} + +static void +conversation_displayed_cb(PidginConversation *gtkconv) +{ + GtkWidget *send_button = NULL; + + send_button = g_object_get_data(G_OBJECT(gtkconv->lower_hbox), + "send_button"); + if (send_button == NULL) { + create_send_button_pidgin(gtkconv); + } +} + +static gboolean +plugin_load(PurplePlugin *plugin) +{ + GList *convs = purple_get_conversations(); + void *gtk_conv_handle = pidgin_conversations_get_handle(); + + purple_signal_connect(gtk_conv_handle, "conversation-displayed", plugin, + PURPLE_CALLBACK(conversation_displayed_cb), NULL); + /* + purple_signal_connect(gtk_conv_handle, "conversation-hiding", plugin, + PURPLE_CALLBACK(conversation_hiding_cb), NULL); + */ + + while (convs) { + + PurpleConversation *conv = (PurpleConversation *)convs->data; + + /* Setup Send button */ + if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) { + create_send_button_pidgin(PIDGIN_CONVERSATION(conv)); + } + + convs = convs->next; + } + + return TRUE; +} + +static gboolean +plugin_unload(PurplePlugin *plugin) +{ + GList *convs = purple_get_conversations(); + + while (convs) { + PurpleConversation *conv = (PurpleConversation *)convs->data; + + /* Remove Send button */ + if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) { + remove_send_button_pidgin(PIDGIN_CONVERSATION(conv)); + } + + convs = convs->next; + } + + return TRUE; +} + +static PurplePluginInfo info = +{ + PURPLE_PLUGIN_MAGIC, + PURPLE_MAJOR_VERSION, /**< major version */ + PURPLE_MINOR_VERSION, /**< minor version */ + PURPLE_PLUGIN_STANDARD, /**< type */ + PIDGIN_PLUGIN_TYPE, /**< ui_requirement */ + 0, /**< flags */ + NULL, /**< dependencies */ + PURPLE_PRIORITY_DEFAULT, /**< priority */ + + "gtksendbutton", /**< id */ + N_("Send Button"), /**< name */ + DISPLAY_VERSION, /**< version */ + N_("Conversation Window Send Button."), /**< summary */ + N_("Adds a Send button to the entry area of " + "the conversation window. Intended for when " + "no physical keyboard is present."), /**< description */ + "Etan Reisner <deryni@pidgin.im>", /**< author */ + PURPLE_WEBSITE, /**< homepage */ + plugin_load, /**< load */ + plugin_unload, /**< unload */ + NULL, /**< destroy */ + NULL, /**< ui_info */ + NULL, /**< extra_info */ + NULL, /**< prefs_info */ + NULL, /**< actions */ + + /* padding */ + NULL, + NULL, + NULL, + NULL +}; + +static void +init_plugin(PurplePlugin *plugin) +{ +} + +PURPLE_INIT_PLUGIN(sendbutton, init_plugin, info)
--- a/po/POTFILES.in Thu Apr 17 07:12:45 2008 +0000 +++ b/po/POTFILES.in Mon Apr 28 06:27:11 2008 +0000 @@ -242,6 +242,7 @@ pidgin/plugins/pidginrc.c pidgin/plugins/raw.c pidgin/plugins/relnot.c +pidgin/plugins/sendbutton.c pidgin/plugins/spellchk.c pidgin/plugins/ticker/ticker.c pidgin/plugins/timestamp.c