summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Villaseñor <masca@cpw.pidgin.im>2010-09-11 19:03:25 +0000
committerJorge Villaseñor <masca@cpw.pidgin.im>2010-09-11 19:03:25 +0000
commit12cb6d0d865139adc30ab1cc81fdf6d30251edb6 (patch)
tree6f3f7ffe6ec2542274a3d34ad6f26ce15617c5d0
parentb2b04723ec4ed34a274bfabe7e4a0835e44cc6b4 (diff)
parent24b6daf50b922b6a2895a9e5d205c40095a2fbb6 (diff)
downloadpidgin-12cb6d0d865139adc30ab1cc81fdf6d30251edb6.tar.gz
propagate from branch 'im.pidgin.pidgin' (head 3e676c22e294f13dae001ce73244b34bfec41c39)cpw.qulogic.msnp16
to branch 'im.pidgin.cpw.qulogic.msnp16' (head 5c9d3ec23a058643590d11b15d023fd656e4968e)
-rw-r--r--COPYRIGHT1
-rw-r--r--ChangeLog48
-rw-r--r--ChangeLog.API12
-rw-r--r--NEWS10
-rw-r--r--configure.ac5
-rw-r--r--finch/gntaccount.c25
-rw-r--r--finch/gntft.c7
-rw-r--r--finch/gntft.h4
-rw-r--r--finch/libgnt/gntentry.c7
-rw-r--r--finch/libgnt/gnttextview.c2
-rw-r--r--libpurple/account.c24
-rw-r--r--libpurple/conversation.c4
-rw-r--r--libpurple/debug.h12
-rw-r--r--libpurple/desktopitem.c2
-rw-r--r--libpurple/ft.c1
-rw-r--r--libpurple/ft.h9
-rw-r--r--libpurple/log.c3
-rw-r--r--libpurple/media.c3
-rw-r--r--libpurple/media/backend-fs2.c85
-rw-r--r--libpurple/media/codec.c10
-rw-r--r--libpurple/media/codec.h3
-rw-r--r--libpurple/network.c11
-rw-r--r--libpurple/network.h2
-rw-r--r--libpurple/plugins/idle.c3
-rw-r--r--libpurple/plugins/perl/common/BuddyList.xs24
-rw-r--r--libpurple/plugins/perl/common/Server.xs1
-rw-r--r--libpurple/plugins/signals-test.c4
-rw-r--r--libpurple/plugins/tcl/tcl_cmd.c9
-rw-r--r--libpurple/plugins/tcl/tcl_signals.c6
-rw-r--r--libpurple/prefs.c1
-rw-r--r--libpurple/protocols/bonjour/bonjour.c6
-rw-r--r--libpurple/protocols/bonjour/jabber.c3
-rw-r--r--libpurple/protocols/bonjour/mdns_avahi.c3
-rw-r--r--libpurple/protocols/jabber/Makefile.am26
-rw-r--r--libpurple/protocols/jabber/Makefile.mingw8
-rw-r--r--libpurple/protocols/jabber/auth.c14
-rw-r--r--libpurple/protocols/jabber/auth_cyrus.c16
-rw-r--r--libpurple/protocols/jabber/bosh.c3
-rw-r--r--libpurple/protocols/jabber/buddy.c2
-rw-r--r--libpurple/protocols/jabber/chat.c15
-rw-r--r--libpurple/protocols/jabber/disco.c6
-rw-r--r--libpurple/protocols/jabber/google.c1429
-rw-r--r--libpurple/protocols/jabber/google/gmail.c207
-rw-r--r--libpurple/protocols/jabber/google/gmail.h30
-rw-r--r--libpurple/protocols/jabber/google/google.c172
-rw-r--r--libpurple/protocols/jabber/google/google.h35
-rw-r--r--libpurple/protocols/jabber/google/google_presence.c43
-rw-r--r--libpurple/protocols/jabber/google/google_presence.h32
-rw-r--r--libpurple/protocols/jabber/google/google_roster.c206
-rw-r--r--libpurple/protocols/jabber/google/google_roster.h (renamed from libpurple/protocols/jabber/google.h)29
-rw-r--r--libpurple/protocols/jabber/google/google_session.c866
-rw-r--r--libpurple/protocols/jabber/google/google_session.h54
-rw-r--r--libpurple/protocols/jabber/google/jingleinfo.c174
-rw-r--r--libpurple/protocols/jabber/google/jingleinfo.h32
-rw-r--r--libpurple/protocols/jabber/google/relay.c151
-rw-r--r--libpurple/protocols/jabber/google/relay.h33
-rw-r--r--libpurple/protocols/jabber/iq.c5
-rw-r--r--libpurple/protocols/jabber/jabber.c61
-rw-r--r--libpurple/protocols/jabber/jabber.h10
-rw-r--r--libpurple/protocols/jabber/jingle/jingle.c92
-rw-r--r--libpurple/protocols/jabber/jingle/jingle.h6
-rw-r--r--libpurple/protocols/jabber/jingle/rtp.c3
-rw-r--r--libpurple/protocols/jabber/jingle/transport.c4
-rw-r--r--libpurple/protocols/jabber/libxmpp.c26
-rw-r--r--libpurple/protocols/jabber/message.c11
-rw-r--r--libpurple/protocols/jabber/oob.c4
-rw-r--r--libpurple/protocols/jabber/parser.c17
-rw-r--r--libpurple/protocols/jabber/presence.c3
-rw-r--r--libpurple/protocols/jabber/roster.c6
-rw-r--r--libpurple/protocols/jabber/si.c6
-rw-r--r--libpurple/protocols/msn/contact.c25
-rw-r--r--libpurple/protocols/msn/directconn.h2
-rw-r--r--libpurple/protocols/msn/httpconn.c10
-rw-r--r--libpurple/protocols/msn/msn.c5
-rw-r--r--libpurple/protocols/msn/msnutils.c2
-rw-r--r--libpurple/protocols/msn/notification.c22
-rw-r--r--libpurple/protocols/msn/session.c2
-rw-r--r--libpurple/protocols/msn/slp.c28
-rw-r--r--libpurple/protocols/msn/slplink.c2
-rw-r--r--libpurple/protocols/msn/soap.c6
-rw-r--r--libpurple/protocols/msn/switchboard.c8
-rw-r--r--libpurple/protocols/oscar/Makefile.am10
-rw-r--r--libpurple/protocols/oscar/Makefile.mingw16
-rw-r--r--libpurple/protocols/oscar/authorization.c153
-rw-r--r--libpurple/protocols/oscar/bstream.c127
-rw-r--r--libpurple/protocols/oscar/encoding.c235
-rw-r--r--libpurple/protocols/oscar/encoding.h46
-rw-r--r--libpurple/protocols/oscar/family_admin.c10
-rw-r--r--libpurple/protocols/oscar/family_advert.c51
-rw-r--r--libpurple/protocols/oscar/family_alert.c4
-rw-r--r--libpurple/protocols/oscar/family_auth.c34
-rw-r--r--libpurple/protocols/oscar/family_bart.c4
-rw-r--r--libpurple/protocols/oscar/family_bos.c92
-rw-r--r--libpurple/protocols/oscar/family_buddy.c111
-rw-r--r--libpurple/protocols/oscar/family_chat.c218
-rw-r--r--libpurple/protocols/oscar/family_chatnav.c76
-rw-r--r--libpurple/protocols/oscar/family_feedbag.c208
-rw-r--r--libpurple/protocols/oscar/family_icbm.c1287
-rw-r--r--libpurple/protocols/oscar/family_icq.c403
-rw-r--r--libpurple/protocols/oscar/family_invite.c53
-rw-r--r--libpurple/protocols/oscar/family_locate.c261
-rw-r--r--libpurple/protocols/oscar/family_odir.c264
-rw-r--r--libpurple/protocols/oscar/family_oservice.c163
-rw-r--r--libpurple/protocols/oscar/family_userlookup.c2
-rw-r--r--libpurple/protocols/oscar/flap_connection.c28
-rw-r--r--libpurple/protocols/oscar/libaim.c3
-rw-r--r--libpurple/protocols/oscar/libicq.c6
-rw-r--r--libpurple/protocols/oscar/misc.c31
-rw-r--r--libpurple/protocols/oscar/msgcookie.c15
-rw-r--r--libpurple/protocols/oscar/odc.c11
-rw-r--r--libpurple/protocols/oscar/oft.c2
-rw-r--r--libpurple/protocols/oscar/oscar.c1982
-rw-r--r--libpurple/protocols/oscar/oscar.h570
-rw-r--r--libpurple/protocols/oscar/oscar_data.c4
-rw-r--r--libpurple/protocols/oscar/oscarcommon.h1
-rw-r--r--libpurple/protocols/oscar/peer_proxy.c10
-rw-r--r--libpurple/protocols/oscar/rxhandlers.c191
-rw-r--r--libpurple/protocols/oscar/snac.c4
-rw-r--r--libpurple/protocols/oscar/tlv.c52
-rw-r--r--libpurple/protocols/oscar/userinfo.c553
-rw-r--r--libpurple/protocols/oscar/util.c171
-rw-r--r--libpurple/protocols/oscar/visibility.c199
-rw-r--r--libpurple/protocols/oscar/visibility.h (renamed from libpurple/protocols/oscar/family_translate.c)30
-rw-r--r--libpurple/protocols/qq/ChangeLog2
-rw-r--r--libpurple/protocols/qq/buddy_info.c11
-rw-r--r--libpurple/protocols/qq/buddy_list.c16
-rw-r--r--libpurple/protocols/qq/buddy_opt.c16
-rw-r--r--libpurple/protocols/qq/char_conv.c20
-rw-r--r--libpurple/protocols/qq/file_trans.c6
-rw-r--r--libpurple/protocols/qq/group.c2
-rw-r--r--libpurple/protocols/qq/group_im.c30
-rw-r--r--libpurple/protocols/qq/group_join.c6
-rw-r--r--libpurple/protocols/qq/group_opt.c2
-rw-r--r--libpurple/protocols/qq/im.c13
-rw-r--r--libpurple/protocols/qq/qq.c12
-rw-r--r--libpurple/protocols/qq/qq_base.c3
-rw-r--r--libpurple/protocols/qq/qq_network.c6
-rw-r--r--libpurple/protocols/qq/qq_process.c22
-rw-r--r--libpurple/protocols/qq/qq_trans.c9
-rw-r--r--libpurple/protocols/qq/send_file.c10
-rw-r--r--libpurple/protocols/sametime/sametime.c2
-rw-r--r--libpurple/protocols/silc/chat.c4
-rw-r--r--libpurple/protocols/silc/ops.c2
-rw-r--r--libpurple/protocols/silc/silcpurple.h2
-rw-r--r--libpurple/protocols/silc10/chat.c4
-rw-r--r--libpurple/protocols/silc10/ops.c2
-rw-r--r--libpurple/protocols/silc10/silcpurple.h2
-rw-r--r--libpurple/protocols/yahoo/libymsg.c29
-rw-r--r--libpurple/protocols/yahoo/util.c2
-rw-r--r--libpurple/protocols/yahoo/yahoo_aliases.c2
-rw-r--r--libpurple/protocols/yahoo/yahoo_doodle.c4
-rw-r--r--libpurple/protocols/yahoo/yahoo_doodle.h2
-rw-r--r--libpurple/protocols/yahoo/yahoo_filexfer.c15
-rw-r--r--libpurple/protocols/yahoo/yahoochat.c12
-rw-r--r--libpurple/protocols/zephyr/ZVariables.c6
-rw-r--r--libpurple/proxy.c2
-rw-r--r--libpurple/request.c5
-rw-r--r--libpurple/stun.c24
-rw-r--r--libpurple/util.c2
-rw-r--r--libpurple/win32/global.mak2
-rw-r--r--libpurple/win32/targets.mak3
-rw-r--r--libpurple/win32/win32dep.c17
-rw-r--r--pidgin.spec.in6
-rw-r--r--pidgin/Makefile.am3
-rw-r--r--pidgin/Makefile.mingw9
-rw-r--r--pidgin/gtkaccount.c96
-rw-r--r--pidgin/gtkblist.c19
-rw-r--r--pidgin/gtkconv.c59
-rw-r--r--pidgin/gtkdialogs.c2
-rw-r--r--pidgin/gtkft.c10
-rw-r--r--pidgin/gtkft.h4
-rw-r--r--pidgin/gtkidle.c2
-rw-r--r--pidgin/gtkimhtml.c2
-rw-r--r--pidgin/gtkimhtmltoolbar.c2
-rw-r--r--pidgin/gtkplugin.c3
-rw-r--r--pidgin/gtkpounce.c3
-rw-r--r--pidgin/gtkprefs.c118
-rw-r--r--pidgin/gtkroomlist.c2
-rw-r--r--pidgin/gtksession.c2
-rw-r--r--pidgin/gtksmiley.c3
-rw-r--r--pidgin/gtksourceundomanager.c2
-rw-r--r--pidgin/gtkstatusbox.c19
-rw-r--r--pidgin/gtkutils.c178
-rw-r--r--pidgin/gtkutils.h11
-rw-r--r--pidgin/minidialog.c46
-rw-r--r--pidgin/minidialog.h18
-rw-r--r--pidgin/pidginstock.h2
-rw-r--r--pidgin/pixmaps/emotes/default/24/default.theme.in94
-rw-r--r--pidgin/pixmaps/emotes/small/16/Makefile.am3
-rw-r--r--pidgin/pixmaps/emotes/small/16/cool.pngbin945 -> 0 bytes
-rw-r--r--pidgin/pixmaps/emotes/small/16/glasses-cool.pngbin0 -> 1017 bytes
-rw-r--r--pidgin/pixmaps/emotes/small/16/grin.pngbin867 -> 0 bytes
-rw-r--r--pidgin/pixmaps/emotes/small/16/small.theme.in64
-rw-r--r--pidgin/pixmaps/emotes/small/16/thunder.pngbin0 -> 926 bytes
-rw-r--r--pidgin/pixmaps/pidgin.icobin25214 -> 25214 bytes
-rw-r--r--pidgin/plugins/gevolution/add_buddy_dialog.c17
-rw-r--r--pidgin/plugins/gevolution/gevo-util.c2
-rw-r--r--pidgin/plugins/gevolution/gevolution.c1
-rw-r--r--pidgin/plugins/gevolution/new_person_dialog.c5
-rw-r--r--pidgin/plugins/notify.c7
-rw-r--r--pidgin/plugins/vvconfig.c106
-rw-r--r--pidgin/plugins/xmppconsole.c2
-rw-r--r--pidgin/win32/IdleTracker/Makefile.mingw47
-rw-r--r--pidgin/win32/IdleTracker/idletrack.c188
-rw-r--r--pidgin/win32/IdleTracker/idletrack.h16
-rw-r--r--pidgin/win32/gtkwin32dep.c29
-rw-r--r--pidgin/win32/gtkwin32dep.h1
-rw-r--r--pidgin/win32/nsis/nsis_translations.desktop.in2
-rw-r--r--pidgin/win32/nsis/pidgin-installer.nsi6
-rw-r--r--pidgin/win32/winpidgin.c23
-rw-r--r--pidgin/win32/wspell.c20
-rw-r--r--po/ChangeLog6
-rw-r--r--po/af.po13
-rw-r--r--po/am.po2
-rw-r--r--po/ar.po4
-rw-r--r--po/as.po2
-rw-r--r--po/az.po4
-rw-r--r--po/be@latin.po4
-rw-r--r--po/bg.po4
-rw-r--r--po/bn.po2
-rw-r--r--po/bn_IN.po2
-rw-r--r--po/bs.po4
-rw-r--r--po/ca.po115
-rw-r--r--po/ca@valencia.po311
-rw-r--r--po/cs.po83
-rw-r--r--po/da.po4
-rw-r--r--po/de.po478
-rw-r--r--po/dz.po4
-rw-r--r--po/el.po4
-rw-r--r--po/en_AU.po16
-rw-r--r--po/en_CA.po4
-rw-r--r--po/en_GB.po2
-rw-r--r--po/eo.po2
-rw-r--r--po/es.po24
-rw-r--r--po/et.po4
-rw-r--r--po/eu.po4
-rw-r--r--po/fa.po4
-rw-r--r--po/fi.po6
-rw-r--r--po/fr.po121
-rw-r--r--po/ga.po2
-rw-r--r--po/gl.po2
-rw-r--r--po/gu.po2
-rw-r--r--po/he.po79
-rw-r--r--po/hi.po2
-rw-r--r--po/hu.po374
-rw-r--r--po/hy.po2
-rw-r--r--po/id.po4
-rw-r--r--po/it.po2
-rw-r--r--po/ja.po4
-rw-r--r--po/ka.po2
-rw-r--r--po/km.po2
-rw-r--r--po/kn.po4
-rw-r--r--po/ko.po4
-rw-r--r--po/ku.po2
-rw-r--r--po/lo.po2
-rw-r--r--po/lt.po2
-rw-r--r--po/mk.po4
-rw-r--r--po/ml.po2
-rw-r--r--po/mn.po4
-rw-r--r--po/mr.po2
-rw-r--r--po/ms_MY.po2
-rw-r--r--po/my_MM.po4
-rw-r--r--po/nb.po4
-rw-r--r--po/ne.po4
-rw-r--r--po/nl.po30
-rw-r--r--po/nn.po41
-rw-r--r--po/oc.po2
-rw-r--r--po/or.po2
-rw-r--r--po/pa.po621
-rw-r--r--po/pl.po151
-rw-r--r--po/ps.po2
-rw-r--r--po/pt.po4
-rw-r--r--po/pt_BR.po4
-rw-r--r--po/ro.po2
-rw-r--r--po/ru.po6
-rw-r--r--po/si.po2
-rw-r--r--po/sk.po4
-rw-r--r--po/sl.po129
-rw-r--r--po/sq.po2
-rw-r--r--po/sr.po4
-rw-r--r--po/sr@latin.po4
-rw-r--r--po/sv.po4
-rw-r--r--po/sw.po2
-rw-r--r--po/ta.po4
-rw-r--r--po/te.po2
-rw-r--r--po/th.po2
-rw-r--r--po/tr.po4
-rw-r--r--po/uk.po200
-rw-r--r--po/ur.po4
-rw-r--r--po/vi.po2
-rw-r--r--po/xh.po4
-rw-r--r--po/zh_CN.po4
-rw-r--r--po/zh_HK.po2
-rw-r--r--po/zh_TW.po2
-rw-r--r--share/ca-certs/Makefile.am1
-rw-r--r--share/ca-certs/ValiCert_Class_2_VA.pem19
296 files changed, 6505 insertions, 10086 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index 269c37d94c..c7593a6223 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -18,6 +18,7 @@ control system to see from where it came and who has modified it.
Copyright (C) 1998-2009 by the following:
Saleem Abdulrasool
+Jakub Adam
Dave Ahlswede
Manuel Amador
Matt Amato
diff --git a/ChangeLog b/ChangeLog
index e059217fd9..50f7dcb190 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,44 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
-version 2.7.3 (??/??/????):
+version 2.7.4 (MM/DD/YYYY):
+ General:
+ * Fix search path for Tk when compiling on Debian Squeeze. (#12465)
+
+ libpurple:
+ * Fall back to an ordinary request if a UI does not support showing a
+ request with an icon. Fixes receiving MSN file transfer requests
+ including a thumbnail in Finch.
+
+ Pidgin:
+ * Add support for the Gadu-Gadu protocol in the gevolution plugin to
+ provide Evolution integration with contacts with GG IDs. (#10709)
+ * Remap the "Set User Mood" shortcut to Control-D, which does not
+ conflict with the previous shortcut for Get Buddy Info on the
+ selected buddy.
+ * Add a plugin action menu (under Tools) for the Voice and Video
+ Settings plugin.
+
+ Finch:
+ * Add support for drop-down account options (like the SILC cipher
+ and HMAC options or the QQ protocol version).
+
+ XMPP:
+ * Unify the connection security-related settings into one dropdown.
+ * Fix a crash when multiple accounts are simultaneously performing
+ SASL authentication when built with Cyrus SASL support. (thanks
+ to Jan Kaluza) (#11560)
+ * Restore the ability to connect to XMPP servers that do not offer
+ Stream ID. (#12331)
+ * Added support for using Google's relay servers when making voice and
+ video calls to Google clients.
+
+ Yahoo/Yahoo JAPAN:
+ * Stop doing unnecessary lookups of certain alias information. This
+ solves deadlocks when a given Yahoo account has a ridiculously large
+ (>500 buddies) list and may improve login speed for those on slow
+ connections. (#12532)
+
+version 2.7.3 (08/10/2010):
General:
* Use silent build rules for automake >1.11. You can enable verbose
builds with the --disable-silent-rules configure option, or using
@@ -25,6 +63,8 @@ version 2.7.3 (??/??/????):
MSN:
* Support for web-based buddy icons, used when a buddy logs in to the
messenger on the Live website.
+ * Fix file transfers with some clients that don't support direct
+ connections (e.g., papyon, telepathy-butterfly, etc.) (#12150)
MXit:
* Fix filename for the Shocked emoticon. (#12364)
@@ -38,7 +78,9 @@ version 2.7.3 (??/??/????):
* If a buddy is offline and we see from their profile that they have
updated their avatar, request the new avatar image from the server.
* Fix a possible crash if a link is clicked while disconnected.
- * New MXit Moods and Emoticons.
+ * Unescape any escaped characters in a chatroom nickname.
+ * Add the new MXit moods and emoticons.
+ * MXit emoticons added to the small emoticon theme.
XMPP:
* Allow connecting to servers that only advertise GSSAPI and expect
@@ -67,7 +109,7 @@ version 2.7.3 (??/??/????):
version 2.7.2 (07/21/2010):
AIM and ICQ:
* Fix a crash bug related to X-Status messages that can be triggered by
- remove users. This is CVE-2010-2528.
+ remote users. This is CVE-2010-2528.
* Fix a rare crash bug caused by certain incoming SMS messages
(discovered by Jan Kaluza--thanks Jan!).
* Change HTML sent from ICQ accounts so that official ICQ clients
diff --git a/ChangeLog.API b/ChangeLog.API
index 0781bc9eda..57e616bcab 100644
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -1,6 +1,16 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
-version 2.7.3 (??/??/????):
+version 2.7.4 (MM/DD/YYYY):
+ Perl:
+ Added:
+ * Purple::BuddyList::Chat::get_components
+
+ Changed:
+ * Purple::BuddyList::Chat::new now works properly. Thanks
+ to Rafael in devel@conference.pidgin.im for reporting and
+ testing.
+
+version 2.7.3 (08/10/2010):
libpurple:
Fixed:
* purple_account_[gs]et_public_alias no longer crash when
diff --git a/NEWS b/NEWS
index 9f38398675..a31cbcb3dc 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,16 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
Our development blog is available at: http://planet.pidgin.im
+2.7.3 (08/10/2010):
+ Mark: Lots of little incremental[1] bug fixes and enhancements in this
+ release.
+
+ [1] No whales were harmed[2] during the creation of this release.
+ [2] Probably.
+
+ John: Finally got some fixes out there for you Yahoo users behind some
+ particularly annoying firewalls and proxies, among other fixes. Enjoy!
+
2.7.2 (07/21/2010):
Mark: We discovered a security issue in Pidgin 2.7.0 and 2.7.1 and
decided to release a patched version quickly. This release contains
diff --git a/configure.ac b/configure.ac
index 669c8fe549..76187238a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ AC_PREREQ([2.50])
m4_define([purple_lt_current], [7])
m4_define([purple_major_version], [2])
m4_define([purple_minor_version], [7])
-m4_define([purple_micro_version], [3])
+m4_define([purple_micro_version], [4])
m4_define([purple_version_suffix], [devel])
m4_define([purple_version],
[purple_major_version.purple_minor_version.purple_micro_version])
@@ -55,7 +55,7 @@ m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suf
m4_define([gnt_lt_current], [8])
m4_define([gnt_major_version], [2])
m4_define([gnt_minor_version], [8])
-m4_define([gnt_micro_version], [0])
+m4_define([gnt_micro_version], [1])
m4_define([gnt_version_suffix], [devel])
m4_define([gnt_version],
[gnt_major_version.gnt_minor_version.gnt_micro_version])
@@ -2248,6 +2248,7 @@ if test "$enable_tcl" = yes -a "$enable_tk" = yes; then
TKCONFIG=no
TKCONFIGDIRS="/usr/lib \
/usr/lib64 \
+ /usr/lib/tk8.5 \
/usr/lib/tk8.4 \
/usr/lib/tk8.3 \
/usr/lib/tk8.2 \
diff --git a/finch/gntaccount.c b/finch/gntaccount.c
index 4f94cfa6e6..fd4913f00d 100644
--- a/finch/gntaccount.c
+++ b/finch/gntaccount.c
@@ -236,7 +236,8 @@ save_account_cb(AccountEditDialog *dialog)
}
else if (type == PURPLE_PREF_STRING_LIST)
{
- /* TODO: */
+ gchar *value = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(entry));
+ purple_account_set_string(account, setting, value);
}
else
{
@@ -430,8 +431,26 @@ add_protocol_options(AccountEditDialog *dialog)
if (type == PURPLE_PREF_STRING_LIST)
{
- /* TODO: Use a combobox */
- /* Don't forget to append the widget to prpl_entries */
+ GntWidget *combo = gnt_combo_box_new();
+ GList *opt_iter = purple_account_option_get_list(option);
+ const char *dv = purple_account_option_get_default_list_value(option);
+ const char *active = dv;
+
+ if (account)
+ active = purple_account_get_string(account,
+ purple_account_option_get_setting(option), dv);
+
+ gnt_box_add_widget(GNT_BOX(box), combo);
+ dialog->prpl_entries = g_list_append(dialog->prpl_entries, combo);
+
+ for ( ; opt_iter; opt_iter = opt_iter->next)
+ {
+ PurpleKeyValuePair *kvp = opt_iter->data;
+ gnt_combo_box_add_data(GNT_COMBO_BOX(combo), kvp->value, kvp->key);
+
+ if (g_str_equal(kvp->value, active))
+ gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), kvp->value);
+ }
}
else
{
diff --git a/finch/gntft.c b/finch/gntft.c
index b54714520f..a587a491c6 100644
--- a/finch/gntft.c
+++ b/finch/gntft.c
@@ -383,12 +383,10 @@ finch_xfer_dialog_cancel_xfer(PurpleXfer *xfer)
return;
}
- data = FINCHXFER(xfer);
-
update_title_progress();
if (purple_xfer_is_canceled(xfer))
- status = _("Canceled");
+ status = _("Cancelled");
else
status = _("Failed");
@@ -402,7 +400,7 @@ finch_xfer_dialog_update_xfer(PurpleXfer *xfer)
char *size_str, *remaining_str;
time_t current_time;
char prog_str[5];
- double kb_sent, kb_rem;
+ double kb_sent;
double kbps = 0.0;
time_t elapsed, now;
char *kbsec;
@@ -412,7 +410,6 @@ finch_xfer_dialog_update_xfer(PurpleXfer *xfer)
now = time(NULL);
kb_sent = purple_xfer_get_bytes_sent(xfer) / 1024.0;
- kb_rem = purple_xfer_get_bytes_remaining(xfer) / 1024.0;
elapsed = (purple_xfer_get_start_time(xfer) > 0 ? now - purple_xfer_get_start_time(xfer) : 0);
kbps = (elapsed > 0 ? (kb_sent / elapsed) : 0);
diff --git a/finch/gntft.h b/finch/gntft.h
index 50cb8562b4..75e69d0bba 100644
--- a/finch/gntft.h
+++ b/finch/gntft.h
@@ -72,9 +72,9 @@ void finch_xfer_dialog_add_xfer(PurpleXfer *xfer);
void finch_xfer_dialog_remove_xfer(PurpleXfer *xfer);
/**
- * Indicate in a file transfer dialog that a transfer was canceled.
+ * Indicate in a file transfer dialog that a transfer was cancelled.
*
- * @param xfer The file transfer that was canceled.
+ * @param xfer The file transfer that was cancelled.
*/
void finch_xfer_dialog_cancel_xfer(PurpleXfer *xfer);
diff --git a/finch/libgnt/gntentry.c b/finch/libgnt/gntentry.c
index d952a1c966..29db9a61c2 100644
--- a/finch/libgnt/gntentry.c
+++ b/finch/libgnt/gntentry.c
@@ -480,8 +480,7 @@ history_search(GntBindable *bind, GList *null)
{
GntEntry *entry = GNT_ENTRY(bind);
GList *iter;
- const char *current , *pos;
- int len;
+ const char *current;
if (entry->history->prev && entry->search->needle)
current = entry->search->needle;
@@ -491,13 +490,11 @@ history_search(GntBindable *bind, GList *null)
if (!entry->histlength || !entry->history->next || !*current)
return FALSE;
- len = g_utf8_strlen(current, -1);
-
for (iter = entry->history->next; iter; iter = iter->next) {
const char *str = iter->data;
/* A more utf8-friendly version of strstr would have been better, but
* for now, this will have to do. */
- if ((pos = strstr(str, current)))
+ if (strstr(str, current) != NULL)
break;
}
diff --git a/finch/libgnt/gnttextview.c b/finch/libgnt/gnttextview.c
index 41139a9191..a9024e2d8c 100644
--- a/finch/libgnt/gnttextview.c
+++ b/finch/libgnt/gnttextview.c
@@ -711,7 +711,7 @@ int gnt_text_view_get_lines_below(GntTextView *view)
int gnt_text_view_get_lines_above(GntTextView *view)
{
int above = 0;
- GList *list = view->list;
+ GList *list;
list = g_list_nth(view->list, GNT_WIDGET(view)->priv.height);
if (!list)
return 0;
diff --git a/libpurple/account.c b/libpurple/account.c
index d69326f2de..4d500dec94 100644
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -513,6 +513,25 @@ migrate_yahoo_japan(PurpleAccount *account)
}
static void
+migrate_xmpp_encryption(PurpleAccount *account)
+{
+ /* When this is removed, nuke the "old_ssl" and "require_tls" settings */
+ if (g_str_equal(purple_account_get_protocol_id(account), "prpl-jabber")) {
+ const char *sec = purple_account_get_string(account, "connection_security", "");
+
+ if (g_str_equal("", sec)) {
+ const char *val = "require_tls";
+ if (purple_account_get_bool(account, "old_ssl", FALSE))
+ val = "old_ssl";
+ else if (!purple_account_get_bool(account, "require_tls", TRUE))
+ val = "opportunistic_tls";
+
+ purple_account_set_string(account, "connection_security", val);
+ }
+ }
+}
+
+static void
parse_settings(xmlnode *node, PurpleAccount *account)
{
const char *ui;
@@ -579,6 +598,9 @@ parse_settings(xmlnode *node, PurpleAccount *account)
/* we do this here because we need access to account settings to determine
* if we can/should migrate an old Yahoo! JAPAN account */
migrate_yahoo_japan(account);
+ /* we do this here because we need to do it before the user views the
+ * Edit Account dialog. */
+ migrate_xmpp_encryption(account);
}
static GList *
@@ -1129,7 +1151,7 @@ request_password_ok_cb(PurpleAccount *account, PurpleRequestFields *fields)
static void
request_password_cancel_cb(PurpleAccount *account, PurpleRequestFields *fields)
{
- /* Disable the account as the user has canceled connecting */
+ /* Disable the account as the user has cancelled connecting */
purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
}
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
index 3292abb9e4..291b9e156e 100644
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -1124,7 +1124,6 @@ void
purple_conv_im_start_typing_timeout(PurpleConvIm *im, int timeout)
{
PurpleConversation *conv;
- const char *name;
g_return_if_fail(im != NULL);
@@ -1132,7 +1131,6 @@ purple_conv_im_start_typing_timeout(PurpleConvIm *im, int timeout)
purple_conv_im_stop_typing_timeout(im);
conv = purple_conv_im_get_conversation(im);
- name = purple_conversation_get_name(conv);
im->typing_timeout = purple_timeout_add_seconds(timeout, reset_typing_cb, conv);
}
@@ -1520,7 +1518,6 @@ purple_conv_chat_write(PurpleConvChat *chat, const char *who, const char *messag
PurpleAccount *account;
PurpleConversation *conv;
PurpleConnection *gc;
- PurplePluginProtocolInfo *prpl_info;
g_return_if_fail(chat != NULL);
g_return_if_fail(who != NULL);
@@ -1529,7 +1526,6 @@ purple_conv_chat_write(PurpleConvChat *chat, const char *who, const char *messag
conv = purple_conv_chat_get_conversation(chat);
gc = purple_conversation_get_gc(conv);
account = purple_connection_get_account(gc);
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc));
/* Don't display this if the person who wrote it is ignored. */
if (purple_conv_chat_is_user_ignored(chat, who))
diff --git a/libpurple/debug.h b/libpurple/debug.h
index 67dd91ce7b..b90b86b99c 100644
--- a/libpurple/debug.h
+++ b/libpurple/debug.h
@@ -176,20 +176,24 @@ void purple_debug_set_verbose(gboolean verbose);
gboolean purple_debug_is_verbose(void);
/**
- * Enable or disable verbose debugging. This ordinarily should only be called
+ * Enable or disable unsafe debugging. This ordinarily should only be called
* by #purple_debug_init, but there are cases where this can be useful for
* plugins.
*
- * @param unsafe TRUE to enable verbose debugging or FALSE to disable it.
+ * @param unsafe TRUE to enable debug logging of messages that could
+ * potentially contain passwords and other sensitive information.
+ * FALSE to disable it.
*
* @since 2.6.0
*/
void purple_debug_set_unsafe(gboolean unsafe);
/**
- * Check if unsafe debugging is enabled.
+ * Check if unsafe debugging is enabled. Defaults to FALSE.
*
- * @return TRUE if verbose debugging is enabled, FALSE if it is not.
+ * @return TRUE if the debug logging of all messages is enabled, FALSE
+ * if messages that could potentially contain passwords and other
+ * sensitive information are not logged.
*
* @since 2.6.0
*/
diff --git a/libpurple/desktopitem.c b/libpurple/desktopitem.c
index df0a5b5920..d7f6d39d2d 100644
--- a/libpurple/desktopitem.c
+++ b/libpurple/desktopitem.c
@@ -330,7 +330,7 @@ my_fgets (char *buf, gsize bufsize, FILE *df)
if (c == EOF && pos == 0)
return NULL;
- buf[pos++] = '\0';
+ buf[pos] = '\0';
return buf;
}
diff --git a/libpurple/ft.c b/libpurple/ft.c
index 3828b464a6..d5711b28eb 100644
--- a/libpurple/ft.c
+++ b/libpurple/ft.c
@@ -752,6 +752,7 @@ purple_xfer_get_status(const PurpleXfer *xfer)
return xfer->status;
}
+/* FIXME: Rename with cancelled for 3.0.0. */
gboolean
purple_xfer_is_canceled(const PurpleXfer *xfer)
{
diff --git a/libpurple/ft.h b/libpurple/ft.h
index fc1209b199..216eda78a6 100644
--- a/libpurple/ft.h
+++ b/libpurple/ft.h
@@ -58,8 +58,8 @@ typedef enum
PURPLE_XFER_STATUS_ACCEPTED, /**< Receive accepted, but destination file not selected yet */
PURPLE_XFER_STATUS_STARTED, /**< purple_xfer_start has been called. */
PURPLE_XFER_STATUS_DONE, /**< The xfer completed successfully. */
- PURPLE_XFER_STATUS_CANCEL_LOCAL, /**< The xfer was canceled by us. */
- PURPLE_XFER_STATUS_CANCEL_REMOTE /**< The xfer was canceled by the other end, or we couldn't connect. */
+ PURPLE_XFER_STATUS_CANCEL_LOCAL, /**< The xfer was cancelled by us. */
+ PURPLE_XFER_STATUS_CANCEL_REMOTE /**< The xfer was cancelled by the other end, or we couldn't connect. */
} PurpleXferStatusType;
/**
@@ -304,11 +304,12 @@ const char *purple_xfer_get_remote_user(const PurpleXfer *xfer);
PurpleXferStatusType purple_xfer_get_status(const PurpleXfer *xfer);
/**
- * Returns true if the file transfer was canceled.
+ * Returns true if the file transfer was cancelled.
*
* @param xfer The file transfer.
*
- * @return Whether or not the transfer was canceled.
+ * @return Whether or not the transfer was cancelled.
+ * FIXME: This should be renamed using cancelled for 3.0.0.
*/
gboolean purple_xfer_is_canceled(const PurpleXfer *xfer);
diff --git a/libpurple/log.c b/libpurple/log.c
index 57eb87c004..e279e6406b 100644
--- a/libpurple/log.c
+++ b/libpurple/log.c
@@ -1681,7 +1681,6 @@ static GList *old_logger_list(PurpleLogType type, const char *sn, PurpleAccount
struct tm tm;
char month[4];
struct old_logger_data *data = NULL;
- char *newlog;
int logfound = 0;
int lastoff = 0;
int newlen;
@@ -1783,7 +1782,7 @@ static GList *old_logger_list(PurpleLogType type, const char *sn, PurpleAccount
}
while (fgets(buf, BUF_LONG, file)) {
- if ((newlog = strstr(buf, "---- New C"))) {
+ if (strstr(buf, "---- New C") != NULL) {
int length;
int offset;
char convostart[32];
diff --git a/libpurple/media.c b/libpurple/media.c
index 0bf35ca310..8234a89982 100644
--- a/libpurple/media.c
+++ b/libpurple/media.c
@@ -515,7 +515,8 @@ purple_media_add_session(PurpleMedia *media, PurpleMediaSession *session)
if (!media->priv->sessions) {
purple_debug_info("media", "Creating hash table for sessions\n");
- media->priv->sessions = g_hash_table_new(g_str_hash, g_str_equal);
+ media->priv->sessions = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
}
g_hash_table_insert(media->priv->sessions, g_strdup(session->id), session);
}
diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
index 3e748966a5..6b0b3e99b3 100644
--- a/libpurple/media/backend-fs2.c
+++ b/libpurple/media/backend-fs2.c
@@ -208,11 +208,7 @@ purple_media_backend_fs2_dispose(GObject *obj)
}
if (priv->participants) {
- GList *participants =
- g_hash_table_get_values(priv->participants);
- for (; participants; participants = g_list_delete_link(
- participants, participants))
- g_object_unref(participants->data);
+ g_hash_table_destroy(priv->participants);
priv->participants = NULL;
}
@@ -1425,7 +1421,8 @@ create_session(PurpleMediaBackendFs2 *self, const gchar *sess_id,
if (!priv->sessions) {
purple_debug_info("backend-fs2",
"Creating hash table for sessions\n");
- priv->sessions = g_hash_table_new(g_str_hash, g_str_equal);
+ priv->sessions = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
}
g_hash_table_insert(priv->sessions, g_strdup(session->id), session);
@@ -1461,7 +1458,7 @@ create_participant(PurpleMediaBackendFs2 *self, const gchar *name)
purple_debug_info("backend-fs2",
"Creating hash table for participants\n");
priv->participants = g_hash_table_new_full(g_str_hash,
- g_str_equal, g_free, NULL);
+ g_str_equal, g_free, g_object_unref);
}
g_hash_table_insert(priv->participants, g_strdup(name), participant);
@@ -1564,6 +1561,30 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
(GSourceFunc)src_pad_added_cb_cb, stream);
}
+static GValueArray *
+append_relay_info(GValueArray *relay_info, const gchar *ip, gint port,
+ const gchar *username, const gchar *password, const gchar *type)
+{
+ GValue value;
+ GstStructure *turn_setup = gst_structure_new("relay-info",
+ "ip", G_TYPE_STRING, ip,
+ "port", G_TYPE_UINT, port,
+ "username", G_TYPE_STRING, username,
+ "password", G_TYPE_STRING, password,
+ "relay-type", G_TYPE_STRING, type,
+ NULL);
+
+ if (turn_setup) {
+ memset(&value, 0, sizeof(GValue));
+ g_value_init(&value, GST_TYPE_STRUCTURE);
+ gst_value_set_structure(&value, turn_setup);
+ relay_info = g_value_array_append(relay_info, &value);
+ gst_structure_free(turn_setup);
+ }
+
+ return relay_info;
+}
+
static gboolean
create_stream(PurpleMediaBackendFs2 *self,
const gchar *sess_id, const gchar *who,
@@ -1584,6 +1605,18 @@ create_stream(PurpleMediaBackendFs2 *self,
PurpleMediaBackendFs2Session *session;
PurpleMediaBackendFs2Stream *stream;
FsParticipant *participant;
+ /* check if the prpl has already specified a relay-info
+ we need to do this to allow them to override when using non-standard
+ TURN modes, like Google f.ex. */
+ gboolean got_turn_from_prpl = FALSE;
+ int i;
+
+ for (i = 0 ; i < num_params ; i++) {
+ if (purple_strequal(params[i].name, "relay-info")) {
+ got_turn_from_prpl = TRUE;
+ break;
+ }
+ }
memcpy(_params, params, sizeof(GParameter) * num_params);
@@ -1603,34 +1636,24 @@ create_stream(PurpleMediaBackendFs2 *self,
++_num_params;
}
- if (turn_ip && !strcmp("nice", transmitter)) {
+ if (turn_ip && !strcmp("nice", transmitter) && !got_turn_from_prpl) {
GValueArray *relay_info = g_value_array_new(0);
- GValue value;
- gint turn_port = purple_prefs_get_int(
- "/purple/network/turn_port");
+ gint port;
const gchar *username = purple_prefs_get_string(
"/purple/network/turn_username");
const gchar *password = purple_prefs_get_string(
"/purple/network/turn_password");
- GstStructure *turn_setup = gst_structure_new("relay-info",
- "ip", G_TYPE_STRING, turn_ip,
- "port", G_TYPE_UINT, turn_port,
- "username", G_TYPE_STRING, username,
- "password", G_TYPE_STRING, password,
- NULL);
- if (!turn_setup) {
- purple_debug_error("backend-fs2",
- "Error creating relay info structure");
- return FALSE;
+ /* UDP */
+ port = purple_prefs_get_int("/purple/network/turn_port");
+ if (port > 0) {
+ relay_info = append_relay_info(relay_info, turn_ip, port, username,
+ password, "udp");
}
- memset(&value, 0, sizeof(GValue));
- g_value_init(&value, GST_TYPE_STRUCTURE);
- gst_value_set_structure(&value, turn_setup);
- relay_info = g_value_array_append(relay_info, &value);
- gst_structure_free(turn_setup);
-
+ /* should add TCP and perhaps TLS relaying options when these are
+ supported by libnice using non-google mode */
+
purple_debug_info("backend-fs2",
"Setting relay-info on new stream\n");
_params[_num_params].name = "relay-info";
@@ -1791,7 +1814,7 @@ purple_media_backend_fs2_codecs_ready(PurpleMediaBackend *self,
const gchar *sess_id)
{
PurpleMediaBackendFs2Private *priv;
- gboolean ret;
+ gboolean ret = FALSE;
g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE);
@@ -1837,15 +1860,12 @@ static GList *
purple_media_backend_fs2_get_codecs(PurpleMediaBackend *self,
const gchar *sess_id)
{
- PurpleMediaBackendFs2Private *priv;
PurpleMediaBackendFs2Session *session;
GList *fscodecs;
GList *codecs;
g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), NULL);
- priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
-
session = get_session(PURPLE_MEDIA_BACKEND_FS2(self), sess_id);
if (session == NULL)
@@ -2014,13 +2034,10 @@ purple_media_backend_fs2_set_output_volume(PurpleMediaBackendFs2 *self,
const gchar *sess_id, const gchar *who, double level)
{
#ifdef USE_VV
- PurpleMediaBackendFs2Private *priv;
GList *streams;
g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self));
- priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
-
purple_prefs_set_int("/purple/media/audio/volume/output", level);
streams = get_streams(self, sess_id, who);
diff --git a/libpurple/media/codec.c b/libpurple/media/codec.c
index 532f11d3dd..9eb68eca62 100644
--- a/libpurple/media/codec.c
+++ b/libpurple/media/codec.c
@@ -83,9 +83,11 @@ purple_media_codec_finalize(GObject *info)
PURPLE_MEDIA_CODEC_GET_PRIVATE(info);
g_free(priv->encoding_name);
for (; priv->optional_params; priv->optional_params =
- g_list_delete_link(priv->optional_params,
- priv->optional_params)) {
- g_free(priv->optional_params->data);
+ g_list_delete_link(priv->optional_params, priv->optional_params)) {
+ PurpleKeyValuePair *param = priv->optional_params->data;
+ g_free(param->key);
+ g_free(param->value);
+ g_free(param);
}
}
@@ -302,10 +304,10 @@ purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
g_free(param->key);
g_free(param->value);
- g_free(param);
priv->optional_params =
g_list_remove(priv->optional_params, param);
+ g_free(param);
}
PurpleKeyValuePair *
diff --git a/libpurple/media/codec.h b/libpurple/media/codec.h
index 771bb62d22..9262698c49 100644
--- a/libpurple/media/codec.h
+++ b/libpurple/media/codec.h
@@ -121,7 +121,8 @@ guint purple_media_codec_get_channels(PurpleMediaCodec *codec);
*
* @param The codec to get the optional parameters from.
*
- * @return The list of optional parameters.
+ * @return The list of optional parameters. The list is owned by the codec and
+ * should not be freed.
*
* @since 2.6.0
*/
diff --git a/libpurple/network.c b/libpurple/network.c
index 0d3a600a77..636cf59d6e 100644
--- a/libpurple/network.c
+++ b/libpurple/network.c
@@ -98,6 +98,7 @@ struct _PurpleNetworkListenData {
PurpleNetworkListenCallback cb;
gpointer cb_data;
UPnPMappingAddRemove *mapping_data;
+ int timer;
};
#ifdef HAVE_NETWORKMANAGER
@@ -373,6 +374,7 @@ purple_network_finish_pmp_map_cb(gpointer data)
gint *value = g_new(gint, 1);
listen_data = data;
+ listen_data->timer = 0;
/* add port mapping to hash table */
*key = purple_network_get_port_from_fd(listen_data->listenfd);
@@ -504,7 +506,7 @@ purple_network_do_listen(unsigned short port, int socket_family, int socket_type
{
purple_debug_info("network", "Skipping external port mapping.\n");
/* The pmp_map_cb does what we want to do */
- purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
+ listen_data->timer = purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
}
/* Attempt a NAT-PMP Mapping, which will return immediately */
else if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
@@ -512,7 +514,7 @@ purple_network_do_listen(unsigned short port, int socket_family, int socket_type
{
purple_debug_info("network", "Created NAT-PMP mapping on port %i\n", actual_port);
/* We want to return listen_data now, and on the next run loop trigger the cb and destroy listen_data */
- purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
+ listen_data->timer = purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
}
else
{
@@ -584,6 +586,9 @@ void purple_network_listen_cancel(PurpleNetworkListenData *listen_data)
if (listen_data->mapping_data != NULL)
purple_upnp_cancel_port_mapping(listen_data->mapping_data);
+ if (listen_data->timer > 0)
+ purple_timeout_remove(listen_data->timer);
+
g_free(listen_data);
}
@@ -1072,12 +1077,10 @@ purple_network_remove_port_mapping(gint fd)
if (protocol) {
purple_network_upnp_mapping_remove(&port, protocol, NULL);
- g_hash_table_remove(upnp_port_mappings, protocol);
} else {
protocol = g_hash_table_lookup(nat_pmp_port_mappings, &port);
if (protocol) {
purple_network_nat_pmp_mapping_remove(&port, protocol, NULL);
- g_hash_table_remove(nat_pmp_port_mappings, protocol);
}
}
}
diff --git a/libpurple/network.h b/libpurple/network.h
index 942ebd5fa4..f836d88520 100644
--- a/libpurple/network.h
+++ b/libpurple/network.h
@@ -239,7 +239,7 @@ PurpleNetworkListenData *purple_network_listen_range_family(
* by passing in the return value from either purple_network_listen()
* or purple_network_listen_range().
*
- * @param listen_data This listener attempt will be canceled and
+ * @param listen_data This listener attempt will be cancelled and
* the struct will be freed.
*/
void purple_network_listen_cancel(PurpleNetworkListenData *listen_data);
diff --git a/libpurple/plugins/idle.c b/libpurple/plugins/idle.c
index 8d3c72e9ca..0860dafa82 100644
--- a/libpurple/plugins/idle.c
+++ b/libpurple/plugins/idle.c
@@ -110,9 +110,6 @@ idle_all_action_ok(void *ignored, PurpleRequestFields *fields)
for(iter = list; iter; iter = iter->next) {
acct = (PurpleAccount *)(iter->data);
- if(acct)
- prpl_id = purple_account_get_protocol_id(acct);
-
if(acct && idleable_filter(acct)) {
purple_debug_misc("idle", "Idling %s.\n",
purple_account_get_username(acct));
diff --git a/libpurple/plugins/perl/common/BuddyList.xs b/libpurple/plugins/perl/common/BuddyList.xs
index 0f68d872a7..65f10184f0 100644
--- a/libpurple/plugins/perl/common/BuddyList.xs
+++ b/libpurple/plugins/perl/common/BuddyList.xs
@@ -2,6 +2,13 @@
#include "module.h"
#include "../perl-handlers.h"
+static void
+chat_components_foreach(gpointer key, gpointer value, gpointer user_data)
+{
+ HV *hv = user_data;
+ hv_store(hv, key, strlen(key), newSVpv(value, 0), 0);
+}
+
MODULE = Purple::BuddyList PACKAGE = Purple PREFIX = purple_
PROTOTYPES: ENABLE
@@ -331,6 +338,19 @@ const char *
purple_chat_get_name(chat)
Purple::BuddyList::Chat chat
+HV *
+purple_chat_get_components(chat)
+ Purple::BuddyList::Chat chat
+INIT:
+ HV * t_HV;
+ GHashTable * t_GHash;
+CODE:
+ t_GHash = purple_chat_get_components(chat);
+ RETVAL = t_HV = newHV();
+ g_hash_table_foreach(t_GHash, chat_components_foreach, t_HV);
+OUTPUT:
+ RETVAL
+
Purple::BuddyList::Chat
purple_chat_new(account, alias, components)
Purple::Account account
@@ -345,14 +365,14 @@ INIT:
char *t_key, *t_value;
CODE:
t_HV = (HV *)SvRV(components);
- t_GHash = g_hash_table_new(g_str_hash, g_str_equal);
+ t_GHash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
for (t_HE = hv_iternext(t_HV); t_HE != NULL; t_HE = hv_iternext(t_HV) ) {
t_key = hv_iterkey(t_HE, &len);
t_SV = *hv_fetch(t_HV, t_key, len, 0);
t_value = SvPVutf8_nolen(t_SV);
- g_hash_table_insert(t_GHash, t_key, t_value);
+ g_hash_table_insert(t_GHash, g_strdup(t_key), g_strdup(t_value));
}
RETVAL = purple_chat_new(account, alias, t_GHash);
diff --git a/libpurple/plugins/perl/common/Server.xs b/libpurple/plugins/perl/common/Server.xs
index 4fe496f746..13e2aefcbf 100644
--- a/libpurple/plugins/perl/common/Server.xs
+++ b/libpurple/plugins/perl/common/Server.xs
@@ -144,6 +144,7 @@ CODE:
g_hash_table_insert(t_GHash, t_key, t_value);
}
serv_join_chat(conn, t_GHash);
+ g_hash_table_destroy(t_GHash);
void
serv_move_buddy(buddy, group1, group2)
diff --git a/libpurple/plugins/signals-test.c b/libpurple/plugins/signals-test.c
index 5e64015a4c..2992d4dc15 100644
--- a/libpurple/plugins/signals-test.c
+++ b/libpurple/plugins/signals-test.c
@@ -592,12 +592,12 @@ ft_send_start_cb(PurpleXfer *xfer, gpointer data) {
static void
ft_recv_cancel_cb(PurpleXfer *xfer, gpointer data) {
- purple_debug_misc("signals test", "file receive canceled\n");
+ purple_debug_misc("signals test", "file receive cancelled\n");
}
static void
ft_send_cancel_cb(PurpleXfer *xfer, gpointer data) {
- purple_debug_misc("signals test", "file send canceled\n");
+ purple_debug_misc("signals test", "file send cancelled\n");
}
static void
diff --git a/libpurple/plugins/tcl/tcl_cmd.c b/libpurple/plugins/tcl/tcl_cmd.c
index 606dc36648..fc0d1c3bb9 100644
--- a/libpurple/plugins/tcl/tcl_cmd.c
+++ b/libpurple/plugins/tcl/tcl_cmd.c
@@ -125,7 +125,7 @@ static PurpleCmdRet tcl_cmd_callback(PurpleConversation *conv, const gchar *cmd,
gchar **args, gchar **errors,
struct tcl_cmd_handler *handler)
{
- int retval, error, i;
+ int retval, i;
Tcl_Obj *command, *arg, *tclargs, *result;
command = Tcl_NewListObj(0, NULL);
@@ -153,8 +153,7 @@ static PurpleCmdRet tcl_cmd_callback(PurpleConversation *conv, const gchar *cmd,
}
Tcl_ListObjAppendElement(handler->interp, command, tclargs);
- if ((error = Tcl_EvalObjEx(handler->interp, command,
- TCL_EVAL_GLOBAL)) != TCL_OK) {
+ if (Tcl_EvalObjEx(handler->interp, command, TCL_EVAL_GLOBAL) != TCL_OK) {
gchar *errorstr;
errorstr = g_strdup_printf("error evaluating callback: %s\n",
@@ -164,8 +163,8 @@ static PurpleCmdRet tcl_cmd_callback(PurpleConversation *conv, const gchar *cmd,
retval = PURPLE_CMD_RET_FAILED;
} else {
result = Tcl_GetObjResult(handler->interp);
- if ((error = Tcl_GetIntFromObj(handler->interp, result,
- &retval)) != TCL_OK) {
+ if (Tcl_GetIntFromObj(handler->interp, result,
+ &retval) != TCL_OK) {
gchar *errorstr;
errorstr = g_strdup_printf("Error retreiving procedure result: %s\n",
diff --git a/libpurple/plugins/tcl/tcl_signals.c b/libpurple/plugins/tcl/tcl_signals.c
index 98c27d8294..c3d6d0fddf 100644
--- a/libpurple/plugins/tcl/tcl_signals.c
+++ b/libpurple/plugins/tcl/tcl_signals.c
@@ -160,7 +160,7 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
{
GString *name, *val;
PurpleBlistNode *node;
- int error, i;
+ int i;
void *retval = NULL;
Tcl_Obj *cmd, *arg, *result;
void **vals; /* Used for inout parameters */
@@ -335,7 +335,7 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
}
/* Call the friggin' procedure already */
- if ((error = Tcl_EvalObjEx(handler->interp, cmd, TCL_EVAL_GLOBAL)) != TCL_OK) {
+ if (Tcl_EvalObjEx(handler->interp, cmd, TCL_EVAL_GLOBAL) != TCL_OK) {
purple_debug(PURPLE_DEBUG_ERROR, "tcl", "error evaluating callback: %s\n",
Tcl_GetString(Tcl_GetObjResult(handler->interp)));
} else {
@@ -345,7 +345,7 @@ static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handle
if (purple_value_get_type(handler->returntype) == PURPLE_TYPE_STRING) {
retval = (void *)g_strdup(Tcl_GetString(result));
} else {
- if ((error = Tcl_GetIntFromObj(handler->interp, result, (int *)&retval)) != TCL_OK) {
+ if (Tcl_GetIntFromObj(handler->interp, result, (int *)&retval) != TCL_OK) {
purple_debug(PURPLE_DEBUG_ERROR, "tcl", "Error retrieving procedure result: %s\n",
Tcl_GetString(Tcl_GetObjResult(handler->interp)));
retval = NULL;
diff --git a/libpurple/prefs.c b/libpurple/prefs.c
index 5ef0c07c08..f02d2d18da 100644
--- a/libpurple/prefs.c
+++ b/libpurple/prefs.c
@@ -506,7 +506,6 @@ pref_full_name(struct purple_pref *pref)
return g_strdup("/");
name = g_string_new(pref->name);
- parent = pref->parent;
for(parent = pref->parent; parent && parent->name; parent = parent->parent) {
name = g_string_prepend_c(name, '/');
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
index cb5163a82e..8745ceddbe 100644
--- a/libpurple/protocols/bonjour/bonjour.c
+++ b/libpurple/protocols/bonjour/bonjour.c
@@ -206,18 +206,12 @@ bonjour_set_status(PurpleAccount *account, PurpleStatus *status)
{
PurpleConnection *gc;
BonjourData *bd;
- gboolean disconnected;
- PurpleStatusType *type;
- int primitive;
PurplePresence *presence;
const char *message, *bonjour_status;
gchar *stripped;
gc = purple_account_get_connection(account);
bd = gc->proto_data;
- disconnected = purple_account_is_disconnected(account);
- type = purple_status_get_type(status);
- primitive = purple_status_type_get_primitive(type);
presence = purple_account_get_presence(account);
message = purple_status_get_attr_string(status, "message");
diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c
index 5e73c4c887..7b5496faef 100644
--- a/libpurple/protocols/bonjour/jabber.c
+++ b/libpurple/protocols/bonjour/jabber.c
@@ -1273,7 +1273,6 @@ check_if_blocked(PurpleBuddy *pb)
static void
xep_iq_parse(xmlnode *packet, PurpleBuddy *pb)
{
- xmlnode *child;
PurpleAccount *account;
PurpleConnection *gc;
@@ -1283,7 +1282,7 @@ xep_iq_parse(xmlnode *packet, PurpleBuddy *pb)
account = purple_buddy_get_account(pb);
gc = purple_account_get_connection(account);
- if ((child = xmlnode_get_child(packet, "si")) || (child = xmlnode_get_child(packet, "error")))
+ if (xmlnode_get_child(packet, "si") != NULL || xmlnode_get_child(packet, "error") != NULL)
xep_si_parse(gc, packet, pb);
else
xep_bytestreams_parse(gc, packet, pb);
diff --git a/libpurple/protocols/bonjour/mdns_avahi.c b/libpurple/protocols/bonjour/mdns_avahi.c
index 7ef358cbea..83d094ad82 100644
--- a/libpurple/protocols/bonjour/mdns_avahi.c
+++ b/libpurple/protocols/bonjour/mdns_avahi.c
@@ -115,7 +115,6 @@ _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtoco
AvahiStringList *l;
size_t size;
char *key, *value;
- int ret;
char ip[AVAHI_ADDRESS_STR_MAX];
AvahiBuddyImplData *b_impl;
AvahiSvcResolverData *rd;
@@ -202,7 +201,7 @@ _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtoco
/* Obtain the parameters from the text_record */
clear_bonjour_buddy_values(bb);
for(l = txt; l != NULL; l = l->next) {
- if ((ret = avahi_string_list_get_pair(l, &key, &value, &size)) < 0)
+ if (avahi_string_list_get_pair(l, &key, &value, &size) < 0)
continue;
set_bonjour_buddy_value(bb, key, value, size);
/* TODO: Since we're using the glib allocator, I think we
diff --git a/libpurple/protocols/jabber/Makefile.am b/libpurple/protocols/jabber/Makefile.am
index ff88986a82..f376b71d21 100644
--- a/libpurple/protocols/jabber/Makefile.am
+++ b/libpurple/protocols/jabber/Makefile.am
@@ -26,8 +26,20 @@ JABBERSOURCES = \
data.h \
disco.c \
disco.h \
- google.c \
- google.h \
+ google/gmail.c \
+ google/gmail.h \
+ google/google.c \
+ google/google.h \
+ google/google_presence.c \
+ google/google_presence.h \
+ google/google_roster.c \
+ google/google_roster.h \
+ google/google_session.c \
+ google/google_session.h \
+ google/jingleinfo.c \
+ google/jingleinfo.h \
+ google/relay.c \
+ google/relay.h \
ibb.c \
ibb.h \
iq.c \
@@ -98,7 +110,10 @@ else
st =
pkg_LTLIBRARIES = libjabber.la libxmpp.la
libjabber_la_SOURCES = $(JABBERSOURCES)
-libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)
+libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\
+ $(FARSIGHT_LIBS) \
+ $(GSTREAMER_LIBS) \
+ $(GSTINTERFACES_LIBS)
libxmpp_la_SOURCES = libxmpp.c
libxmpp_la_LIBADD = libjabber.la
@@ -111,4 +126,7 @@ AM_CPPFLAGS = \
$(DEBUG_CFLAGS) \
$(GLIB_CFLAGS) \
$(IDN_CFLAGS) \
- $(LIBXML_CFLAGS)
+ $(LIBXML_CFLAGS) \
+ $(FARSIGHT_CFLAGS) \
+ $(GSTREAMER_CFLAGS) \
+ $(GSTINTERFACES_CFLAGS)
diff --git a/libpurple/protocols/jabber/Makefile.mingw b/libpurple/protocols/jabber/Makefile.mingw
index c648d42fd4..4e9f9f9db6 100644
--- a/libpurple/protocols/jabber/Makefile.mingw
+++ b/libpurple/protocols/jabber/Makefile.mingw
@@ -55,7 +55,13 @@ C_SRC = \
chat.c \
data.c \
disco.c \
- google.c \
+ google/gmail.c \
+ google/google.c \
+ google/google_presence.c \
+ google/google_roster.c \
+ google/google_session.c \
+ google/jingleinfo.c \
+ google/relay.c \
ibb.c \
iq.c \
jabber.c \
diff --git a/libpurple/protocols/jabber/auth.c b/libpurple/protocols/jabber/auth.c
index 933ff4711b..4ecbe55608 100644
--- a/libpurple/protocols/jabber/auth.c
+++ b/libpurple/protocols/jabber/auth.c
@@ -123,7 +123,7 @@ auth_no_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields)
if (!PURPLE_CONNECTION_IS_VALID(gc))
return;
- /* Disable the account as the user has canceled connecting */
+ /* Disable the account as the user has cancelled connecting */
purple_account_set_enabled(purple_connection_get_account(gc), purple_core_get_ui(), FALSE);
}
#endif
@@ -251,7 +251,8 @@ static void auth_old_cb(JabberStream *js, const char *from,
g_free(msg);
} else if (type == JABBER_IQ_RESULT) {
query = xmlnode_get_child(packet, "query");
- if(js->stream_id && xmlnode_get_child(query, "digest")) {
+ if (js->stream_id && *js->stream_id &&
+ xmlnode_get_child(query, "digest")) {
char *s, *hash;
iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
@@ -269,8 +270,10 @@ static void auth_old_cb(JabberStream *js, const char *from,
g_free(s);
jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
jabber_iq_send(iq);
-
- } else if(js->stream_id && (x = xmlnode_get_child(query, "crammd5"))) {
+ } else if ((x = xmlnode_get_child(query, "crammd5"))) {
+ /* For future reference, this appears to be a custom OS X extension
+ * to non-SASL authentication.
+ */
const char *challenge;
gchar digest[33];
PurpleCipherContext *hmac;
@@ -340,7 +343,8 @@ void jabber_auth_start_old(JabberStream *js)
* is requiring SSL/TLS, we need to enforce it.
*/
if (!jabber_stream_is_ssl(js) &&
- purple_account_get_bool(account, "require_tls", JABBER_DEFAULT_REQUIRE_TLS)) {
+ g_str_equal("require_tls",
+ purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
purple_connection_error_reason(js->gc,
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("You require encryption, but it is not available on this server."));
diff --git a/libpurple/protocols/jabber/auth_cyrus.c b/libpurple/protocols/jabber/auth_cyrus.c
index 33617e3dd4..b022a177c4 100644
--- a/libpurple/protocols/jabber/auth_cyrus.c
+++ b/libpurple/protocols/jabber/auth_cyrus.c
@@ -94,7 +94,6 @@ static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secr
PurpleAccount *account;
const char *pw;
size_t len;
- static sasl_secret_t *x = NULL;
account = purple_connection_get_account(js->gc);
pw = purple_account_get_password(account);
@@ -103,15 +102,16 @@ static int jabber_sasl_cb_secret(sasl_conn_t *conn, void *ctx, int id, sasl_secr
return SASL_BADPARAM;
len = strlen(pw);
- x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);
-
- if (!x)
+ /* Not an off-by-one because sasl_secret_t defines char data[1] */
+ /* TODO: This can probably be moved to glib's allocator */
+ js->sasl_secret = malloc(sizeof(sasl_secret_t) + len);
+ if (!js->sasl_secret)
return SASL_NOMEM;
- x->len = len;
- strcpy((char*)x->data, pw);
+ js->sasl_secret->len = len;
+ strcpy((char*)js->sasl_secret->data, pw);
- *secret = x;
+ *secret = js->sasl_secret;
return SASL_OK;
}
@@ -176,7 +176,7 @@ auth_no_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields)
account = purple_connection_get_account(gc);
js = purple_connection_get_protocol_data(gc);
- /* Disable the account as the user has canceled connecting */
+ /* Disable the account as the user has cancelled connecting */
purple_account_set_enabled(account, purple_core_get_ui(), FALSE);
}
diff --git a/libpurple/protocols/jabber/bosh.c b/libpurple/protocols/jabber/bosh.c
index 8a4fb93714..f0116a5418 100644
--- a/libpurple/protocols/jabber/bosh.c
+++ b/libpurple/protocols/jabber/bosh.c
@@ -711,11 +711,10 @@ jabber_bosh_http_connection_process(PurpleHTTPConnection *conn)
/* Make sure Content-Length is in headers, not body */
if (content_length && (!end_of_headers || content_length < end_of_headers)) {
const char *sep;
- const char *eol;
int len;
if ((sep = strstr(content_length, ": ")) == NULL ||
- (eol = strstr(sep, "\r\n")) == NULL)
+ strstr(sep, "\r\n") == NULL)
/*
* The packet ends in the middle of the Content-Length line.
* We'll try again later when we have more.
diff --git a/libpurple/protocols/jabber/buddy.c b/libpurple/protocols/jabber/buddy.c
index 85b8eefee4..0266f8d2d1 100644
--- a/libpurple/protocols/jabber/buddy.c
+++ b/libpurple/protocols/jabber/buddy.c
@@ -38,7 +38,7 @@
#include "xdata.h"
#include "pep.h"
#include "adhoccommands.h"
-#include "google.h"
+#include "google/google.h"
typedef struct {
long idle_seconds;
diff --git a/libpurple/protocols/jabber/chat.c b/libpurple/protocols/jabber/chat.c
index 6eefd9e404..380d5634a5 100644
--- a/libpurple/protocols/jabber/chat.c
+++ b/libpurple/protocols/jabber/chat.c
@@ -173,8 +173,10 @@ void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
xmlnode_set_namespace(x, "http://jabber.org/protocol/muc#user");
invite = xmlnode_new_child(x, "invite");
xmlnode_set_attrib(invite, "to", name);
- body = xmlnode_new_child(invite, "reason");
- xmlnode_insert_data(body, msg, -1);
+ if (msg) {
+ body = xmlnode_new_child(invite, "reason");
+ xmlnode_insert_data(body, msg, -1);
+ }
} else {
xmlnode_set_attrib(message, "to", name);
/*
@@ -184,14 +186,17 @@ void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
*
* Left here for compatibility.
*/
- body = xmlnode_new_child(message, "body");
- xmlnode_insert_data(body, msg, -1);
+ if (msg) {
+ body = xmlnode_new_child(message, "body");
+ xmlnode_insert_data(body, msg, -1);
+ }
x = xmlnode_new_child(message, "x");
xmlnode_set_attrib(x, "jid", room_jid);
/* The better place for it! XEP-0249 style. */
- xmlnode_set_attrib(x, "reason", msg);
+ if (msg)
+ xmlnode_set_attrib(x, "reason", msg);
xmlnode_set_namespace(x, "jabber:x:conference");
}
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
index 8a3ae80bcb..5803ca7d2d 100644
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -30,7 +30,9 @@
#include "adhoccommands.h"
#include "buddy.h"
#include "disco.h"
-#include "google.h"
+#include "google/google.h"
+#include "google/gmail.h"
+#include "google/jingleinfo.h"
#include "iq.h"
#include "jabber.h"
#include "jingle/jingle.h"
@@ -604,7 +606,7 @@ jabber_disco_server_items_result_cb(JabberStream *js, const char *from,
/* we don't actually care about the specific nodes,
* so we won't query them */
- if((node = xmlnode_get_attrib(child, "node")))
+ if(xmlnode_get_attrib(child, "node") != NULL)
continue;
iq = jabber_iq_new_query(js, JABBER_IQ_GET, NS_DISCO_INFO);
diff --git a/libpurple/protocols/jabber/google.c b/libpurple/protocols/jabber/google.c
deleted file mode 100644
index 1d843fe701..0000000000
--- a/libpurple/protocols/jabber/google.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-/**
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-#include "mediamanager.h"
-#include "util.h"
-#include "privacy.h"
-#include "dnsquery.h"
-#include "network.h"
-
-#include "buddy.h"
-#include "google.h"
-#include "jabber.h"
-#include "presence.h"
-#include "roster.h"
-#include "iq.h"
-#include "chat.h"
-
-#include "jingle/jingle.h"
-
-#ifdef USE_VV
-
-typedef struct {
- char *id;
- char *initiator;
-} GoogleSessionId;
-
-typedef enum {
- UNINIT,
- SENT_INITIATE,
- RECEIVED_INITIATE,
- IN_PRORESS,
- TERMINATED
-} GoogleSessionState;
-
-typedef struct {
- GoogleSessionId id;
- GoogleSessionState state;
- PurpleMedia *media;
- JabberStream *js;
- char *remote_jid;
- gboolean video;
-} GoogleSession;
-
-static gboolean
-google_session_id_equal(gconstpointer a, gconstpointer b)
-{
- GoogleSessionId *c = (GoogleSessionId*)a;
- GoogleSessionId *d = (GoogleSessionId*)b;
-
- return !strcmp(c->id, d->id) && !strcmp(c->initiator, d->initiator);
-}
-
-static void
-google_session_destroy(GoogleSession *session)
-{
- g_free(session->id.id);
- g_free(session->id.initiator);
- g_free(session->remote_jid);
- g_free(session);
-}
-
-static xmlnode *
-google_session_create_xmlnode(GoogleSession *session, const char *type)
-{
- xmlnode *node = xmlnode_new("session");
- xmlnode_set_namespace(node, NS_GOOGLE_SESSION);
- xmlnode_set_attrib(node, "id", session->id.id);
- xmlnode_set_attrib(node, "initiator", session->id.initiator);
- xmlnode_set_attrib(node, "type", type);
- return node;
-}
-
-static void
-google_session_send_candidates(PurpleMedia *media, gchar *session_id,
- gchar *participant, GoogleSession *session)
-{
- GList *candidates = purple_media_get_local_candidates(
- session->media, session_id, session->remote_jid), *iter;
- PurpleMediaCandidate *transport;
- gboolean video = FALSE;
-
- if (!strcmp(session_id, "google-video"))
- video = TRUE;
-
- for (iter = candidates; iter; iter = iter->next) {
- JabberIq *iq;
- gchar *ip, *port, *username, *password;
- gchar pref[16];
- PurpleMediaCandidateType type;
- xmlnode *sess;
- xmlnode *candidate;
- guint component_id;
- transport = PURPLE_MEDIA_CANDIDATE(iter->data);
- component_id = purple_media_candidate_get_component_id(
- transport);
-
- iq = jabber_iq_new(session->js, JABBER_IQ_SET);
- sess = google_session_create_xmlnode(session, "candidates");
- xmlnode_insert_child(iq->node, sess);
- xmlnode_set_attrib(iq->node, "to", session->remote_jid);
-
- candidate = xmlnode_new("candidate");
-
- ip = purple_media_candidate_get_ip(transport);
- port = g_strdup_printf("%d",
- purple_media_candidate_get_port(transport));
- g_ascii_dtostr(pref, 16,
- purple_media_candidate_get_priority(transport) / 1000.0);
- username = purple_media_candidate_get_username(transport);
- password = purple_media_candidate_get_password(transport);
- type = purple_media_candidate_get_candidate_type(transport);
-
- xmlnode_set_attrib(candidate, "address", ip);
- xmlnode_set_attrib(candidate, "port", port);
- xmlnode_set_attrib(candidate, "name",
- component_id == PURPLE_MEDIA_COMPONENT_RTP ?
- video ? "video_rtp" : "rtp" :
- component_id == PURPLE_MEDIA_COMPONENT_RTCP ?
- video ? "video_rtcp" : "rtcp" : "none");
- xmlnode_set_attrib(candidate, "username", username);
- /*
- * As of this writing, Farsight 2 in Google compatibility
- * mode doesn't provide a password. The Gmail client
- * requires this to be set.
- */
- xmlnode_set_attrib(candidate, "password",
- password != NULL ? password : "");
- xmlnode_set_attrib(candidate, "preference", pref);
- xmlnode_set_attrib(candidate, "protocol",
- purple_media_candidate_get_protocol(transport)
- == PURPLE_MEDIA_NETWORK_PROTOCOL_UDP ?
- "udp" : "tcp");
- xmlnode_set_attrib(candidate, "type", type ==
- PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "local" :
- type ==
- PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "stun" :
- type ==
- PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" :
- NULL);
- xmlnode_set_attrib(candidate, "generation", "0");
- xmlnode_set_attrib(candidate, "network", "0");
- xmlnode_insert_child(sess, candidate);
-
- g_free(ip);
- g_free(port);
- g_free(username);
- g_free(password);
-
- jabber_iq_send(iq);
- }
- purple_media_candidate_list_free(candidates);
-}
-
-static void
-google_session_ready(GoogleSession *session)
-{
- PurpleMedia *media = session->media;
- if (purple_media_codecs_ready(media, NULL) &&
- purple_media_candidates_prepared(media, NULL, NULL)) {
- gchar *me = g_strdup_printf("%s@%s/%s",
- session->js->user->node,
- session->js->user->domain,
- session->js->user->resource);
- JabberIq *iq;
- xmlnode *sess, *desc, *payload;
- GList *codecs, *iter;
- gboolean is_initiator = !strcmp(session->id.initiator, me);
-
- if (!is_initiator &&
- !purple_media_accepted(media, NULL, NULL)) {
- g_free(me);
- return;
- }
-
- iq = jabber_iq_new(session->js, JABBER_IQ_SET);
-
- if (is_initiator) {
- xmlnode_set_attrib(iq->node, "to", session->remote_jid);
- xmlnode_set_attrib(iq->node, "from", session->id.initiator);
- sess = google_session_create_xmlnode(session, "initiate");
- } else {
- google_session_send_candidates(session->media,
- "google-voice", session->remote_jid,
- session);
- google_session_send_candidates(session->media,
- "google-video", session->remote_jid,
- session);
- xmlnode_set_attrib(iq->node, "to", session->remote_jid);
- xmlnode_set_attrib(iq->node, "from", me);
- sess = google_session_create_xmlnode(session, "accept");
- }
- xmlnode_insert_child(iq->node, sess);
- desc = xmlnode_new_child(sess, "description");
- if (session->video)
- xmlnode_set_namespace(desc, NS_GOOGLE_SESSION_VIDEO);
- else
- xmlnode_set_namespace(desc, NS_GOOGLE_SESSION_PHONE);
-
- codecs = purple_media_get_codecs(media, "google-video");
-
- for (iter = codecs; iter; iter = g_list_next(iter)) {
- PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data;
- gchar *id = g_strdup_printf("%d",
- purple_media_codec_get_id(codec));
- gchar *encoding_name =
- purple_media_codec_get_encoding_name(codec);
- payload = xmlnode_new_child(desc, "payload-type");
- xmlnode_set_attrib(payload, "id", id);
- xmlnode_set_attrib(payload, "name", encoding_name);
- xmlnode_set_attrib(payload, "width", "320");
- xmlnode_set_attrib(payload, "height", "200");
- xmlnode_set_attrib(payload, "framerate", "30");
- g_free(encoding_name);
- g_free(id);
- }
- purple_media_codec_list_free(codecs);
-
- codecs = purple_media_get_codecs(media, "google-voice");
-
- for (iter = codecs; iter; iter = g_list_next(iter)) {
- PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data;
- gchar *id = g_strdup_printf("%d",
- purple_media_codec_get_id(codec));
- gchar *encoding_name =
- purple_media_codec_get_encoding_name(codec);
- gchar *clock_rate = g_strdup_printf("%d",
- purple_media_codec_get_clock_rate(codec));
- payload = xmlnode_new_child(desc, "payload-type");
- if (session->video)
- xmlnode_set_namespace(payload, NS_GOOGLE_SESSION_PHONE);
- xmlnode_set_attrib(payload, "id", id);
- /*
- * Hack to make Gmail accept speex as the codec.
- * It shouldn't have to be case sensitive.
- */
- if (purple_strequal(encoding_name, "SPEEX"))
- xmlnode_set_attrib(payload, "name", "speex");
- else
- xmlnode_set_attrib(payload, "name", encoding_name);
- xmlnode_set_attrib(payload, "clockrate", clock_rate);
- g_free(clock_rate);
- g_free(encoding_name);
- g_free(id);
- }
- purple_media_codec_list_free(codecs);
-
- jabber_iq_send(iq);
-
- if (is_initiator) {
- google_session_send_candidates(session->media,
- "google-voice", session->remote_jid,
- session);
- google_session_send_candidates(session->media,
- "google-video", session->remote_jid,
- session);
- }
-
- g_signal_handlers_disconnect_by_func(G_OBJECT(session->media),
- G_CALLBACK(google_session_ready), session);
- }
-}
-
-static void
-google_session_state_changed_cb(PurpleMedia *media, PurpleMediaState state,
- gchar *sid, gchar *name, GoogleSession *session)
-{
- if (sid == NULL && name == NULL) {
- if (state == PURPLE_MEDIA_STATE_END) {
- google_session_destroy(session);
- }
- }
-}
-
-static void
-google_session_stream_info_cb(PurpleMedia *media, PurpleMediaInfoType type,
- gchar *sid, gchar *name, gboolean local,
- GoogleSession *session)
-{
- if (sid != NULL || name != NULL)
- return;
-
- if (type == PURPLE_MEDIA_INFO_HANGUP) {
- xmlnode *sess;
- JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET);
-
- xmlnode_set_attrib(iq->node, "to", session->remote_jid);
- sess = google_session_create_xmlnode(session, "terminate");
- xmlnode_insert_child(iq->node, sess);
-
- jabber_iq_send(iq);
- } else if (type == PURPLE_MEDIA_INFO_REJECT) {
- xmlnode *sess;
- JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET);
-
- xmlnode_set_attrib(iq->node, "to", session->remote_jid);
- sess = google_session_create_xmlnode(session, "reject");
- xmlnode_insert_child(iq->node, sess);
-
- jabber_iq_send(iq);
- } else if (type == PURPLE_MEDIA_INFO_ACCEPT && local == TRUE) {
- google_session_ready(session);
- }
-}
-
-static GParameter *
-jabber_google_session_get_params(JabberStream *js, guint *num)
-{
- guint num_params;
- GParameter *params = jingle_get_params(js, &num_params);
- GParameter *new_params = g_new0(GParameter, num_params + 1);
-
- memcpy(new_params, params, sizeof(GParameter) * num_params);
-
- purple_debug_info("jabber", "setting Google jingle compatibility param\n");
- new_params[num_params].name = "compatibility-mode";
- g_value_init(&new_params[num_params].value, G_TYPE_UINT);
- g_value_set_uint(&new_params[num_params].value, 1); /* NICE_COMPATIBILITY_GOOGLE */
-
- g_free(params);
- *num = num_params + 1;
- return new_params;
-}
-
-
-gboolean
-jabber_google_session_initiate(JabberStream *js, const gchar *who, PurpleMediaSessionType type)
-{
- GoogleSession *session;
- JabberBuddy *jb;
- JabberBuddyResource *jbr;
- gchar *jid;
- GParameter *params;
- guint num_params;
-
- /* construct JID to send to */
- jb = jabber_buddy_find(js, who, FALSE);
- if (!jb) {
- purple_debug_error("jingle-rtp",
- "Could not find Jabber buddy\n");
- return FALSE;
- }
- jbr = jabber_buddy_find_resource(jb, NULL);
- if (!jbr) {
- purple_debug_error("jingle-rtp",
- "Could not find buddy's resource\n");
- }
-
- if ((strchr(who, '/') == NULL) && jbr && (jbr->name != NULL)) {
- jid = g_strdup_printf("%s/%s", who, jbr->name);
- } else {
- jid = g_strdup(who);
- }
-
- session = g_new0(GoogleSession, 1);
- session->id.id = jabber_get_next_id(js);
- session->id.initiator = g_strdup_printf("%s@%s/%s", js->user->node,
- js->user->domain, js->user->resource);
- session->state = SENT_INITIATE;
- session->js = js;
- session->remote_jid = jid;
-
- if (type & PURPLE_MEDIA_VIDEO)
- session->video = TRUE;
-
- session->media = purple_media_manager_create_media(
- purple_media_manager_get(),
- purple_connection_get_account(js->gc),
- "fsrtpconference", session->remote_jid, TRUE);
-
- purple_media_set_prpl_data(session->media, session);
-
- g_signal_connect_swapped(G_OBJECT(session->media),
- "candidates-prepared",
- G_CALLBACK(google_session_ready), session);
- g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed",
- G_CALLBACK(google_session_ready), session);
- g_signal_connect(G_OBJECT(session->media), "state-changed",
- G_CALLBACK(google_session_state_changed_cb), session);
- g_signal_connect(G_OBJECT(session->media), "stream-info",
- G_CALLBACK(google_session_stream_info_cb), session);
-
- params = jabber_google_session_get_params(js, &num_params);
-
- if (purple_media_add_stream(session->media, "google-voice",
- session->remote_jid, PURPLE_MEDIA_AUDIO,
- TRUE, "nice", num_params, params) == FALSE ||
- (session->video && purple_media_add_stream(
- session->media, "google-video",
- session->remote_jid, PURPLE_MEDIA_VIDEO,
- TRUE, "nice", num_params, params) == FALSE)) {
- purple_media_error(session->media, "Error adding stream.");
- purple_media_end(session->media, NULL, NULL);
- g_free(params);
- return FALSE;
- }
-
- g_free(params);
-
- return (session->media != NULL) ? TRUE : FALSE;
-}
-
-static gboolean
-google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
-{
- JabberIq *result;
- GList *codecs = NULL, *video_codecs = NULL;
- xmlnode *desc_element, *codec_element;
- PurpleMediaCodec *codec;
- const char *xmlns;
- GParameter *params;
- guint num_params;
-
- if (session->state != UNINIT) {
- purple_debug_error("jabber", "Received initiate for active session.\n");
- return FALSE;
- }
-
- desc_element = xmlnode_get_child(sess, "description");
- xmlns = xmlnode_get_namespace(desc_element);
-
- if (purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE))
- session->video = FALSE;
- else if (purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO))
- session->video = TRUE;
- else {
- purple_debug_error("jabber", "Received initiate with "
- "invalid namespace %s.\n", xmlns);
- return FALSE;
- }
-
- session->media = purple_media_manager_create_media(
- purple_media_manager_get(),
- purple_connection_get_account(js->gc),
- "fsrtpconference", session->remote_jid, FALSE);
-
- purple_media_set_prpl_data(session->media, session);
-
- g_signal_connect_swapped(G_OBJECT(session->media),
- "candidates-prepared",
- G_CALLBACK(google_session_ready), session);
- g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed",
- G_CALLBACK(google_session_ready), session);
- g_signal_connect(G_OBJECT(session->media), "state-changed",
- G_CALLBACK(google_session_state_changed_cb), session);
- g_signal_connect(G_OBJECT(session->media), "stream-info",
- G_CALLBACK(google_session_stream_info_cb), session);
-
- params = jabber_google_session_get_params(js, &num_params);
-
- if (purple_media_add_stream(session->media, "google-voice",
- session->remote_jid, PURPLE_MEDIA_AUDIO, FALSE,
- "nice", num_params, params) == FALSE ||
- (session->video && purple_media_add_stream(
- session->media, "google-video",
- session->remote_jid, PURPLE_MEDIA_VIDEO,
- FALSE, "nice", num_params, params) == FALSE)) {
- purple_media_error(session->media, "Error adding stream.");
- purple_media_stream_info(session->media,
- PURPLE_MEDIA_INFO_REJECT, NULL, NULL, TRUE);
- g_free(params);
- return FALSE;
- }
-
- g_free(params);
-
- for (codec_element = xmlnode_get_child(desc_element, "payload-type");
- codec_element; codec_element = codec_element->next) {
- const char *id, *encoding_name, *clock_rate,
- *width, *height, *framerate;
- gboolean video;
- if (codec_element->name &&
- strcmp(codec_element->name, "payload-type"))
- continue;
-
- xmlns = xmlnode_get_namespace(codec_element);
- encoding_name = xmlnode_get_attrib(codec_element, "name");
- id = xmlnode_get_attrib(codec_element, "id");
-
- if (!session->video ||
- (xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_PHONE))) {
- clock_rate = xmlnode_get_attrib(
- codec_element, "clockrate");
- video = FALSE;
- } else {
- width = xmlnode_get_attrib(codec_element, "width");
- height = xmlnode_get_attrib(codec_element, "height");
- framerate = xmlnode_get_attrib(
- codec_element, "framerate");
- clock_rate = "90000";
- video = TRUE;
- }
-
- if (id) {
- codec = purple_media_codec_new(atoi(id), encoding_name,
- video ? PURPLE_MEDIA_VIDEO :
- PURPLE_MEDIA_AUDIO,
- clock_rate ? atoi(clock_rate) : 0);
- if (video)
- video_codecs = g_list_append(
- video_codecs, codec);
- else
- codecs = g_list_append(codecs, codec);
- }
- }
-
- if (codecs)
- purple_media_set_remote_codecs(session->media, "google-voice",
- session->remote_jid, codecs);
- if (video_codecs)
- purple_media_set_remote_codecs(session->media, "google-video",
- session->remote_jid, video_codecs);
-
- purple_media_codec_list_free(codecs);
- purple_media_codec_list_free(video_codecs);
-
- result = jabber_iq_new(js, JABBER_IQ_RESULT);
- jabber_iq_set_id(result, iq_id);
- xmlnode_set_attrib(result->node, "to", session->remote_jid);
- jabber_iq_send(result);
-
- return TRUE;
-}
-
-static void
-google_session_handle_candidates(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
-{
- JabberIq *result;
- GList *list = NULL, *video_list = NULL;
- xmlnode *cand;
- static int name = 0;
- char n[4];
-
- for (cand = xmlnode_get_child(sess, "candidate"); cand;
- cand = xmlnode_get_next_twin(cand)) {
- PurpleMediaCandidate *info;
- const gchar *cname = xmlnode_get_attrib(cand, "name");
- const gchar *type = xmlnode_get_attrib(cand, "type");
- const gchar *protocol = xmlnode_get_attrib(cand, "protocol");
- const gchar *address = xmlnode_get_attrib(cand, "address");
- const gchar *port = xmlnode_get_attrib(cand, "port");
- guint component_id;
-
- if (cname && type && address && port) {
- PurpleMediaCandidateType candidate_type;
-
- g_snprintf(n, sizeof(n), "S%d", name++);
-
- if (g_str_equal(type, "local"))
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
- else if (g_str_equal(type, "stun"))
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX;
- else if (g_str_equal(type, "relay"))
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_RELAY;
- else
- candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
-
- if (purple_strequal(cname, "rtcp") ||
- purple_strequal(cname, "video_rtcp"))
- component_id = PURPLE_MEDIA_COMPONENT_RTCP;
- else
- component_id = PURPLE_MEDIA_COMPONENT_RTP;
-
- info = purple_media_candidate_new(n, component_id,
- candidate_type,
- purple_strequal(protocol, "udp") ?
- PURPLE_MEDIA_NETWORK_PROTOCOL_UDP :
- PURPLE_MEDIA_NETWORK_PROTOCOL_TCP,
- address,
- atoi(port));
- g_object_set(info, "username", xmlnode_get_attrib(cand, "username"),
- "password", xmlnode_get_attrib(cand, "password"), NULL);
- if (!strncmp(cname, "video_", 6))
- video_list = g_list_append(video_list, info);
- else
- list = g_list_append(list, info);
- }
- }
-
- if (list)
- purple_media_add_remote_candidates(
- session->media, "google-voice",
- session->remote_jid, list);
- if (video_list)
- purple_media_add_remote_candidates(
- session->media, "google-video",
- session->remote_jid, video_list);
- purple_media_candidate_list_free(list);
- purple_media_candidate_list_free(video_list);
-
- result = jabber_iq_new(js, JABBER_IQ_RESULT);
- jabber_iq_set_id(result, iq_id);
- xmlnode_set_attrib(result->node, "to", session->remote_jid);
- jabber_iq_send(result);
-}
-
-static void
-google_session_handle_accept(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
-{
- xmlnode *desc_element = xmlnode_get_child(sess, "description");
- xmlnode *codec_element = xmlnode_get_child(
- desc_element, "payload-type");
- GList *codecs = NULL, *video_codecs = NULL;
- JabberIq *result = NULL;
- const gchar *xmlns = xmlnode_get_namespace(desc_element);
- gboolean video = (xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_VIDEO));
-
- for (; codec_element; codec_element = codec_element->next) {
- const gchar *xmlns, *encoding_name, *id,
- *clock_rate, *width, *height, *framerate;
- gboolean video_codec = FALSE;
-
- if (!purple_strequal(codec_element->name, "payload-type"))
- continue;
-
- xmlns = xmlnode_get_namespace(codec_element);
- encoding_name = xmlnode_get_attrib(codec_element, "name");
- id = xmlnode_get_attrib(codec_element, "id");
-
- if (!video || purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE))
- clock_rate = xmlnode_get_attrib(
- codec_element, "clockrate");
- else {
- clock_rate = "90000";
- width = xmlnode_get_attrib(codec_element, "width");
- height = xmlnode_get_attrib(codec_element, "height");
- framerate = xmlnode_get_attrib(
- codec_element, "framerate");
- video_codec = TRUE;
- }
-
- if (id && encoding_name) {
- PurpleMediaCodec *codec = purple_media_codec_new(
- atoi(id), encoding_name,
- video_codec ? PURPLE_MEDIA_VIDEO :
- PURPLE_MEDIA_AUDIO,
- clock_rate ? atoi(clock_rate) : 0);
- if (video_codec)
- video_codecs = g_list_append(
- video_codecs, codec);
- else
- codecs = g_list_append(codecs, codec);
- }
- }
-
- if (codecs)
- purple_media_set_remote_codecs(session->media, "google-voice",
- session->remote_jid, codecs);
- if (video_codecs)
- purple_media_set_remote_codecs(session->media, "google-video",
- session->remote_jid, video_codecs);
-
- purple_media_stream_info(session->media, PURPLE_MEDIA_INFO_ACCEPT,
- NULL, NULL, FALSE);
-
- result = jabber_iq_new(js, JABBER_IQ_RESULT);
- jabber_iq_set_id(result, iq_id);
- xmlnode_set_attrib(result->node, "to", session->remote_jid);
- jabber_iq_send(result);
-}
-
-static void
-google_session_handle_reject(JabberStream *js, GoogleSession *session, xmlnode *sess)
-{
- purple_media_end(session->media, NULL, NULL);
-}
-
-static void
-google_session_handle_terminate(JabberStream *js, GoogleSession *session, xmlnode *sess)
-{
- purple_media_end(session->media, NULL, NULL);
-}
-
-static void
-google_session_parse_iq(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
-{
- const char *type = xmlnode_get_attrib(sess, "type");
-
- if (!strcmp(type, "initiate")) {
- google_session_handle_initiate(js, session, sess, iq_id);
- } else if (!strcmp(type, "accept")) {
- google_session_handle_accept(js, session, sess, iq_id);
- } else if (!strcmp(type, "reject")) {
- google_session_handle_reject(js, session, sess);
- } else if (!strcmp(type, "terminate")) {
- google_session_handle_terminate(js, session, sess);
- } else if (!strcmp(type, "candidates")) {
- google_session_handle_candidates(js, session, sess, iq_id);
- }
-}
-
-void
-jabber_google_session_parse(JabberStream *js, const char *from,
- JabberIqType type, const char *iq_id,
- xmlnode *session_node)
-{
- GoogleSession *session = NULL;
- GoogleSessionId id;
-
- xmlnode *desc_node;
-
- GList *iter = NULL;
-
- if (type != JABBER_IQ_SET)
- return;
-
- id.id = (gchar*)xmlnode_get_attrib(session_node, "id");
- if (!id.id)
- return;
-
- id.initiator = (gchar*)xmlnode_get_attrib(session_node, "initiator");
- if (!id.initiator)
- return;
-
- iter = purple_media_manager_get_media_by_account(
- purple_media_manager_get(),
- purple_connection_get_account(js->gc));
- for (; iter; iter = g_list_delete_link(iter, iter)) {
- GoogleSession *gsession =
- purple_media_get_prpl_data(iter->data);
- if (google_session_id_equal(&(gsession->id), &id)) {
- session = gsession;
- break;
- }
- }
- if (iter != NULL) {
- g_list_free(iter);
- }
-
- if (session) {
- google_session_parse_iq(js, session, session_node, iq_id);
- return;
- }
-
- /* If the session doesn't exist, this has to be an initiate message */
- if (strcmp(xmlnode_get_attrib(session_node, "type"), "initiate"))
- return;
- desc_node = xmlnode_get_child(session_node, "description");
- if (!desc_node)
- return;
- session = g_new0(GoogleSession, 1);
- session->id.id = g_strdup(id.id);
- session->id.initiator = g_strdup(id.initiator);
- session->state = UNINIT;
- session->js = js;
- session->remote_jid = g_strdup(session->id.initiator);
-
- google_session_handle_initiate(js, session, session_node, iq_id);
-}
-#endif /* USE_VV */
-
-static void
-jabber_gmail_parse(JabberStream *js, const char *from,
- JabberIqType type, const char *id,
- xmlnode *packet, gpointer nul)
-{
- xmlnode *child;
- xmlnode *message;
- const char *to, *url;
- const char *in_str;
- char *to_name;
-
- int i, count = 1, returned_count;
-
- const char **tos, **froms, **urls;
- char **subjects;
-
- if (type == JABBER_IQ_ERROR)
- return;
-
- child = xmlnode_get_child(packet, "mailbox");
- if (!child)
- return;
-
- in_str = xmlnode_get_attrib(child, "total-matched");
- if (in_str && *in_str)
- count = atoi(in_str);
-
- /* If Gmail doesn't tell us who the mail is to, let's use our JID */
- to = xmlnode_get_attrib(packet, "to");
-
- message = xmlnode_get_child(child, "mail-thread-info");
-
- if (count == 0 || !message) {
- if (count > 0) {
- char *bare_jid = jabber_get_bare_jid(to);
- const char *default_tos[2] = { bare_jid };
-
- purple_notify_emails(js->gc, count, FALSE, NULL, NULL, default_tos, NULL, NULL, NULL);
- g_free(bare_jid);
- } else {
- purple_notify_emails(js->gc, count, FALSE, NULL, NULL, NULL, NULL, NULL, NULL);
- }
-
- return;
- }
-
- /* Loop once to see how many messages were returned so we can allocate arrays
- * accordingly */
- for (returned_count = 0; message; returned_count++, message=xmlnode_get_next_twin(message));
-
- froms = g_new0(const char* , returned_count + 1);
- tos = g_new0(const char* , returned_count + 1);
- subjects = g_new0(char* , returned_count + 1);
- urls = g_new0(const char* , returned_count + 1);
-
- to = xmlnode_get_attrib(packet, "to");
- to_name = jabber_get_bare_jid(to);
- url = xmlnode_get_attrib(child, "url");
- if (!url || !*url)
- url = "http://www.gmail.com";
-
- message= xmlnode_get_child(child, "mail-thread-info");
- for (i=0; message; message = xmlnode_get_next_twin(message), i++) {
- xmlnode *sender_node, *subject_node;
- const char *from, *tid;
- char *subject;
-
- subject_node = xmlnode_get_child(message, "subject");
- sender_node = xmlnode_get_child(message, "senders");
- sender_node = xmlnode_get_child(sender_node, "sender");
-
- while (sender_node && (!xmlnode_get_attrib(sender_node, "unread") ||
- !strcmp(xmlnode_get_attrib(sender_node, "unread"),"0")))
- sender_node = xmlnode_get_next_twin(sender_node);
-
- if (!sender_node) {
- i--;
- continue;
- }
-
- from = xmlnode_get_attrib(sender_node, "name");
- if (!from || !*from)
- from = xmlnode_get_attrib(sender_node, "address");
- subject = xmlnode_get_data(subject_node);
- /*
- * url = xmlnode_get_attrib(message, "url");
- */
- tos[i] = (to_name != NULL ? to_name : "");
- froms[i] = (from != NULL ? from : "");
- subjects[i] = (subject != NULL ? subject : g_strdup(""));
- urls[i] = url;
-
- tid = xmlnode_get_attrib(message, "tid");
- if (tid &&
- (js->gmail_last_tid == NULL || strcmp(tid, js->gmail_last_tid) > 0)) {
- g_free(js->gmail_last_tid);
- js->gmail_last_tid = g_strdup(tid);
- }
- }
-
- if (i>0)
- purple_notify_emails(js->gc, count, count == i, (const char**) subjects, froms, tos,
- urls, NULL, NULL);
-
- g_free(to_name);
- g_free(tos);
- g_free(froms);
- for (i = 0; i < returned_count; i++)
- g_free(subjects[i]);
- g_free(subjects);
- g_free(urls);
-
- in_str = xmlnode_get_attrib(child, "result-time");
- if (in_str && *in_str) {
- g_free(js->gmail_last_time);
- js->gmail_last_time = g_strdup(in_str);
- }
-}
-
-void
-jabber_gmail_poke(JabberStream *js, const char *from, JabberIqType type,
- const char *id, xmlnode *new_mail)
-{
- xmlnode *query;
- JabberIq *iq;
-
- /* bail if the user isn't interested */
- if (!purple_account_get_check_mail(js->gc->account))
- return;
-
- /* Is this an initial incoming mail notification? If so, send a request for more info */
- if (type != JABBER_IQ_SET)
- return;
-
- /* Acknowledge the notification */
- iq = jabber_iq_new(js, JABBER_IQ_RESULT);
- if (from)
- xmlnode_set_attrib(iq->node, "to", from);
- xmlnode_set_attrib(iq->node, "id", id);
- jabber_iq_send(iq);
-
- purple_debug_misc("jabber",
- "Got new mail notification. Sending request for more info\n");
-
- iq = jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_MAIL_NOTIFY);
- jabber_iq_set_callback(iq, jabber_gmail_parse, NULL);
- query = xmlnode_get_child(iq->node, "query");
-
- if (js->gmail_last_time)
- xmlnode_set_attrib(query, "newer-than-time", js->gmail_last_time);
- if (js->gmail_last_tid)
- xmlnode_set_attrib(query, "newer-than-tid", js->gmail_last_tid);
-
- jabber_iq_send(iq);
- return;
-}
-
-void jabber_gmail_init(JabberStream *js) {
- JabberIq *iq;
- xmlnode *usersetting, *mailnotifications;
-
- if (!purple_account_get_check_mail(purple_connection_get_account(js->gc)))
- return;
-
- /*
- * Quoting http://code.google.com/apis/talk/jep_extensions/usersettings.html:
- * To ensure better compatibility with other clients, rather than
- * setting this value to "false" to turn off notifications, it is
- * recommended that a client set this to "true" and filter incoming
- * email notifications itself.
- */
- iq = jabber_iq_new(js, JABBER_IQ_SET);
- usersetting = xmlnode_new_child(iq->node, "usersetting");
- xmlnode_set_namespace(usersetting, "google:setting");
- mailnotifications = xmlnode_new_child(usersetting, "mailnotifications");
- xmlnode_set_attrib(mailnotifications, "value", "true");
- jabber_iq_send(iq);
-
- iq = jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_MAIL_NOTIFY);
- jabber_iq_set_callback(iq, jabber_gmail_parse, NULL);
- jabber_iq_send(iq);
-}
-
-void jabber_google_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *item)
-{
- PurpleAccount *account = purple_connection_get_account(js->gc);
- GSList *list = account->deny;
- const char *jid = xmlnode_get_attrib(item, "jid");
- char *jid_norm = (char *)jabber_normalize(account, jid);
-
- while (list) {
- if (!strcmp(jid_norm, (char*)list->data)) {
- xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
- xmlnode_set_attrib(query, "gr:ext", "2");
- xmlnode_set_attrib(item, "gr:t", "B");
- return;
- }
- list = list->next;
- }
-}
-
-gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item)
-{
- PurpleAccount *account = purple_connection_get_account(js->gc);
- const char *jid = xmlnode_get_attrib(item, "jid");
- gboolean on_block_list = FALSE;
-
- char *jid_norm;
-
- const char *grt = xmlnode_get_attrib_with_namespace(item, "t", NS_GOOGLE_ROSTER);
- const char *subscription = xmlnode_get_attrib(item, "subscription");
- const char *ask = xmlnode_get_attrib(item, "ask");
-
- if ((!subscription || !strcmp(subscription, "none")) && !ask) {
- /* The Google Talk servers will automatically add people from your Gmail address book
- * with subscription=none. If we see someone with subscription=none, ignore them.
- */
- return FALSE;
- }
-
- jid_norm = g_strdup(jabber_normalize(account, jid));
-
- on_block_list = NULL != g_slist_find_custom(account->deny, jid_norm,
- (GCompareFunc)strcmp);
-
- if (grt && (*grt == 'H' || *grt == 'h')) {
- /* Hidden; don't show this buddy. */
- GSList *buddies = purple_find_buddies(account, jid_norm);
- if (buddies)
- purple_debug_info("jabber", "Removing %s from local buddy list\n",
- jid_norm);
-
- for ( ; buddies; buddies = g_slist_delete_link(buddies, buddies)) {
- purple_blist_remove_buddy(buddies->data);
- }
-
- g_free(jid_norm);
- return FALSE;
- }
-
- if (!on_block_list && (grt && (*grt == 'B' || *grt == 'b'))) {
- purple_debug_info("jabber", "Blocking %s\n", jid_norm);
- purple_privacy_deny_add(account, jid_norm, TRUE);
- } else if (on_block_list && (!grt || (*grt != 'B' && *grt != 'b' ))){
- purple_debug_info("jabber", "Unblocking %s\n", jid_norm);
- purple_privacy_deny_remove(account, jid_norm, TRUE);
- }
-
- g_free(jid_norm);
- return TRUE;
-}
-
-void jabber_google_roster_add_deny(JabberStream *js, const char *who)
-{
- PurpleAccount *account;
- GSList *buddies;
- JabberIq *iq;
- xmlnode *query;
- xmlnode *item;
- xmlnode *group;
- PurpleBuddy *b;
- JabberBuddy *jb;
- const char *balias;
-
- jb = jabber_buddy_find(js, who, TRUE);
-
- account = purple_connection_get_account(js->gc);
- buddies = purple_find_buddies(account, who);
- if(!buddies)
- return;
-
- b = buddies->data;
-
- iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
-
- query = xmlnode_get_child(iq->node, "query");
- item = xmlnode_new_child(query, "item");
-
- while(buddies) {
- PurpleGroup *g;
-
- b = buddies->data;
- g = purple_buddy_get_group(b);
-
- group = xmlnode_new_child(item, "group");
- xmlnode_insert_data(group, purple_group_get_name(g), -1);
-
- buddies = buddies->next;
- }
-
- balias = purple_buddy_get_local_buddy_alias(b);
- xmlnode_set_attrib(item, "jid", who);
- xmlnode_set_attrib(item, "name", balias ? balias : "");
- xmlnode_set_attrib(item, "gr:t", "B");
- xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
- xmlnode_set_attrib(query, "gr:ext", "2");
-
- jabber_iq_send(iq);
-
- /* Synthesize a sign-off */
- if (jb) {
- JabberBuddyResource *jbr;
- GList *l = jb->resources;
- while (l) {
- jbr = l->data;
- if (jbr && jbr->name)
- {
- purple_debug_misc("jabber", "Removing resource %s\n", jbr->name);
- jabber_buddy_remove_resource(jb, jbr->name);
- }
- l = l->next;
- }
- }
-
- purple_prpl_got_user_status(account, who, "offline", NULL);
-}
-
-void jabber_google_roster_rem_deny(JabberStream *js, const char *who)
-{
- GSList *buddies;
- JabberIq *iq;
- xmlnode *query;
- xmlnode *item;
- xmlnode *group;
- PurpleBuddy *b;
- const char *balias;
-
- buddies = purple_find_buddies(purple_connection_get_account(js->gc), who);
- if(!buddies)
- return;
-
- b = buddies->data;
-
- iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
-
- query = xmlnode_get_child(iq->node, "query");
- item = xmlnode_new_child(query, "item");
-
- while(buddies) {
- PurpleGroup *g;
-
- b = buddies->data;
- g = purple_buddy_get_group(b);
-
- group = xmlnode_new_child(item, "group");
- xmlnode_insert_data(group, purple_group_get_name(g), -1);
-
- buddies = buddies->next;
- }
-
- balias = purple_buddy_get_local_buddy_alias(b);
- xmlnode_set_attrib(item, "jid", who);
- xmlnode_set_attrib(item, "name", balias ? balias : "");
- xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
- xmlnode_set_attrib(query, "gr:ext", "2");
-
- jabber_iq_send(iq);
-
- /* See if he's online */
- jabber_presence_subscription_set(js, who, "probe");
-}
-
-/* This does two passes on the string. The first pass goes through
- * and determine if all the structured text is properly balanced, and
- * how many instances of each there is. The second pass goes and converts
- * everything to HTML, depending on what's figured out by the first pass.
- * It will short circuit once it knows it has no more replacements to make
- */
-char *jabber_google_format_to_html(const char *text)
-{
- const char *p;
-
- /* The start of the screen may be consdiered a space for this purpose */
- gboolean preceding_space = TRUE;
-
- gboolean in_bold = FALSE, in_italic = FALSE;
- gboolean in_tag = FALSE;
-
- gint bold_count = 0, italic_count = 0;
-
- GString *str;
-
- for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
- gunichar c = g_utf8_get_char(p);
- if (c == '*' && !in_tag) {
- if (in_bold && (g_unichar_isspace(*(p+1)) ||
- *(p+1) == '\0' ||
- *(p+1) == '<')) {
- bold_count++;
- in_bold = FALSE;
- } else if (preceding_space && !in_bold && !g_unichar_isspace(*(p+1))) {
- bold_count++;
- in_bold = TRUE;
- }
- preceding_space = TRUE;
- } else if (c == '_' && !in_tag) {
- if (in_italic && (g_unichar_isspace(*(p+1)) ||
- *(p+1) == '\0' ||
- *(p+1) == '<')) {
- italic_count++;
- in_italic = FALSE;
- } else if (preceding_space && !in_italic && !g_unichar_isspace(*(p+1))) {
- italic_count++;
- in_italic = TRUE;
- }
- preceding_space = TRUE;
- } else if (c == '<' && !in_tag) {
- in_tag = TRUE;
- } else if (c == '>' && in_tag) {
- in_tag = FALSE;
- } else if (!in_tag) {
- if (g_unichar_isspace(c))
- preceding_space = TRUE;
- else
- preceding_space = FALSE;
- }
- }
-
- str = g_string_new(NULL);
- in_bold = in_italic = in_tag = FALSE;
- preceding_space = TRUE;
-
- for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
- gunichar c = g_utf8_get_char(p);
-
- if (bold_count < 2 && italic_count < 2 && !in_bold && !in_italic) {
- g_string_append(str, p);
- return g_string_free(str, FALSE);
- }
-
-
- if (c == '*' && !in_tag) {
- if (in_bold &&
- (g_unichar_isspace(*(p+1))||*(p+1)=='<')) { /* This is safe in UTF-8 */
- str = g_string_append(str, "</b>");
- in_bold = FALSE;
- bold_count--;
- } else if (preceding_space && bold_count > 1 && !g_unichar_isspace(*(p+1))) {
- str = g_string_append(str, "<b>");
- bold_count--;
- in_bold = TRUE;
- } else {
- str = g_string_append_unichar(str, c);
- }
- preceding_space = TRUE;
- } else if (c == '_' && !in_tag) {
- if (in_italic &&
- (g_unichar_isspace(*(p+1))||*(p+1)=='<')) {
- str = g_string_append(str, "</i>");
- italic_count--;
- in_italic = FALSE;
- } else if (preceding_space && italic_count > 1 && !g_unichar_isspace(*(p+1))) {
- str = g_string_append(str, "<i>");
- italic_count--;
- in_italic = TRUE;
- } else {
- str = g_string_append_unichar(str, c);
- }
- preceding_space = TRUE;
- } else if (c == '<' && !in_tag) {
- str = g_string_append_unichar(str, c);
- in_tag = TRUE;
- } else if (c == '>' && in_tag) {
- str = g_string_append_unichar(str, c);
- in_tag = FALSE;
- } else if (!in_tag) {
- str = g_string_append_unichar(str, c);
- if (g_unichar_isspace(c))
- preceding_space = TRUE;
- else
- preceding_space = FALSE;
- } else {
- str = g_string_append_unichar(str, c);
- }
- }
- return g_string_free(str, FALSE);
-}
-
-void jabber_google_presence_incoming(JabberStream *js, const char *user, JabberBuddyResource *jbr)
-{
- if (!js->googletalk)
- return;
- if (jbr->status && purple_str_has_prefix(jbr->status, "♫ ")) {
- purple_prpl_got_user_status(js->gc->account, user, "tune",
- PURPLE_TUNE_TITLE, jbr->status + strlen("♫ "), NULL);
- g_free(jbr->status);
- jbr->status = NULL;
- } else {
- purple_prpl_got_user_status_deactive(js->gc->account, user, "tune");
- }
-}
-
-char *jabber_google_presence_outgoing(PurpleStatus *tune)
-{
- const char *attr = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
- return attr ? g_strdup_printf("♫ %s", attr) : g_strdup("");
-}
-
-static void
-jabber_google_stun_lookup_cb(GSList *hosts, gpointer data,
- const char *error_message)
-{
- JabberStream *js = (JabberStream *) data;
-
- if (error_message) {
- purple_debug_error("jabber", "Google STUN lookup failed: %s\n",
- error_message);
- g_slist_free(hosts);
- js->stun_query = NULL;
- return;
- }
-
- if (hosts && g_slist_next(hosts)) {
- struct sockaddr *addr = g_slist_next(hosts)->data;
- char dst[INET6_ADDRSTRLEN];
- int port;
-
- if (addr->sa_family == AF_INET6) {
- inet_ntop(addr->sa_family, &((struct sockaddr_in6 *) addr)->sin6_addr,
- dst, sizeof(dst));
- port = ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
- } else {
- inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr,
- dst, sizeof(dst));
- port = ntohs(((struct sockaddr_in *) addr)->sin_port);
- }
-
- if (js->stun_ip)
- g_free(js->stun_ip);
- js->stun_ip = g_strdup(dst);
- js->stun_port = port;
-
- purple_debug_info("jabber", "set Google STUN IP/port address: "
- "%s:%d\n", dst, port);
-
- /* unmark ongoing query */
- js->stun_query = NULL;
- }
-
- while (hosts != NULL) {
- hosts = g_slist_delete_link(hosts, hosts);
- /* Free the address */
- g_free(hosts->data);
- hosts = g_slist_delete_link(hosts, hosts);
- }
-}
-
-static void
-jabber_google_jingle_info_common(JabberStream *js, const char *from,
- JabberIqType type, xmlnode *query)
-{
- const xmlnode *stun = xmlnode_get_child(query, "stun");
- gchar *my_bare_jid;
-
- /*
- * Make sure that random people aren't sending us STUN servers. Per
- * http://code.google.com/apis/talk/jep_extensions/jingleinfo.html, these
- * stanzas are stamped from our bare JID.
- */
- if (from) {
- my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain);
- if (!purple_strequal(from, my_bare_jid)) {
- purple_debug_warning("jabber", "got google:jingleinfo with invalid from (%s)\n",
- from);
- g_free(my_bare_jid);
- return;
- }
-
- g_free(my_bare_jid);
- }
-
- if (type == JABBER_IQ_ERROR || type == JABBER_IQ_GET)
- return;
-
- purple_debug_info("jabber", "got google:jingleinfo\n");
-
- if (stun) {
- xmlnode *server = xmlnode_get_child(stun, "server");
-
- if (server) {
- const gchar *host = xmlnode_get_attrib(server, "host");
- const gchar *udp = xmlnode_get_attrib(server, "udp");
-
- if (host && udp) {
- int port = atoi(udp);
- /* if there, would already be an ongoing query,
- cancel it */
- if (js->stun_query)
- purple_dnsquery_destroy(js->stun_query);
-
- js->stun_query = purple_dnsquery_a(host, port,
- jabber_google_stun_lookup_cb, js);
- }
- }
- }
- /* should perhaps handle relays later on, or maybe wait until
- Google supports a common standard... */
-}
-
-static void
-jabber_google_jingle_info_cb(JabberStream *js, const char *from,
- JabberIqType type, const char *id,
- xmlnode *packet, gpointer data)
-{
- xmlnode *query = xmlnode_get_child_with_namespace(packet, "query",
- NS_GOOGLE_JINGLE_INFO);
-
- if (query)
- jabber_google_jingle_info_common(js, from, type, query);
- else
- purple_debug_warning("jabber", "Got invalid google:jingleinfo\n");
-}
-
-void
-jabber_google_handle_jingle_info(JabberStream *js, const char *from,
- JabberIqType type, const char *id,
- xmlnode *child)
-{
- jabber_google_jingle_info_common(js, from, type, child);
-}
-
-void
-jabber_google_send_jingle_info(JabberStream *js)
-{
- JabberIq *jingle_info =
- jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_JINGLE_INFO);
-
- jabber_iq_set_callback(jingle_info, jabber_google_jingle_info_cb,
- NULL);
- purple_debug_info("jabber", "sending google:jingleinfo query\n");
- jabber_iq_send(jingle_info);
-}
-
-void google_buddy_node_chat(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
- JabberStream *js;
- JabberChat *chat;
- gchar *room;
- gchar *uuid = purple_uuid_random();
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = PURPLE_BUDDY(node);
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- g_return_if_fail(gc != NULL);
- js = purple_connection_get_protocol_data(gc);
-
- room = g_strdup_printf("private-chat-%s", uuid);
- chat = jabber_join_chat(js, room, GOOGLE_GROUPCHAT_SERVER, js->user->node,
- NULL, NULL);
- if (chat) {
- chat->muc = TRUE;
- jabber_chat_invite(gc, chat->id, "", purple_buddy_get_name(buddy));
- }
-
- g_free(room);
- g_free(uuid);
-}
diff --git a/libpurple/protocols/jabber/google/gmail.c b/libpurple/protocols/jabber/google/gmail.c
new file mode 100644
index 0000000000..5f86b8efac
--- /dev/null
+++ b/libpurple/protocols/jabber/google/gmail.c
@@ -0,0 +1,207 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+#include "jabber.h"
+#include "gmail.h"
+
+static void
+jabber_gmail_parse(JabberStream *js, const char *from,
+ JabberIqType type, const char *id,
+ xmlnode *packet, gpointer nul)
+{
+ xmlnode *child;
+ xmlnode *message;
+ const char *to, *url;
+ const char *in_str;
+ char *to_name;
+
+ int i, count = 1, returned_count;
+
+ const char **tos, **froms, **urls;
+ char **subjects;
+
+ if (type == JABBER_IQ_ERROR)
+ return;
+
+ child = xmlnode_get_child(packet, "mailbox");
+ if (!child)
+ return;
+
+ in_str = xmlnode_get_attrib(child, "total-matched");
+ if (in_str && *in_str)
+ count = atoi(in_str);
+
+ /* If Gmail doesn't tell us who the mail is to, let's use our JID */
+ to = xmlnode_get_attrib(packet, "to");
+
+ message = xmlnode_get_child(child, "mail-thread-info");
+
+ if (count == 0 || !message) {
+ if (count > 0) {
+ char *bare_jid = jabber_get_bare_jid(to);
+ const char *default_tos[2] = { bare_jid };
+
+ purple_notify_emails(js->gc, count, FALSE, NULL, NULL, default_tos, NULL, NULL, NULL);
+ g_free(bare_jid);
+ } else {
+ purple_notify_emails(js->gc, count, FALSE, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return;
+ }
+
+ /* Loop once to see how many messages were returned so we can allocate arrays
+ * accordingly */
+ for (returned_count = 0; message; returned_count++, message=xmlnode_get_next_twin(message));
+
+ froms = g_new0(const char* , returned_count + 1);
+ tos = g_new0(const char* , returned_count + 1);
+ subjects = g_new0(char* , returned_count + 1);
+ urls = g_new0(const char* , returned_count + 1);
+
+ to = xmlnode_get_attrib(packet, "to");
+ to_name = jabber_get_bare_jid(to);
+ url = xmlnode_get_attrib(child, "url");
+ if (!url || !*url)
+ url = "http://www.gmail.com";
+
+ message= xmlnode_get_child(child, "mail-thread-info");
+ for (i=0; message; message = xmlnode_get_next_twin(message), i++) {
+ xmlnode *sender_node, *subject_node;
+ const char *from, *tid;
+ char *subject;
+
+ subject_node = xmlnode_get_child(message, "subject");
+ sender_node = xmlnode_get_child(message, "senders");
+ sender_node = xmlnode_get_child(sender_node, "sender");
+
+ while (sender_node && (!xmlnode_get_attrib(sender_node, "unread") ||
+ !strcmp(xmlnode_get_attrib(sender_node, "unread"),"0")))
+ sender_node = xmlnode_get_next_twin(sender_node);
+
+ if (!sender_node) {
+ i--;
+ continue;
+ }
+
+ from = xmlnode_get_attrib(sender_node, "name");
+ if (!from || !*from)
+ from = xmlnode_get_attrib(sender_node, "address");
+ subject = xmlnode_get_data(subject_node);
+ /*
+ * url = xmlnode_get_attrib(message, "url");
+ */
+ tos[i] = (to_name != NULL ? to_name : "");
+ froms[i] = (from != NULL ? from : "");
+ subjects[i] = (subject != NULL ? subject : g_strdup(""));
+ urls[i] = url;
+
+ tid = xmlnode_get_attrib(message, "tid");
+ if (tid &&
+ (js->gmail_last_tid == NULL || strcmp(tid, js->gmail_last_tid) > 0)) {
+ g_free(js->gmail_last_tid);
+ js->gmail_last_tid = g_strdup(tid);
+ }
+ }
+
+ if (i>0)
+ purple_notify_emails(js->gc, count, count == i, (const char**) subjects, froms, tos,
+ urls, NULL, NULL);
+
+ g_free(to_name);
+ g_free(tos);
+ g_free(froms);
+ for (i = 0; i < returned_count; i++)
+ g_free(subjects[i]);
+ g_free(subjects);
+ g_free(urls);
+
+ in_str = xmlnode_get_attrib(child, "result-time");
+ if (in_str && *in_str) {
+ g_free(js->gmail_last_time);
+ js->gmail_last_time = g_strdup(in_str);
+ }
+}
+
+void
+jabber_gmail_poke(JabberStream *js, const char *from, JabberIqType type,
+ const char *id, xmlnode *new_mail)
+{
+ xmlnode *query;
+ JabberIq *iq;
+
+ /* bail if the user isn't interested */
+ if (!purple_account_get_check_mail(js->gc->account))
+ return;
+
+ /* Is this an initial incoming mail notification? If so, send a request for more info */
+ if (type != JABBER_IQ_SET)
+ return;
+
+ /* Acknowledge the notification */
+ iq = jabber_iq_new(js, JABBER_IQ_RESULT);
+ if (from)
+ xmlnode_set_attrib(iq->node, "to", from);
+ xmlnode_set_attrib(iq->node, "id", id);
+ jabber_iq_send(iq);
+
+ purple_debug_misc("jabber",
+ "Got new mail notification. Sending request for more info\n");
+
+ iq = jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_MAIL_NOTIFY);
+ jabber_iq_set_callback(iq, jabber_gmail_parse, NULL);
+ query = xmlnode_get_child(iq->node, "query");
+
+ if (js->gmail_last_time)
+ xmlnode_set_attrib(query, "newer-than-time", js->gmail_last_time);
+ if (js->gmail_last_tid)
+ xmlnode_set_attrib(query, "newer-than-tid", js->gmail_last_tid);
+
+ jabber_iq_send(iq);
+ return;
+}
+
+void jabber_gmail_init(JabberStream *js) {
+ JabberIq *iq;
+ xmlnode *usersetting, *mailnotifications;
+
+ if (!purple_account_get_check_mail(purple_connection_get_account(js->gc)))
+ return;
+
+ /*
+ * Quoting http://code.google.com/apis/talk/jep_extensions/usersettings.html:
+ * To ensure better compatibility with other clients, rather than
+ * setting this value to "false" to turn off notifications, it is
+ * recommended that a client set this to "true" and filter incoming
+ * email notifications itself.
+ */
+ iq = jabber_iq_new(js, JABBER_IQ_SET);
+ usersetting = xmlnode_new_child(iq->node, "usersetting");
+ xmlnode_set_namespace(usersetting, "google:setting");
+ mailnotifications = xmlnode_new_child(usersetting, "mailnotifications");
+ xmlnode_set_attrib(mailnotifications, "value", "true");
+ jabber_iq_send(iq);
+
+ iq = jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_MAIL_NOTIFY);
+ jabber_iq_set_callback(iq, jabber_gmail_parse, NULL);
+ jabber_iq_send(iq);
+}
diff --git a/libpurple/protocols/jabber/google/gmail.h b/libpurple/protocols/jabber/google/gmail.h
new file mode 100644
index 0000000000..2058802ea2
--- /dev/null
+++ b/libpurple/protocols/jabber/google/gmail.h
@@ -0,0 +1,30 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_JABBER_GOOGLE_GMAIL_H_
+#define PURPLE_JABBER_GOOGLE_GMAIL_H_
+
+#include "jabber.h"
+
+void jabber_gmail_init(JabberStream *js);
+void jabber_gmail_poke(JabberStream *js, const char *from, JabberIqType type,
+ const char *id, xmlnode *new_mail);
+
+#endif /* PURPLE_JABBER_GOOGLE_GMAIL_H_ */
diff --git a/libpurple/protocols/jabber/google/google.c b/libpurple/protocols/jabber/google/google.c
new file mode 100644
index 0000000000..b4336d9d2a
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google.c
@@ -0,0 +1,172 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+
+#include "google.h"
+#include "jabber.h"
+#include "chat.h"
+
+/* This does two passes on the string. The first pass goes through
+ * and determine if all the structured text is properly balanced, and
+ * how many instances of each there is. The second pass goes and converts
+ * everything to HTML, depending on what's figured out by the first pass.
+ * It will short circuit once it knows it has no more replacements to make
+ */
+char *jabber_google_format_to_html(const char *text)
+{
+ const char *p;
+
+ /* The start of the screen may be consdiered a space for this purpose */
+ gboolean preceding_space = TRUE;
+
+ gboolean in_bold = FALSE, in_italic = FALSE;
+ gboolean in_tag = FALSE;
+
+ gint bold_count = 0, italic_count = 0;
+
+ GString *str;
+
+ for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
+ gunichar c = g_utf8_get_char(p);
+ if (c == '*' && !in_tag) {
+ if (in_bold && (g_unichar_isspace(*(p+1)) ||
+ *(p+1) == '\0' ||
+ *(p+1) == '<')) {
+ bold_count++;
+ in_bold = FALSE;
+ } else if (preceding_space && !in_bold && !g_unichar_isspace(*(p+1))) {
+ bold_count++;
+ in_bold = TRUE;
+ }
+ preceding_space = TRUE;
+ } else if (c == '_' && !in_tag) {
+ if (in_italic && (g_unichar_isspace(*(p+1)) ||
+ *(p+1) == '\0' ||
+ *(p+1) == '<')) {
+ italic_count++;
+ in_italic = FALSE;
+ } else if (preceding_space && !in_italic && !g_unichar_isspace(*(p+1))) {
+ italic_count++;
+ in_italic = TRUE;
+ }
+ preceding_space = TRUE;
+ } else if (c == '<' && !in_tag) {
+ in_tag = TRUE;
+ } else if (c == '>' && in_tag) {
+ in_tag = FALSE;
+ } else if (!in_tag) {
+ if (g_unichar_isspace(c))
+ preceding_space = TRUE;
+ else
+ preceding_space = FALSE;
+ }
+ }
+
+ str = g_string_new(NULL);
+ in_bold = in_italic = in_tag = FALSE;
+ preceding_space = TRUE;
+
+ for (p = text; *p != '\0'; p = g_utf8_next_char(p)) {
+ gunichar c = g_utf8_get_char(p);
+
+ if (bold_count < 2 && italic_count < 2 && !in_bold && !in_italic) {
+ g_string_append(str, p);
+ return g_string_free(str, FALSE);
+ }
+
+
+ if (c == '*' && !in_tag) {
+ if (in_bold &&
+ (g_unichar_isspace(*(p+1))||*(p+1)=='<')) { /* This is safe in UTF-8 */
+ str = g_string_append(str, "</b>");
+ in_bold = FALSE;
+ bold_count--;
+ } else if (preceding_space && bold_count > 1 && !g_unichar_isspace(*(p+1))) {
+ str = g_string_append(str, "<b>");
+ bold_count--;
+ in_bold = TRUE;
+ } else {
+ str = g_string_append_unichar(str, c);
+ }
+ preceding_space = TRUE;
+ } else if (c == '_' && !in_tag) {
+ if (in_italic &&
+ (g_unichar_isspace(*(p+1))||*(p+1)=='<')) {
+ str = g_string_append(str, "</i>");
+ italic_count--;
+ in_italic = FALSE;
+ } else if (preceding_space && italic_count > 1 && !g_unichar_isspace(*(p+1))) {
+ str = g_string_append(str, "<i>");
+ italic_count--;
+ in_italic = TRUE;
+ } else {
+ str = g_string_append_unichar(str, c);
+ }
+ preceding_space = TRUE;
+ } else if (c == '<' && !in_tag) {
+ str = g_string_append_unichar(str, c);
+ in_tag = TRUE;
+ } else if (c == '>' && in_tag) {
+ str = g_string_append_unichar(str, c);
+ in_tag = FALSE;
+ } else if (!in_tag) {
+ str = g_string_append_unichar(str, c);
+ if (g_unichar_isspace(c))
+ preceding_space = TRUE;
+ else
+ preceding_space = FALSE;
+ } else {
+ str = g_string_append_unichar(str, c);
+ }
+ }
+ return g_string_free(str, FALSE);
+}
+
+
+
+void google_buddy_node_chat(PurpleBlistNode *node, gpointer data)
+{
+ PurpleBuddy *buddy;
+ PurpleConnection *gc;
+ JabberStream *js;
+ JabberChat *chat;
+ gchar *room;
+ gchar *uuid = purple_uuid_random();
+
+ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+
+ buddy = PURPLE_BUDDY(node);
+ gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+ g_return_if_fail(gc != NULL);
+ js = purple_connection_get_protocol_data(gc);
+
+ room = g_strdup_printf("private-chat-%s", uuid);
+ chat = jabber_join_chat(js, room, GOOGLE_GROUPCHAT_SERVER, js->user->node,
+ NULL, NULL);
+ if (chat) {
+ chat->muc = TRUE;
+ jabber_chat_invite(gc, chat->id, "", purple_buddy_get_name(buddy));
+ }
+
+ g_free(room);
+ g_free(uuid);
+}
diff --git a/libpurple/protocols/jabber/google/google.h b/libpurple/protocols/jabber/google/google.h
new file mode 100644
index 0000000000..3f6a80361e
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google.h
@@ -0,0 +1,35 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_JABBER_GOOGLE_H_
+#define PURPLE_JABBER_GOOGLE_H_
+
+/* This is a place for Google Talk-specific XMPP extensions to live
+ * such that they don't intermingle with code for the XMPP RFCs and XEPs :) */
+
+#include "jabber.h"
+
+#define GOOGLE_GROUPCHAT_SERVER "groupchat.google.com"
+
+char *jabber_google_format_to_html(const char *text);
+
+void google_buddy_node_chat(PurpleBlistNode *node, gpointer data);
+
+#endif /* PURPLE_JABBER_GOOGLE_H_ */
diff --git a/libpurple/protocols/jabber/google/google_presence.c b/libpurple/protocols/jabber/google/google_presence.c
new file mode 100644
index 0000000000..c5ec55d946
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google_presence.c
@@ -0,0 +1,43 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+#include "google_presence.h"
+
+void jabber_google_presence_incoming(JabberStream *js, const char *user, JabberBuddyResource *jbr)
+{
+ if (!js->googletalk)
+ return;
+ if (jbr->status && purple_str_has_prefix(jbr->status, "♫ ")) {
+ purple_prpl_got_user_status(js->gc->account, user, "tune",
+ PURPLE_TUNE_TITLE, jbr->status + strlen("♫ "), NULL);
+ g_free(jbr->status);
+ jbr->status = NULL;
+ } else {
+ purple_prpl_got_user_status_deactive(js->gc->account, user, "tune");
+ }
+}
+
+char *jabber_google_presence_outgoing(PurpleStatus *tune)
+{
+ const char *attr = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
+ return attr ? g_strdup_printf("♫ %s", attr) : g_strdup("");
+}
diff --git a/libpurple/protocols/jabber/google/google_presence.h b/libpurple/protocols/jabber/google/google_presence.h
new file mode 100644
index 0000000000..4cf9dc347f
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google_presence.h
@@ -0,0 +1,32 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_JABBER_GOOGLE_PRESENCE_H_
+#define PURPLE_JABBER_GOOGLE_PRESENCE_H_
+
+#include "jabber.h"
+#include "buddy.h"
+#include "status.h"
+
+void jabber_google_presence_incoming(JabberStream *js, const char *who, JabberBuddyResource *jbr);
+char *jabber_google_presence_outgoing(PurpleStatus *tune);
+
+
+#endif /* PURPLE_JABBER_GOOGLE_PRESENCE_H_ */ \ No newline at end of file
diff --git a/libpurple/protocols/jabber/google/google_roster.c b/libpurple/protocols/jabber/google/google_roster.c
new file mode 100644
index 0000000000..cca6320f14
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google_roster.c
@@ -0,0 +1,206 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "google_roster.h"
+#include "jabber.h"
+#include "presence.h"
+#include "debug.h"
+#include "xmlnode.h"
+
+void jabber_google_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *item)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ GSList *list = account->deny;
+ const char *jid = xmlnode_get_attrib(item, "jid");
+ char *jid_norm = (char *)jabber_normalize(account, jid);
+
+ while (list) {
+ if (!strcmp(jid_norm, (char*)list->data)) {
+ xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
+ xmlnode_set_attrib(query, "gr:ext", "2");
+ xmlnode_set_attrib(item, "gr:t", "B");
+ return;
+ }
+ list = list->next;
+ }
+}
+
+gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item)
+{
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ const char *jid = xmlnode_get_attrib(item, "jid");
+ gboolean on_block_list = FALSE;
+
+ char *jid_norm;
+
+ const char *grt = xmlnode_get_attrib_with_namespace(item, "t", NS_GOOGLE_ROSTER);
+ const char *subscription = xmlnode_get_attrib(item, "subscription");
+ const char *ask = xmlnode_get_attrib(item, "ask");
+
+ if ((!subscription || !strcmp(subscription, "none")) && !ask) {
+ /* The Google Talk servers will automatically add people from your Gmail address book
+ * with subscription=none. If we see someone with subscription=none, ignore them.
+ */
+ return FALSE;
+ }
+
+ jid_norm = g_strdup(jabber_normalize(account, jid));
+
+ on_block_list = NULL != g_slist_find_custom(account->deny, jid_norm,
+ (GCompareFunc)strcmp);
+
+ if (grt && (*grt == 'H' || *grt == 'h')) {
+ /* Hidden; don't show this buddy. */
+ GSList *buddies = purple_find_buddies(account, jid_norm);
+ if (buddies)
+ purple_debug_info("jabber", "Removing %s from local buddy list\n",
+ jid_norm);
+
+ for ( ; buddies; buddies = g_slist_delete_link(buddies, buddies)) {
+ purple_blist_remove_buddy(buddies->data);
+ }
+
+ g_free(jid_norm);
+ return FALSE;
+ }
+
+ if (!on_block_list && (grt && (*grt == 'B' || *grt == 'b'))) {
+ purple_debug_info("jabber", "Blocking %s\n", jid_norm);
+ purple_privacy_deny_add(account, jid_norm, TRUE);
+ } else if (on_block_list && (!grt || (*grt != 'B' && *grt != 'b' ))){
+ purple_debug_info("jabber", "Unblocking %s\n", jid_norm);
+ purple_privacy_deny_remove(account, jid_norm, TRUE);
+ }
+
+ g_free(jid_norm);
+ return TRUE;
+}
+
+void jabber_google_roster_add_deny(JabberStream *js, const char *who)
+{
+ PurpleAccount *account;
+ GSList *buddies;
+ JabberIq *iq;
+ xmlnode *query;
+ xmlnode *item;
+ xmlnode *group;
+ PurpleBuddy *b;
+ JabberBuddy *jb;
+ const char *balias;
+
+ jb = jabber_buddy_find(js, who, TRUE);
+
+ account = purple_connection_get_account(js->gc);
+ buddies = purple_find_buddies(account, who);
+ if(!buddies)
+ return;
+
+ b = buddies->data;
+
+ iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
+
+ query = xmlnode_get_child(iq->node, "query");
+ item = xmlnode_new_child(query, "item");
+
+ while(buddies) {
+ PurpleGroup *g;
+
+ b = buddies->data;
+ g = purple_buddy_get_group(b);
+
+ group = xmlnode_new_child(item, "group");
+ xmlnode_insert_data(group, purple_group_get_name(g), -1);
+
+ buddies = buddies->next;
+ }
+
+ balias = purple_buddy_get_local_buddy_alias(b);
+ xmlnode_set_attrib(item, "jid", who);
+ xmlnode_set_attrib(item, "name", balias ? balias : "");
+ xmlnode_set_attrib(item, "gr:t", "B");
+ xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
+ xmlnode_set_attrib(query, "gr:ext", "2");
+
+ jabber_iq_send(iq);
+
+ /* Synthesize a sign-off */
+ if (jb) {
+ JabberBuddyResource *jbr;
+ GList *l = jb->resources;
+ while (l) {
+ jbr = l->data;
+ if (jbr && jbr->name)
+ {
+ purple_debug_misc("jabber", "Removing resource %s\n", jbr->name);
+ jabber_buddy_remove_resource(jb, jbr->name);
+ }
+ l = l->next;
+ }
+ }
+
+ purple_prpl_got_user_status(account, who, "offline", NULL);
+}
+
+void jabber_google_roster_rem_deny(JabberStream *js, const char *who)
+{
+ GSList *buddies;
+ JabberIq *iq;
+ xmlnode *query;
+ xmlnode *item;
+ xmlnode *group;
+ PurpleBuddy *b;
+ const char *balias;
+
+ buddies = purple_find_buddies(purple_connection_get_account(js->gc), who);
+ if(!buddies)
+ return;
+
+ b = buddies->data;
+
+ iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
+
+ query = xmlnode_get_child(iq->node, "query");
+ item = xmlnode_new_child(query, "item");
+
+ while(buddies) {
+ PurpleGroup *g;
+
+ b = buddies->data;
+ g = purple_buddy_get_group(b);
+
+ group = xmlnode_new_child(item, "group");
+ xmlnode_insert_data(group, purple_group_get_name(g), -1);
+
+ buddies = buddies->next;
+ }
+
+ balias = purple_buddy_get_local_buddy_alias(b);
+ xmlnode_set_attrib(item, "jid", who);
+ xmlnode_set_attrib(item, "name", balias ? balias : "");
+ xmlnode_set_attrib(query, "xmlns:gr", NS_GOOGLE_ROSTER);
+ xmlnode_set_attrib(query, "gr:ext", "2");
+
+ jabber_iq_send(iq);
+
+ /* See if he's online */
+ jabber_presence_subscription_set(js, who, "probe");
+}
+
diff --git a/libpurple/protocols/jabber/google.h b/libpurple/protocols/jabber/google/google_roster.h
index 3439fbf927..34f6fa5d8c 100644
--- a/libpurple/protocols/jabber/google.h
+++ b/libpurple/protocols/jabber/google/google_roster.h
@@ -18,20 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#ifndef PURPLE_JABBER_GOOGLE_H_
-#define PURPLE_JABBER_GOOGLE_H_
-
-/* This is a place for Google Talk-specific XMPP extensions to live
- * such that they don't intermingle with code for the XMPP RFCs and XEPs :) */
+#ifndef PURPLE_JABBER_GOOGLE_ROSTER_H_
+#define PURPLE_JABBER_GOOGLE_ROSTER_H_
#include "jabber.h"
-#define GOOGLE_GROUPCHAT_SERVER "groupchat.google.com"
-
-void jabber_gmail_init(JabberStream *js);
-void jabber_gmail_poke(JabberStream *js, const char *from, JabberIqType type,
- const char *id, xmlnode *new_mail);
-
void jabber_google_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *item);
/* Returns FALSE if this should short-circuit processing of this roster item, or TRUE
@@ -39,22 +30,8 @@ void jabber_google_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *it
*/
gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item);
-void jabber_google_presence_incoming(JabberStream *js, const char *who, JabberBuddyResource *jbr);
-char *jabber_google_presence_outgoing(PurpleStatus *tune);
-
void jabber_google_roster_add_deny(JabberStream *js, const char *who);
void jabber_google_roster_rem_deny(JabberStream *js, const char *who);
-char *jabber_google_format_to_html(const char *text);
-
-gboolean jabber_google_session_initiate(JabberStream *js, const gchar *who, PurpleMediaSessionType type);
-void jabber_google_session_parse(JabberStream *js, const char *from, JabberIqType type, const char *iq, xmlnode *session);
-
-void jabber_google_handle_jingle_info(JabberStream *js, const char *from,
- JabberIqType type, const char *id,
- xmlnode *child);
-void jabber_google_send_jingle_info(JabberStream *js);
-
-void google_buddy_node_chat(PurpleBlistNode *node, gpointer data);
-#endif /* PURPLE_JABBER_GOOGLE_H_ */
+#endif /* PURPLE_JABBER_GOOGLE_ROSTER_H_ */
diff --git a/libpurple/protocols/jabber/google/google_session.c b/libpurple/protocols/jabber/google/google_session.c
new file mode 100644
index 0000000000..12faf31869
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google_session.c
@@ -0,0 +1,866 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+#include "google_session.h"
+#include "relay.h"
+
+#include "jingle/jingle.h"
+
+#ifdef USE_VV
+
+typedef struct {
+ PurpleMedia *media;
+ gboolean video;
+ GList *remote_audio_candidates; /* list of PurpleMediaCandidate */
+ GList *remote_video_candidates; /* list of PurpleMediaCandidate */
+ gboolean added_streams; /* this indicates if the streams have been
+ to media (ie. after getting relay credentials */
+} GoogleAVSessionData;
+
+static gboolean
+google_session_id_equal(gconstpointer a, gconstpointer b)
+{
+ GoogleSessionId *c = (GoogleSessionId*)a;
+ GoogleSessionId *d = (GoogleSessionId*)b;
+
+ return !strcmp(c->id, d->id) && !strcmp(c->initiator, d->initiator);
+}
+
+static void
+google_session_destroy(GoogleSession *session)
+{
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+ g_free(session->id.id);
+ g_free(session->id.initiator);
+ g_free(session->remote_jid);
+
+ if (session_data->remote_audio_candidates)
+ purple_media_candidate_list_free(session_data->remote_audio_candidates);
+
+ if (session_data->remote_video_candidates)
+ purple_media_candidate_list_free(session_data->remote_video_candidates);
+
+ g_free(session->session_data);
+ g_free(session);
+}
+
+static xmlnode *
+google_session_create_xmlnode(GoogleSession *session, const char *type)
+{
+ xmlnode *node = xmlnode_new("session");
+ xmlnode_set_namespace(node, NS_GOOGLE_SESSION);
+ xmlnode_set_attrib(node, "id", session->id.id);
+ xmlnode_set_attrib(node, "initiator", session->id.initiator);
+ xmlnode_set_attrib(node, "type", type);
+ return node;
+}
+
+static void
+google_session_send_candidates(PurpleMedia *media, gchar *session_id,
+ gchar *participant, GoogleSession *session)
+{
+ PurpleMedia *session_media =
+ ((GoogleAVSessionData *) session->session_data)->media;
+ GList *candidates =
+ purple_media_get_local_candidates(session_media, session_id,
+ session->remote_jid);
+ GList *iter;
+ PurpleMediaCandidate *transport;
+ gboolean video = FALSE;
+
+ if (!strcmp(session_id, "google-video"))
+ video = TRUE;
+
+ for (iter = candidates; iter; iter = iter->next) {
+ JabberIq *iq;
+ gchar *ip, *port, *username, *password;
+ gchar pref[16];
+ PurpleMediaCandidateType type;
+ xmlnode *sess;
+ xmlnode *candidate;
+ guint component_id;
+ transport = PURPLE_MEDIA_CANDIDATE(iter->data);
+ component_id = purple_media_candidate_get_component_id(
+ transport);
+
+ iq = jabber_iq_new(session->js, JABBER_IQ_SET);
+ sess = google_session_create_xmlnode(session, "candidates");
+ xmlnode_insert_child(iq->node, sess);
+ xmlnode_set_attrib(iq->node, "to", session->remote_jid);
+
+ candidate = xmlnode_new("candidate");
+
+ ip = purple_media_candidate_get_ip(transport);
+ port = g_strdup_printf("%d",
+ purple_media_candidate_get_port(transport));
+ g_ascii_dtostr(pref, 16,
+ purple_media_candidate_get_priority(transport) / 1000.0);
+ username = purple_media_candidate_get_username(transport);
+ password = purple_media_candidate_get_password(transport);
+ type = purple_media_candidate_get_candidate_type(transport);
+
+ xmlnode_set_attrib(candidate, "address", ip);
+ xmlnode_set_attrib(candidate, "port", port);
+ xmlnode_set_attrib(candidate, "name",
+ component_id == PURPLE_MEDIA_COMPONENT_RTP ?
+ video ? "video_rtp" : "rtp" :
+ component_id == PURPLE_MEDIA_COMPONENT_RTCP ?
+ video ? "video_rtcp" : "rtcp" : "none");
+ xmlnode_set_attrib(candidate, "username", username);
+ /*
+ * As of this writing, Farsight 2 in Google compatibility
+ * mode doesn't provide a password. The Gmail client
+ * requires this to be set.
+ */
+ xmlnode_set_attrib(candidate, "password",
+ password != NULL ? password : "");
+ xmlnode_set_attrib(candidate, "preference", pref);
+ xmlnode_set_attrib(candidate, "protocol",
+ purple_media_candidate_get_protocol(transport)
+ == PURPLE_MEDIA_NETWORK_PROTOCOL_UDP ?
+ "udp" : "tcp");
+ xmlnode_set_attrib(candidate, "type", type ==
+ PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "local" :
+ type ==
+ PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "stun" :
+ type ==
+ PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" :
+ NULL);
+ xmlnode_set_attrib(candidate, "generation", "0");
+ xmlnode_set_attrib(candidate, "network", "0");
+ xmlnode_insert_child(sess, candidate);
+
+ g_free(ip);
+ g_free(port);
+ g_free(username);
+ g_free(password);
+
+ jabber_iq_send(iq);
+ }
+ purple_media_candidate_list_free(candidates);
+}
+
+static void
+google_session_ready(GoogleSession *session)
+{
+ PurpleMedia *media =
+ ((GoogleAVSessionData *)session->session_data)->media;
+ gboolean video =
+ ((GoogleAVSessionData *)session->session_data)->video;
+ if (purple_media_codecs_ready(media, NULL) &&
+ purple_media_candidates_prepared(media, NULL, NULL)) {
+ gchar *me = g_strdup_printf("%s@%s/%s",
+ session->js->user->node,
+ session->js->user->domain,
+ session->js->user->resource);
+ JabberIq *iq;
+ xmlnode *sess, *desc, *payload;
+ GList *codecs, *iter;
+ gboolean is_initiator = !strcmp(session->id.initiator, me);
+
+ if (!is_initiator &&
+ !purple_media_accepted(media, NULL, NULL)) {
+ g_free(me);
+ return;
+ }
+
+ iq = jabber_iq_new(session->js, JABBER_IQ_SET);
+
+ if (is_initiator) {
+ xmlnode_set_attrib(iq->node, "to", session->remote_jid);
+ xmlnode_set_attrib(iq->node, "from", session->id.initiator);
+ sess = google_session_create_xmlnode(session, "initiate");
+ } else {
+ google_session_send_candidates(media,
+ "google-voice", session->remote_jid,
+ session);
+ google_session_send_candidates(media,
+ "google-video", session->remote_jid,
+ session);
+ xmlnode_set_attrib(iq->node, "to", session->remote_jid);
+ xmlnode_set_attrib(iq->node, "from", me);
+ sess = google_session_create_xmlnode(session, "accept");
+ }
+ xmlnode_insert_child(iq->node, sess);
+ desc = xmlnode_new_child(sess, "description");
+ if (video)
+ xmlnode_set_namespace(desc, NS_GOOGLE_SESSION_VIDEO);
+ else
+ xmlnode_set_namespace(desc, NS_GOOGLE_SESSION_PHONE);
+
+ codecs = purple_media_get_codecs(media, "google-video");
+
+ for (iter = codecs; iter; iter = g_list_next(iter)) {
+ PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data;
+ gchar *id = g_strdup_printf("%d",
+ purple_media_codec_get_id(codec));
+ gchar *encoding_name =
+ purple_media_codec_get_encoding_name(codec);
+ payload = xmlnode_new_child(desc, "payload-type");
+ xmlnode_set_attrib(payload, "id", id);
+ xmlnode_set_attrib(payload, "name", encoding_name);
+ xmlnode_set_attrib(payload, "width", "320");
+ xmlnode_set_attrib(payload, "height", "200");
+ xmlnode_set_attrib(payload, "framerate", "30");
+ g_free(encoding_name);
+ g_free(id);
+ }
+ purple_media_codec_list_free(codecs);
+
+ codecs = purple_media_get_codecs(media, "google-voice");
+
+ for (iter = codecs; iter; iter = g_list_next(iter)) {
+ PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data;
+ gchar *id = g_strdup_printf("%d",
+ purple_media_codec_get_id(codec));
+ gchar *encoding_name =
+ purple_media_codec_get_encoding_name(codec);
+ gchar *clock_rate = g_strdup_printf("%d",
+ purple_media_codec_get_clock_rate(codec));
+ payload = xmlnode_new_child(desc, "payload-type");
+ if (video)
+ xmlnode_set_namespace(payload, NS_GOOGLE_SESSION_PHONE);
+ xmlnode_set_attrib(payload, "id", id);
+ /*
+ * Hack to make Gmail accept speex as the codec.
+ * It shouldn't have to be case sensitive.
+ */
+ if (purple_strequal(encoding_name, "SPEEX"))
+ xmlnode_set_attrib(payload, "name", "speex");
+ else
+ xmlnode_set_attrib(payload, "name", encoding_name);
+ xmlnode_set_attrib(payload, "clockrate", clock_rate);
+ g_free(clock_rate);
+ g_free(encoding_name);
+ g_free(id);
+ }
+ purple_media_codec_list_free(codecs);
+
+ jabber_iq_send(iq);
+
+ if (is_initiator) {
+ google_session_send_candidates(media,
+ "google-voice", session->remote_jid,
+ session);
+ google_session_send_candidates(media,
+ "google-video", session->remote_jid,
+ session);
+ }
+
+ g_signal_handlers_disconnect_by_func(G_OBJECT(media),
+ G_CALLBACK(google_session_ready), session);
+ }
+}
+
+static void
+google_session_state_changed_cb(PurpleMedia *media, PurpleMediaState state,
+ gchar *sid, gchar *name, GoogleSession *session)
+{
+ if (sid == NULL && name == NULL) {
+ if (state == PURPLE_MEDIA_STATE_END) {
+ google_session_destroy(session);
+ }
+ }
+}
+
+static void
+google_session_stream_info_cb(PurpleMedia *media, PurpleMediaInfoType type,
+ gchar *sid, gchar *name, gboolean local,
+ GoogleSession *session)
+{
+ if (sid != NULL || name != NULL)
+ return;
+
+ if (type == PURPLE_MEDIA_INFO_HANGUP) {
+ xmlnode *sess;
+ JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET);
+
+ xmlnode_set_attrib(iq->node, "to", session->remote_jid);
+ sess = google_session_create_xmlnode(session, "terminate");
+ xmlnode_insert_child(iq->node, sess);
+
+ jabber_iq_send(iq);
+ } else if (type == PURPLE_MEDIA_INFO_REJECT) {
+ xmlnode *sess;
+ JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET);
+
+ xmlnode_set_attrib(iq->node, "to", session->remote_jid);
+ sess = google_session_create_xmlnode(session, "reject");
+ xmlnode_insert_child(iq->node, sess);
+
+ jabber_iq_send(iq);
+ } else if (type == PURPLE_MEDIA_INFO_ACCEPT && local == TRUE) {
+ google_session_ready(session);
+ }
+}
+
+static GParameter *
+jabber_google_session_get_params(JabberStream *js, const gchar *relay_ip,
+ guint16 relay_udp, guint16 relay_tcp, guint16 relay_ssltcp,
+ const gchar *relay_username, const gchar *relay_password, guint *num)
+{
+ guint num_params;
+ GParameter *params =
+ jingle_get_params(js, relay_ip, relay_udp, relay_tcp, relay_ssltcp,
+ relay_username, relay_password, &num_params);
+ GParameter *new_params = g_new0(GParameter, num_params + 1);
+
+ memcpy(new_params, params, sizeof(GParameter) * num_params);
+
+ purple_debug_info("jabber", "setting Google jingle compatibility param\n");
+ new_params[num_params].name = "compatibility-mode";
+ g_value_init(&new_params[num_params].value, G_TYPE_UINT);
+ g_value_set_uint(&new_params[num_params].value, 1); /* NICE_COMPATIBILITY_GOOGLE */
+
+ g_free(params);
+ *num = num_params + 1;
+ return new_params;
+}
+
+
+static void
+jabber_google_relay_response_session_initiate_cb(GoogleSession *session,
+ const gchar *relay_ip, guint relay_udp, guint relay_tcp, guint relay_ssltcp,
+ const gchar *relay_username, const gchar *relay_password)
+{
+ GParameter *params;
+ guint num_params;
+ JabberStream *js = session->js;
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+
+ session_data->media = purple_media_manager_create_media(
+ purple_media_manager_get(),
+ purple_connection_get_account(js->gc),
+ "fsrtpconference", session->remote_jid, TRUE);
+
+ purple_media_set_prpl_data(session_data->media, session);
+
+ g_signal_connect_swapped(G_OBJECT(session_data->media),
+ "candidates-prepared",
+ G_CALLBACK(google_session_ready), session);
+ g_signal_connect_swapped(G_OBJECT(session_data->media), "codecs-changed",
+ G_CALLBACK(google_session_ready), session);
+ g_signal_connect(G_OBJECT(session_data->media), "state-changed",
+ G_CALLBACK(google_session_state_changed_cb), session);
+ g_signal_connect(G_OBJECT(session_data->media), "stream-info",
+ G_CALLBACK(google_session_stream_info_cb), session);
+
+ params =
+ jabber_google_session_get_params(js, relay_ip, relay_udp, relay_tcp,
+ relay_ssltcp, relay_username, relay_password, &num_params);
+
+ if (purple_media_add_stream(session_data->media, "google-voice",
+ session->remote_jid, PURPLE_MEDIA_AUDIO,
+ TRUE, "nice", num_params, params) == FALSE ||
+ (session_data->video && purple_media_add_stream(
+ session_data->media, "google-video",
+ session->remote_jid, PURPLE_MEDIA_VIDEO,
+ TRUE, "nice", num_params, params) == FALSE)) {
+ purple_media_error(session_data->media, "Error adding stream.");
+ purple_media_end(session_data->media, NULL, NULL);
+ g_free(params);
+ } else {
+ session_data->added_streams = TRUE;
+ }
+
+ g_free(params);
+}
+
+
+gboolean
+jabber_google_session_initiate(JabberStream *js, const gchar *who, PurpleMediaSessionType type)
+{
+ GoogleSession *session;
+ JabberBuddy *jb;
+ JabberBuddyResource *jbr;
+ gchar *jid;
+ GoogleAVSessionData *session_data = NULL;
+
+ /* construct JID to send to */
+ jb = jabber_buddy_find(js, who, FALSE);
+ if (!jb) {
+ purple_debug_error("jingle-rtp",
+ "Could not find Jabber buddy\n");
+ return FALSE;
+ }
+ jbr = jabber_buddy_find_resource(jb, NULL);
+ if (!jbr) {
+ purple_debug_error("jingle-rtp",
+ "Could not find buddy's resource\n");
+ }
+
+ if ((strchr(who, '/') == NULL) && jbr && (jbr->name != NULL)) {
+ jid = g_strdup_printf("%s/%s", who, jbr->name);
+ } else {
+ jid = g_strdup(who);
+ }
+
+ session = g_new0(GoogleSession, 1);
+ session->id.id = jabber_get_next_id(js);
+ session->id.initiator = g_strdup_printf("%s@%s/%s", js->user->node,
+ js->user->domain, js->user->resource);
+ session->state = SENT_INITIATE;
+ session->js = js;
+ session->remote_jid = jid;
+ session_data = g_new0(GoogleAVSessionData, 1);
+ session->session_data = session_data;
+
+ if (type & PURPLE_MEDIA_VIDEO)
+ session_data->video = TRUE;
+
+ /* if we got a relay token and relay host in google:jingleinfo, issue an
+ HTTP request to get that data */
+ if (js->google_relay_host && js->google_relay_token) {
+ jabber_google_do_relay_request(js, session,
+ jabber_google_relay_response_session_initiate_cb);
+ } else {
+ jabber_google_relay_response_session_initiate_cb(session, NULL, 0, 0, 0,
+ NULL, NULL);
+ }
+
+ /* we don't actually know yet wether it succeeded... maybe this is very
+ wrong... */
+ return TRUE;
+}
+
+static void
+jabber_google_relay_response_session_handle_initiate_cb(GoogleSession *session,
+ const gchar *relay_ip, guint relay_udp, guint relay_tcp, guint relay_ssltcp,
+ const gchar *relay_username, const gchar *relay_password)
+{
+ GParameter *params;
+ guint num_params;
+ JabberStream *js = session->js;
+ xmlnode *codec_element;
+ xmlnode *desc_element;
+ const gchar *xmlns;
+ PurpleMediaCodec *codec;
+ GList *video_codecs = NULL;
+ GList *codecs = NULL;
+ JabberIq *result;
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+
+ params =
+ jabber_google_session_get_params(js, relay_ip, relay_udp, relay_tcp,
+ relay_ssltcp, relay_username, relay_password, &num_params);
+
+ if (purple_media_add_stream(session_data->media, "google-voice",
+ session->remote_jid, PURPLE_MEDIA_AUDIO, FALSE,
+ "nice", num_params, params) == FALSE ||
+ (session_data->video && purple_media_add_stream(
+ session_data->media, "google-video",
+ session->remote_jid, PURPLE_MEDIA_VIDEO,
+ FALSE, "nice", num_params, params) == FALSE)) {
+ purple_media_error(session_data->media, "Error adding stream.");
+ purple_media_stream_info(session_data->media,
+ PURPLE_MEDIA_INFO_REJECT, NULL, NULL, TRUE);
+ } else {
+ /* successfully added stream(s) */
+ session_data->added_streams = TRUE;
+
+ if (session_data->remote_audio_candidates) {
+ purple_media_add_remote_candidates(session_data->media,
+ "google-voice", session->remote_jid,
+ session_data->remote_audio_candidates);
+ purple_media_candidate_list_free(session_data->remote_audio_candidates);
+ session_data->remote_audio_candidates = NULL;
+ }
+ if (session_data->remote_video_candidates) {
+ purple_media_add_remote_candidates(session_data->media,
+ "google-video", session->remote_jid,
+ session_data->remote_video_candidates);
+ purple_media_candidate_list_free(session_data->remote_video_candidates);
+ session_data->remote_video_candidates = NULL;
+ }
+ }
+
+ g_free(params);
+
+ for (codec_element = xmlnode_get_child(desc_element, "payload-type");
+ codec_element; codec_element = codec_element->next) {
+ const char *id, *encoding_name, *clock_rate,
+ *width, *height, *framerate;
+ gboolean video;
+ if (codec_element->name &&
+ strcmp(codec_element->name, "payload-type"))
+ continue;
+
+ xmlns = xmlnode_get_namespace(codec_element);
+ encoding_name = xmlnode_get_attrib(codec_element, "name");
+ id = xmlnode_get_attrib(codec_element, "id");
+
+ if (!session_data->video ||
+ (xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_PHONE))) {
+ clock_rate = xmlnode_get_attrib(
+ codec_element, "clockrate");
+ video = FALSE;
+ } else {
+ width = xmlnode_get_attrib(codec_element, "width");
+ height = xmlnode_get_attrib(codec_element, "height");
+ framerate = xmlnode_get_attrib(
+ codec_element, "framerate");
+ clock_rate = "90000";
+ video = TRUE;
+ }
+
+ if (id) {
+ codec = purple_media_codec_new(atoi(id), encoding_name,
+ video ? PURPLE_MEDIA_VIDEO :
+ PURPLE_MEDIA_AUDIO,
+ clock_rate ? atoi(clock_rate) : 0);
+ if (video)
+ video_codecs = g_list_append(
+ video_codecs, codec);
+ else
+ codecs = g_list_append(codecs, codec);
+ }
+ }
+
+ if (codecs)
+ purple_media_set_remote_codecs(session_data->media, "google-voice",
+ session->remote_jid, codecs);
+ if (video_codecs)
+ purple_media_set_remote_codecs(session_data->media, "google-video",
+ session->remote_jid, video_codecs);
+
+ purple_media_codec_list_free(codecs);
+ purple_media_codec_list_free(video_codecs);
+
+ result = jabber_iq_new(js, JABBER_IQ_RESULT);
+ jabber_iq_set_id(result, session->iq_id);
+ xmlnode_set_attrib(result->node, "to", session->remote_jid);
+ jabber_iq_send(result);
+}
+
+static gboolean
+google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
+{
+ xmlnode *desc_element;
+ const gchar *xmlns;
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+
+ if (session->state != UNINIT) {
+ purple_debug_error("jabber", "Received initiate for active session.\n");
+ return FALSE;
+ }
+
+ desc_element = xmlnode_get_child(sess, "description");
+ xmlns = xmlnode_get_namespace(desc_element);
+
+ if (purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE))
+ session_data->video = FALSE;
+ else if (purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO))
+ session_data->video = TRUE;
+ else {
+ purple_debug_error("jabber", "Received initiate with "
+ "invalid namespace %s.\n", xmlns);
+ return FALSE;
+ }
+
+ session_data->media = purple_media_manager_create_media(
+ purple_media_manager_get(),
+ purple_connection_get_account(js->gc),
+ "fsrtpconference", session->remote_jid, FALSE);
+
+ purple_media_set_prpl_data(session_data->media, session);
+
+ g_signal_connect_swapped(G_OBJECT(session_data->media),
+ "candidates-prepared",
+ G_CALLBACK(google_session_ready), session);
+ g_signal_connect_swapped(G_OBJECT(session_data->media), "codecs-changed",
+ G_CALLBACK(google_session_ready), session);
+ g_signal_connect(G_OBJECT(session_data->media), "state-changed",
+ G_CALLBACK(google_session_state_changed_cb), session);
+ g_signal_connect(G_OBJECT(session_data->media), "stream-info",
+ G_CALLBACK(google_session_stream_info_cb), session);
+
+ session->iq_id = g_strdup(iq_id);
+
+ if (js->google_relay_host && js->google_relay_token) {
+ jabber_google_do_relay_request(js, session,
+ jabber_google_relay_response_session_handle_initiate_cb);
+ } else {
+ jabber_google_relay_response_session_handle_initiate_cb(session, NULL,
+ 0, 0, 0, NULL, NULL);
+ }
+
+ return TRUE;
+}
+
+
+static void
+google_session_handle_candidates(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
+{
+ JabberIq *result;
+ GList *list = NULL, *video_list = NULL;
+ xmlnode *cand;
+ static int name = 0;
+ char n[4];
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+
+ for (cand = xmlnode_get_child(sess, "candidate"); cand;
+ cand = xmlnode_get_next_twin(cand)) {
+ PurpleMediaCandidate *info;
+ const gchar *cname = xmlnode_get_attrib(cand, "name");
+ const gchar *type = xmlnode_get_attrib(cand, "type");
+ const gchar *protocol = xmlnode_get_attrib(cand, "protocol");
+ const gchar *address = xmlnode_get_attrib(cand, "address");
+ const gchar *port = xmlnode_get_attrib(cand, "port");
+ const gchar *preference = xmlnode_get_attrib(cand, "preference");
+ guint component_id;
+
+ if (cname && type && address && port) {
+ PurpleMediaCandidateType candidate_type;
+ guint prio = preference ? atof(preference) * 1000 : 0;
+
+ g_snprintf(n, sizeof(n), "S%d", name++);
+
+ if (g_str_equal(type, "local"))
+ candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
+ else if (g_str_equal(type, "stun"))
+ candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX;
+ else if (g_str_equal(type, "relay"))
+ candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_RELAY;
+ else
+ candidate_type = PURPLE_MEDIA_CANDIDATE_TYPE_HOST;
+
+ if (purple_strequal(cname, "rtcp") ||
+ purple_strequal(cname, "video_rtcp"))
+ component_id = PURPLE_MEDIA_COMPONENT_RTCP;
+ else
+ component_id = PURPLE_MEDIA_COMPONENT_RTP;
+
+ info = purple_media_candidate_new(n, component_id,
+ candidate_type,
+ purple_strequal(protocol, "udp") ?
+ PURPLE_MEDIA_NETWORK_PROTOCOL_UDP :
+ PURPLE_MEDIA_NETWORK_PROTOCOL_TCP,
+ address,
+ atoi(port));
+ g_object_set(info, "username", xmlnode_get_attrib(cand, "username"),
+ "password", xmlnode_get_attrib(cand, "password"),
+ "priority", prio, NULL);
+ if (!strncmp(cname, "video_", 6)) {
+ if (session_data->added_streams) {
+ video_list = g_list_append(video_list, info);
+ } else {
+ session_data->remote_video_candidates =
+ g_list_append(session_data->remote_video_candidates,
+ info);
+ }
+ } else {
+ if (session_data->added_streams) {
+ list = g_list_append(list, info);
+ } else {
+ session_data->remote_audio_candidates =
+ g_list_append(session_data->remote_audio_candidates,
+ info);
+ }
+ }
+ }
+ }
+
+ if (list) {
+ purple_media_add_remote_candidates(session_data->media, "google-voice",
+ session->remote_jid, list);
+ purple_media_candidate_list_free(list);
+ }
+ if (video_list) {
+ purple_media_add_remote_candidates(session_data->media, "google-video",
+ session->remote_jid, video_list);
+ purple_media_candidate_list_free(video_list);
+ }
+
+ result = jabber_iq_new(js, JABBER_IQ_RESULT);
+ jabber_iq_set_id(result, iq_id);
+ xmlnode_set_attrib(result->node, "to", session->remote_jid);
+ jabber_iq_send(result);
+}
+
+static void
+google_session_handle_accept(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
+{
+ xmlnode *desc_element = xmlnode_get_child(sess, "description");
+ xmlnode *codec_element = xmlnode_get_child(
+ desc_element, "payload-type");
+ GList *codecs = NULL, *video_codecs = NULL;
+ JabberIq *result = NULL;
+ const gchar *xmlns = xmlnode_get_namespace(desc_element);
+ gboolean video = (xmlns && !strcmp(xmlns, NS_GOOGLE_SESSION_VIDEO));
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+
+ for (; codec_element; codec_element = codec_element->next) {
+ const gchar *xmlns, *encoding_name, *id,
+ *clock_rate, *width, *height, *framerate;
+ gboolean video_codec = FALSE;
+
+ if (!purple_strequal(codec_element->name, "payload-type"))
+ continue;
+
+ xmlns = xmlnode_get_namespace(codec_element);
+ encoding_name = xmlnode_get_attrib(codec_element, "name");
+ id = xmlnode_get_attrib(codec_element, "id");
+
+ if (!video || purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE))
+ clock_rate = xmlnode_get_attrib(
+ codec_element, "clockrate");
+ else {
+ clock_rate = "90000";
+ width = xmlnode_get_attrib(codec_element, "width");
+ height = xmlnode_get_attrib(codec_element, "height");
+ framerate = xmlnode_get_attrib(
+ codec_element, "framerate");
+ video_codec = TRUE;
+ }
+
+ if (id && encoding_name) {
+ PurpleMediaCodec *codec = purple_media_codec_new(
+ atoi(id), encoding_name,
+ video_codec ? PURPLE_MEDIA_VIDEO :
+ PURPLE_MEDIA_AUDIO,
+ clock_rate ? atoi(clock_rate) : 0);
+ if (video_codec)
+ video_codecs = g_list_append(
+ video_codecs, codec);
+ else
+ codecs = g_list_append(codecs, codec);
+ }
+ }
+
+ if (codecs)
+ purple_media_set_remote_codecs(session_data->media, "google-voice",
+ session->remote_jid, codecs);
+ if (video_codecs)
+ purple_media_set_remote_codecs(session_data->media, "google-video",
+ session->remote_jid, video_codecs);
+
+ purple_media_stream_info(session_data->media, PURPLE_MEDIA_INFO_ACCEPT,
+ NULL, NULL, FALSE);
+
+ result = jabber_iq_new(js, JABBER_IQ_RESULT);
+ jabber_iq_set_id(result, iq_id);
+ xmlnode_set_attrib(result->node, "to", session->remote_jid);
+ jabber_iq_send(result);
+}
+
+static void
+google_session_handle_reject(JabberStream *js, GoogleSession *session, xmlnode *sess)
+{
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+ purple_media_end(session_data->media, NULL, NULL);
+}
+
+static void
+google_session_handle_terminate(JabberStream *js, GoogleSession *session, xmlnode *sess)
+{
+ GoogleAVSessionData *session_data =
+ (GoogleAVSessionData *) session->session_data;
+ purple_media_end(session_data->media, NULL, NULL);
+}
+
+static void
+google_session_parse_iq(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
+{
+ const char *type = xmlnode_get_attrib(sess, "type");
+
+ if (!strcmp(type, "initiate")) {
+ google_session_handle_initiate(js, session, sess, iq_id);
+ } else if (!strcmp(type, "accept")) {
+ google_session_handle_accept(js, session, sess, iq_id);
+ } else if (!strcmp(type, "reject")) {
+ google_session_handle_reject(js, session, sess);
+ } else if (!strcmp(type, "terminate")) {
+ google_session_handle_terminate(js, session, sess);
+ } else if (!strcmp(type, "candidates")) {
+ google_session_handle_candidates(js, session, sess, iq_id);
+ }
+}
+
+void
+jabber_google_session_parse(JabberStream *js, const char *from,
+ JabberIqType type, const char *iq_id,
+ xmlnode *session_node)
+{
+ GoogleSession *session = NULL;
+ GoogleSessionId id;
+
+ xmlnode *desc_node;
+
+ GList *iter = NULL;
+
+ if (type != JABBER_IQ_SET)
+ return;
+
+ id.id = (gchar*)xmlnode_get_attrib(session_node, "id");
+ if (!id.id)
+ return;
+
+ id.initiator = (gchar*)xmlnode_get_attrib(session_node, "initiator");
+ if (!id.initiator)
+ return;
+
+ iter = purple_media_manager_get_media_by_account(
+ purple_media_manager_get(),
+ purple_connection_get_account(js->gc));
+ for (; iter; iter = g_list_delete_link(iter, iter)) {
+ GoogleSession *gsession =
+ purple_media_get_prpl_data(iter->data);
+ if (google_session_id_equal(&(gsession->id), &id)) {
+ session = gsession;
+ break;
+ }
+ }
+ if (iter != NULL) {
+ g_list_free(iter);
+ }
+
+ if (session) {
+ google_session_parse_iq(js, session, session_node, iq_id);
+ return;
+ }
+
+ /* If the session doesn't exist, this has to be an initiate message */
+ if (strcmp(xmlnode_get_attrib(session_node, "type"), "initiate"))
+ return;
+ desc_node = xmlnode_get_child(session_node, "description");
+ if (!desc_node)
+ return;
+ session = g_new0(GoogleSession, 1);
+ session->id.id = g_strdup(id.id);
+ session->id.initiator = g_strdup(id.initiator);
+ session->state = UNINIT;
+ session->js = js;
+ session->remote_jid = g_strdup(session->id.initiator);
+ session->session_data = g_new0(GoogleAVSessionData, 1);
+
+ google_session_handle_initiate(js, session, session_node, iq_id);
+}
+#endif /* USE_VV */
+
+
diff --git a/libpurple/protocols/jabber/google/google_session.h b/libpurple/protocols/jabber/google/google_session.h
new file mode 100644
index 0000000000..1f8e7db26f
--- /dev/null
+++ b/libpurple/protocols/jabber/google/google_session.h
@@ -0,0 +1,54 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_JABBER_GOOGLE_SESSION_H_
+#define PURPLE_JABBER_GOOGLE_SESSION_H_
+
+#include "jabber.h"
+
+typedef struct {
+ char *id;
+ char *initiator;
+} GoogleSessionId;
+
+typedef enum {
+ UNINIT,
+ SENT_INITIATE,
+ RECEIVED_INITIATE,
+ IN_PRORESS,
+ TERMINATED
+} GoogleSessionState;
+
+typedef struct {
+ GoogleSessionId id;
+ GoogleSessionState state;
+ JabberStream *js;
+ char *remote_jid;
+ char *iq_id;
+ gpointer session_data;
+} GoogleSession;
+
+gboolean jabber_google_session_initiate(JabberStream *js, const gchar *who,
+ PurpleMediaSessionType type);
+
+void jabber_google_session_parse(JabberStream *js, const char *from,
+ JabberIqType type, const char *iq, xmlnode *session);
+
+#endif /* PURPLE_JABBER_GOOGLE_SESSION_H_ */ \ No newline at end of file
diff --git a/libpurple/protocols/jabber/google/jingleinfo.c b/libpurple/protocols/jabber/google/jingleinfo.c
new file mode 100644
index 0000000000..70ca49c24f
--- /dev/null
+++ b/libpurple/protocols/jabber/google/jingleinfo.c
@@ -0,0 +1,174 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+#include "jingleinfo.h"
+
+static void
+jabber_google_stun_lookup_cb(GSList *hosts, gpointer data,
+ const char *error_message)
+{
+ JabberStream *js = (JabberStream *) data;
+
+ if (error_message) {
+ purple_debug_error("jabber", "Google STUN lookup failed: %s\n",
+ error_message);
+ g_slist_free(hosts);
+ js->stun_query = NULL;
+ return;
+ }
+
+ if (hosts && g_slist_next(hosts)) {
+ struct sockaddr *addr = g_slist_next(hosts)->data;
+ char dst[INET6_ADDRSTRLEN];
+ int port;
+
+ if (addr->sa_family == AF_INET6) {
+ inet_ntop(addr->sa_family, &((struct sockaddr_in6 *) addr)->sin6_addr,
+ dst, sizeof(dst));
+ port = ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
+ } else {
+ inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr,
+ dst, sizeof(dst));
+ port = ntohs(((struct sockaddr_in *) addr)->sin_port);
+ }
+
+ if (js->stun_ip)
+ g_free(js->stun_ip);
+ js->stun_ip = g_strdup(dst);
+ js->stun_port = port;
+
+ purple_debug_info("jabber", "set Google STUN IP/port address: "
+ "%s:%d\n", dst, port);
+
+ /* unmark ongoing query */
+ js->stun_query = NULL;
+ }
+
+ while (hosts != NULL) {
+ hosts = g_slist_delete_link(hosts, hosts);
+ /* Free the address */
+ g_free(hosts->data);
+ hosts = g_slist_delete_link(hosts, hosts);
+ }
+}
+
+static void
+jabber_google_jingle_info_common(JabberStream *js, const char *from,
+ JabberIqType type, xmlnode *query)
+{
+ const xmlnode *stun = xmlnode_get_child(query, "stun");
+ const xmlnode *relay = xmlnode_get_child(query, "relay");
+ gchar *my_bare_jid;
+
+ /*
+ * Make sure that random people aren't sending us STUN servers. Per
+ * http://code.google.com/apis/talk/jep_extensions/jingleinfo.html, these
+ * stanzas are stamped from our bare JID.
+ */
+ if (from) {
+ my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain);
+ if (!purple_strequal(from, my_bare_jid)) {
+ purple_debug_warning("jabber", "got google:jingleinfo with invalid from (%s)\n",
+ from);
+ g_free(my_bare_jid);
+ return;
+ }
+
+ g_free(my_bare_jid);
+ }
+
+ if (type == JABBER_IQ_ERROR || type == JABBER_IQ_GET)
+ return;
+
+ purple_debug_info("jabber", "got google:jingleinfo\n");
+
+ if (stun) {
+ xmlnode *server = xmlnode_get_child(stun, "server");
+
+ if (server) {
+ const gchar *host = xmlnode_get_attrib(server, "host");
+ const gchar *udp = xmlnode_get_attrib(server, "udp");
+
+ if (host && udp) {
+ int port = atoi(udp);
+ /* if there, would already be an ongoing query,
+ cancel it */
+ if (js->stun_query)
+ purple_dnsquery_destroy(js->stun_query);
+
+ js->stun_query = purple_dnsquery_a(host, port,
+ jabber_google_stun_lookup_cb, js);
+ }
+ }
+ }
+
+ if (relay) {
+ xmlnode *token = xmlnode_get_child(relay, "token");
+ xmlnode *server = xmlnode_get_child(relay, "server");
+
+ if (token) {
+ gchar *relay_token = xmlnode_get_data(token);
+
+ /* we let js own the string returned from xmlnode_get_data */
+ js->google_relay_token = relay_token;
+ }
+
+ if (server) {
+ js->google_relay_host =
+ g_strdup(xmlnode_get_attrib(server, "host"));
+ }
+ }
+}
+
+static void
+jabber_google_jingle_info_cb(JabberStream *js, const char *from,
+ JabberIqType type, const char *id,
+ xmlnode *packet, gpointer data)
+{
+ xmlnode *query = xmlnode_get_child_with_namespace(packet, "query",
+ NS_GOOGLE_JINGLE_INFO);
+
+ if (query)
+ jabber_google_jingle_info_common(js, from, type, query);
+ else
+ purple_debug_warning("jabber", "Got invalid google:jingleinfo\n");
+}
+
+void
+jabber_google_handle_jingle_info(JabberStream *js, const char *from,
+ JabberIqType type, const char *id,
+ xmlnode *child)
+{
+ jabber_google_jingle_info_common(js, from, type, child);
+}
+
+void
+jabber_google_send_jingle_info(JabberStream *js)
+{
+ JabberIq *jingle_info =
+ jabber_iq_new_query(js, JABBER_IQ_GET, NS_GOOGLE_JINGLE_INFO);
+
+ jabber_iq_set_callback(jingle_info, jabber_google_jingle_info_cb,
+ NULL);
+ purple_debug_info("jabber", "sending google:jingleinfo query\n");
+ jabber_iq_send(jingle_info);
+}
diff --git a/libpurple/protocols/jabber/google/jingleinfo.h b/libpurple/protocols/jabber/google/jingleinfo.h
new file mode 100644
index 0000000000..e5f4da232b
--- /dev/null
+++ b/libpurple/protocols/jabber/google/jingleinfo.h
@@ -0,0 +1,32 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef PURPLE_JABBER_GOOGLE_ROSTER_H_
+#define PURPLE_JABBER_GOOGLE_ROSTER_H_
+
+#include "jabber.h"
+
+void jabber_google_handle_jingle_info(JabberStream *js, const char *from,
+ JabberIqType type, const char *id,
+ xmlnode *child);
+void jabber_google_send_jingle_info(JabberStream *js);
+
+
+#endif /* PURPLE_JABBER_GOOGLE_ROSTER_H_ */ \ No newline at end of file
diff --git a/libpurple/protocols/jabber/google/relay.c b/libpurple/protocols/jabber/google/relay.c
new file mode 100644
index 0000000000..79cf456eba
--- /dev/null
+++ b/libpurple/protocols/jabber/google/relay.c
@@ -0,0 +1,151 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "debug.h"
+
+#include "relay.h"
+
+typedef struct {
+ GoogleSession *session;
+ JabberGoogleRelayCallback *cb;
+} JabberGoogleRelayCallbackData;
+
+static void
+jabber_google_relay_parse_response(const gchar *response, gchar **ip,
+ guint *udp, guint *tcp, guint *ssltcp, gchar **username, gchar **password)
+{
+ gchar **lines = g_strsplit(response, "\n", -1);
+ int i = 0;
+
+ for (; lines[i] ; i++) {
+ gchar *line = lines[i];
+ gchar **parts = g_strsplit(line, "=", 2);
+
+ if (parts[0] && parts[1]) {
+ if (purple_strequal(parts[0], "relay.ip")) {
+ *ip = g_strdup(parts[1]);
+ } else if (purple_strequal(parts[0], "relay.udp_port")) {
+ *udp = atoi(parts[1]);
+ } else if (purple_strequal(parts[0], "relay.tcp_port")) {
+ *tcp = atoi(parts[1]);
+ } else if (purple_strequal(parts[0], "relay.ssltcp_port")) {
+ *ssltcp = atoi(parts[1]);
+ } else if (purple_strequal(parts[0], "username")) {
+ *username = g_strdup(parts[1]);
+ } else if (purple_strequal(parts[0], "password")) {
+ *password = g_strdup(parts[1]);
+ }
+ }
+ g_strfreev(parts);
+ }
+
+ g_strfreev(lines);
+}
+
+static void
+jabber_google_relay_remove_url_data(JabberStream *js,
+ PurpleUtilFetchUrlData *url_data)
+{
+ GList *iter = js->google_relay_requests;
+
+ while (iter) {
+ if (iter->data == url_data) {
+ js->google_relay_requests =
+ g_list_delete_link(js->google_relay_requests, iter);
+ break;
+ }
+ }
+}
+
+static void
+jabber_google_relay_fetch_cb(PurpleUtilFetchUrlData *url_data,
+ gpointer user_data, const gchar *url_text, gsize len,
+ const gchar *error_message)
+{
+ JabberGoogleRelayCallbackData *data =
+ (JabberGoogleRelayCallbackData *) user_data;
+ GoogleSession *session = data->session;
+ JabberStream *js = session->js;
+ JabberGoogleRelayCallback *cb = data->cb;
+ gchar *relay_ip = NULL;
+ guint relay_udp = 0;
+ guint relay_tcp = 0;
+ guint relay_ssltcp = 0;
+ gchar *relay_username = NULL;
+ gchar *relay_password = NULL;
+
+ g_free(data);
+
+ if (url_data) {
+ jabber_google_relay_remove_url_data(js, url_data);
+ }
+
+ purple_debug_info("jabber", "got response on HTTP request to relay server\n");
+
+ if (url_text && len > 0) {
+ purple_debug_info("jabber", "got Google relay request response:\n%s\n",
+ url_text);
+ jabber_google_relay_parse_response(url_text, &relay_ip, &relay_udp,
+ &relay_tcp, &relay_ssltcp, &relay_username, &relay_password);
+ }
+
+ if (cb)
+ cb(session, relay_ip, relay_udp, relay_tcp, relay_ssltcp,
+ relay_username, relay_password);
+
+ g_free(relay_ip);
+ g_free(relay_username);
+ g_free(relay_password);
+}
+
+void
+jabber_google_do_relay_request(JabberStream *js, GoogleSession *session,
+ JabberGoogleRelayCallback cb)
+{
+ PurpleUtilFetchUrlData *url_data = NULL;
+ gchar *url = g_strdup_printf("http://%s", js->google_relay_host);
+ /* yes, the relay token is included twice as different request headers,
+ this is apparently needed to make Google's relay servers work... */
+ gchar *request =
+ g_strdup_printf("GET /create_session HTTP/1.0\r\n"
+ "Host: %s\r\n"
+ "X-Talk-Google-Relay-Auth: %s\r\n"
+ "X-Google-Relay-Auth: %s\r\n\r\n",
+ js->google_relay_host, js->google_relay_token, js->google_relay_token);
+ JabberGoogleRelayCallbackData *data = g_new0(JabberGoogleRelayCallbackData, 1);
+
+ data->session = session;
+ data->cb = cb;
+ purple_debug_info("jabber",
+ "sending Google relay request %s to %s\n", request, url);
+ url_data =
+ purple_util_fetch_url_request(url, FALSE, NULL, FALSE, request, FALSE,
+ jabber_google_relay_fetch_cb, data);
+ if (url_data) {
+ js->google_relay_requests =
+ g_list_prepend(js->google_relay_requests, url_data);
+ } else {
+ purple_debug_error("jabber", "unable to create Google relay request\n");
+ jabber_google_relay_fetch_cb(NULL, data, NULL, 0, NULL);
+ }
+ g_free(url);
+ g_free(request);
+} \ No newline at end of file
diff --git a/libpurple/protocols/jabber/google/relay.h b/libpurple/protocols/jabber/google/relay.h
new file mode 100644
index 0000000000..d1032c09fe
--- /dev/null
+++ b/libpurple/protocols/jabber/google/relay.h
@@ -0,0 +1,33 @@
+/**
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef JABBER_GOOGLE_RELAY
+#define JABBER_GOOGLE_RELAY
+
+#include "google_session.h"
+
+typedef void (JabberGoogleRelayCallback)(GoogleSession *session, const gchar *ip,
+ guint udp_port, guint tcp_port, guint tls_port,
+ const gchar *username, const gchar *password);
+
+void jabber_google_do_relay_request(JabberStream *js, GoogleSession *session,
+ JabberGoogleRelayCallback cb);
+
+#endif /* JABBER_GOOGLE_RELAY */
diff --git a/libpurple/protocols/jabber/iq.c b/libpurple/protocols/jabber/iq.c
index 4d1f14cf81..6cd591b1d4 100644
--- a/libpurple/protocols/jabber/iq.c
+++ b/libpurple/protocols/jabber/iq.c
@@ -28,7 +28,10 @@
#include "buddy.h"
#include "disco.h"
-#include "google.h"
+#include "google/gmail.h"
+#include "google/google.h"
+#include "google/jingleinfo.h"
+#include "google/google_session.h"
#include "iq.h"
#include "jingle/jingle.h"
#include "oob.h"
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index 8ea73b7244..d1816c15fa 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -51,7 +51,9 @@
#include "chat.h"
#include "data.h"
#include "disco.h"
-#include "google.h"
+#include "google/google.h"
+#include "google/google_roster.h"
+#include "google/google_session.h"
#include "ibb.h"
#include "iq.h"
#include "jutil.h"
@@ -205,7 +207,7 @@ static char *jabber_prep_resource(char *input) {
* resource string from being unreasonably long on systems which stuff the
* whole FQDN in the hostname */
if((dot = strchr(hostname, '.')))
- dot = '\0';
+ *dot = '\0';
return purple_strreplace(input, "__HOSTNAME__", hostname);
}
@@ -232,7 +234,7 @@ jabber_process_starttls(JabberStream *js, xmlnode *packet)
return TRUE;
}
- if(purple_account_get_bool(account, "require_tls", JABBER_DEFAULT_REQUIRE_TLS)) {
+ if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
purple_connection_error_reason(js->gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
_("You require encryption, but no TLS/SSL support was found."));
@@ -244,12 +246,16 @@ jabber_process_starttls(JabberStream *js, xmlnode *packet)
void jabber_stream_features_parse(JabberStream *js, xmlnode *packet)
{
- if(xmlnode_get_child(packet, "starttls")) {
- if(jabber_process_starttls(js, packet)) {
+ PurpleAccount *account = purple_connection_get_account(js->gc);
+ const char *connection_security =
+ purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS);
+
+ if (xmlnode_get_child(packet, "starttls")) {
+ if (jabber_process_starttls(js, packet)) {
jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING_ENCRYPTION);
return;
}
- } else if(purple_account_get_bool(js->gc->account, "require_tls", JABBER_DEFAULT_REQUIRE_TLS) && !jabber_stream_is_ssl(js)) {
+ } else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) {
purple_connection_error_reason(js->gc,
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("You require encryption, but it is not available on this server."));
@@ -567,8 +573,7 @@ void jabber_send_signal_cb(PurpleConnection *pc, xmlnode **packet,
if (NULL == packet)
return;
- if (!PURPLE_CONNECTION_IS_VALID(pc))
- return;
+ g_return_if_fail(PURPLE_CONNECTION_IS_VALID(pc));
js = purple_connection_get_protocol_data(pc);
@@ -625,7 +630,7 @@ jabber_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc,
/* TODO: It should be possible to make this check unnecessary */
if(!PURPLE_CONNECTION_IS_VALID(gc)) {
purple_ssl_close(gsc);
- return;
+ g_return_if_reached();
}
while((len = purple_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) {
@@ -660,8 +665,7 @@ jabber_recv_cb(gpointer data, gint source, PurpleInputCondition condition)
int len;
static char buf[4096];
- if(!PURPLE_CONNECTION_IS_VALID(gc))
- return;
+ g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) {
gc->last_received = time(NULL);
@@ -721,7 +725,7 @@ jabber_login_callback_ssl(gpointer data, PurpleSslConnection *gsc,
/* TODO: It should be possible to make this check unnecessary */
if(!PURPLE_CONNECTION_IS_VALID(gc)) {
purple_ssl_close(gsc);
- return;
+ g_return_if_reached();
}
js = gc->proto_data;
@@ -816,8 +820,7 @@ jabber_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error,
JabberStream *js;
/* If the connection is already disconnected, we don't need to do anything else */
- if(!PURPLE_CONNECTION_IS_VALID(gc))
- return;
+ g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
js = gc->proto_data;
js->gsc = NULL;
@@ -975,6 +978,9 @@ jabber_stream_new(PurpleAccount *account)
js->stun_ip = NULL;
js->stun_port = 0;
js->stun_query = NULL;
+ js->google_relay_token = NULL;
+ js->google_relay_host = NULL;
+ js->google_relay_requests = NULL;
/* if we are idle, set idle-ness on the stream (this could happen if we get
disconnected and the reconnects while being idle. I don't think it makes
@@ -1017,7 +1023,7 @@ jabber_stream_connect(JabberStream *js)
js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain);
/* if they've got old-ssl mode going, we probably want to ignore SRV lookups */
- if(purple_account_get_bool(account, "old_ssl", FALSE)) {
+ if (g_str_equal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
if(purple_ssl_is_supported()) {
js->gsc = purple_ssl_connect(account, js->certificate_CN,
purple_account_get_int(account, "port", 5223),
@@ -1634,6 +1640,8 @@ void jabber_close(PurpleConnection *gc)
if(js->sasl_mechs)
g_string_free(js->sasl_mechs, TRUE);
g_free(js->sasl_cb);
+ /* Note: _not_ g_free. See auth_cyrus.c:jabber_sasl_cb_secret */
+ free(js->sasl_secret);
#endif
g_free(js->serverFQDN);
while(js->commands) {
@@ -1676,6 +1684,21 @@ void jabber_close(PurpleConnection *gc)
js->stun_query = NULL;
}
+ /* remove Google relay-related stuff */
+ g_free(js->google_relay_token);
+ g_free(js->google_relay_host);
+ if (js->google_relay_requests) {
+ while (js->google_relay_requests) {
+ PurpleUtilFetchUrlData *url_data =
+ (PurpleUtilFetchUrlData *) js->google_relay_requests->data;
+ purple_util_fetch_url_cancel(url_data);
+ g_free(url_data);
+ js->google_relay_requests =
+ g_list_delete_link(js->google_relay_requests,
+ js->google_relay_requests);
+ }
+ }
+
g_free(js);
gc->proto_data = NULL;
@@ -3232,9 +3255,9 @@ jabber_initiate_media(PurpleAccount *account, const char *who,
g_free(resource);
if (type & PURPLE_MEDIA_AUDIO &&
- !jabber_resource_has_capability(jbr,
- JINGLE_APP_RTP_SUPPORT_AUDIO) &&
- jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE))
+ !jabber_resource_has_capability(jbr,
+ JINGLE_APP_RTP_SUPPORT_AUDIO) &&
+ jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE))
return jabber_google_session_initiate(js, who, type);
else
return jingle_rtp_initiate_media(js, who, type);
@@ -3496,7 +3519,7 @@ jabber_cmd_mood(PurpleConversation *conv,
if (js->pep) {
/* if no argument was given, unset mood */
- if (!args | !args[0]) {
+ if (!args || !args[0]) {
jabber_mood_set(js, NULL, NULL);
} else if (!args[1]) {
jabber_mood_set(js, args[0], NULL);
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
index 94ce1eaa4f..70db5bd0bb 100644
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -80,7 +80,7 @@ typedef struct _JabberStream JabberStream;
#define CAPS0115_NODE "http://pidgin.im/"
-#define JABBER_DEFAULT_REQUIRE_TLS TRUE
+#define JABBER_DEFAULT_REQUIRE_TLS "require_starttls"
#define JABBER_DEFAULT_FT_PROXIES "proxy.eu.jabber.org"
/* Index into attention_types list */
@@ -206,6 +206,7 @@ struct _JabberStream
#ifdef HAVE_CYRUS_SASL
sasl_conn_t *sasl;
sasl_callback_t *sasl_cb;
+ sasl_secret_t *sasl_secret;
const char *current_mech;
int auth_fail_count;
@@ -275,7 +276,12 @@ struct _JabberStream
gchar *stun_ip;
int stun_port;
PurpleDnsQueryData *stun_query;
- /* later add stuff to handle TURN relays... */
+
+ /* stuff for Google's relay handling */
+ gchar *google_relay_token;
+ gchar *google_relay_host;
+ GList *google_relay_requests; /* the HTTP requests to get */
+ /* relay info */
};
typedef gboolean (JabberFeatureEnabled)(JabberStream *js, const gchar *namespace);
diff --git a/libpurple/protocols/jabber/jingle/jingle.c b/libpurple/protocols/jabber/jingle/jingle.c
index d445bdecb6..f106797fff 100644
--- a/libpurple/protocols/jabber/jingle/jingle.c
+++ b/libpurple/protocols/jabber/jingle/jingle.c
@@ -35,6 +35,9 @@
#include "rtp.h"
#include <string.h>
+#ifdef USE_VV
+#include <gst/gst.h>
+#endif
GType
jingle_get_type(const gchar *type)
@@ -431,32 +434,91 @@ jingle_terminate_sessions(JabberStream *js)
jingle_terminate_sessions_gh, NULL);
}
+#ifdef USE_VV
+static GValueArray *
+jingle_create_relay_info(const gchar *ip, guint port, const gchar *username,
+ const gchar *password, const gchar *relay_type, GValueArray *relay_info)
+{
+ GValue value;
+ GstStructure *turn_setup = gst_structure_new("relay-info",
+ "ip", G_TYPE_STRING, ip,
+ "port", G_TYPE_UINT, port,
+ "username", G_TYPE_STRING, username,
+ "password", G_TYPE_STRING, password,
+ "relay-type", G_TYPE_STRING, relay_type,
+ NULL);
+ purple_debug_info("jabber", "created gst_structure %" GST_PTR_FORMAT "\n",
+ turn_setup);
+ if (turn_setup) {
+ memset(&value, 0, sizeof(GValue));
+ g_value_init(&value, GST_TYPE_STRUCTURE);
+ gst_value_set_structure(&value, turn_setup);
+ relay_info = g_value_array_append(relay_info, &value);
+ gst_structure_free(turn_setup);
+ }
+ return relay_info;
+}
+
GParameter *
-jingle_get_params(JabberStream *js, guint *num)
+jingle_get_params(JabberStream *js, const gchar *relay_ip, guint relay_udp,
+ guint relay_tcp, guint relay_ssltcp, const gchar *relay_username,
+ const gchar *relay_password, guint *num)
{
/* don't set a STUN server if one is set globally in prefs, in that case
this will be handled in media.c */
gboolean has_account_stun = js->stun_ip && !purple_network_get_stun_ip();
- guint num_params = has_account_stun ? 2 : 0;
+ guint num_params = has_account_stun ?
+ (relay_ip ? 3 : 2) : (relay_ip ? 1 : 0);
GParameter *params = NULL;
-
+ int next_index = 0;
+
if (num_params > 0) {
params = g_new0(GParameter, num_params);
- purple_debug_info("jabber",
- "setting param stun-ip for stream using auto-discovered IP: %s\n",
- js->stun_ip);
- params[0].name = "stun-ip";
- g_value_init(&params[0].value, G_TYPE_STRING);
- g_value_set_string(&params[0].value, js->stun_ip);
- purple_debug_info("jabber",
- "setting param stun-port for stream using auto-discovered port: %d\n",
- js->stun_port);
- params[1].name = "stun-port";
- g_value_init(&params[1].value, G_TYPE_UINT);
- g_value_set_uint(&params[1].value, js->stun_port);
+ if (has_account_stun) {
+ purple_debug_info("jabber",
+ "setting param stun-ip for stream using Google auto-config: %s\n",
+ js->stun_ip);
+ params[next_index].name = "stun-ip";
+ g_value_init(&params[next_index].value, G_TYPE_STRING);
+ g_value_set_string(&params[next_index].value, js->stun_ip);
+ purple_debug_info("jabber",
+ "setting param stun-port for stream using Google auto-config: %d\n",
+ js->stun_port);
+ next_index++;
+ params[next_index].name = "stun-port";
+ g_value_init(&params[next_index].value, G_TYPE_UINT);
+ g_value_set_uint(&params[next_index].value, js->stun_port);
+ next_index++;
+ }
+
+ if (relay_ip) {
+ GValueArray *relay_info = g_value_array_new(0);
+
+ if (relay_udp) {
+ relay_info =
+ jingle_create_relay_info(relay_ip, relay_udp, relay_username,
+ relay_password, "udp", relay_info);
+ }
+ if (relay_tcp) {
+ relay_info =
+ jingle_create_relay_info(relay_ip, relay_tcp, relay_username,
+ relay_password, "tcp", relay_info);
+ }
+ if (relay_ssltcp) {
+ relay_info =
+ jingle_create_relay_info(relay_ip, relay_ssltcp, relay_username,
+ relay_password, "tls", relay_info);
+ }
+ params[next_index].name = "relay-info";
+ g_value_init(&params[next_index].value, G_TYPE_VALUE_ARRAY);
+ g_value_set_boxed(&params[next_index].value, relay_info);
+ g_value_array_free(relay_info);
+ }
}
*num = num_params;
return params;
}
+#endif
+
diff --git a/libpurple/protocols/jabber/jingle/jingle.h b/libpurple/protocols/jabber/jingle/jingle.h
index 7ccdc55fe2..3813529f8d 100644
--- a/libpurple/protocols/jabber/jingle/jingle.h
+++ b/libpurple/protocols/jabber/jingle/jingle.h
@@ -78,9 +78,13 @@ void jingle_parse(JabberStream *js, const char *from, JabberIqType type,
void jingle_terminate_sessions(JabberStream *js);
+#ifdef USE_VV
/* create a GParam array given autoconfigured STUN (and later perhaps TURN).
if google_talk is TRUE, set compatability mode to GOOGLE_TALK */
-GParameter *jingle_get_params(JabberStream *js, guint *num_params);
+GParameter *jingle_get_params(JabberStream *js, const gchar *relay_ip,
+ guint relay_udp, guint relay_tcp, guint relay_ssltcp,
+ const gchar *relay_username, const gchar *relay_password, guint *num_params);
+#endif
#ifdef __cplusplus
}
diff --git a/libpurple/protocols/jabber/jingle/rtp.c b/libpurple/protocols/jabber/jingle/rtp.c
index 7350e1c32a..4de0bcad99 100644
--- a/libpurple/protocols/jabber/jingle/rtp.c
+++ b/libpurple/protocols/jabber/jingle/rtp.c
@@ -611,7 +611,8 @@ jingle_rtp_init_media(JingleContent *content)
: PURPLE_MEDIA_RECV_VIDEO;
params =
- jingle_get_params(jingle_session_get_js(session), &num_params);
+ jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0,
+ NULL, NULL, &num_params);
creator = jingle_content_get_creator(content);
if (!strcmp(creator, "initiator"))
diff --git a/libpurple/protocols/jabber/jingle/transport.c b/libpurple/protocols/jabber/jingle/transport.c
index 1a465bbb2a..b5d1c342e1 100644
--- a/libpurple/protocols/jabber/jingle/transport.c
+++ b/libpurple/protocols/jabber/jingle/transport.c
@@ -111,8 +111,6 @@ jingle_transport_set_property (GObject *object, guint prop_id, const GValue *val
JingleTransport *transport;
g_return_if_fail(JINGLE_IS_TRANSPORT(object));
- transport = JINGLE_TRANSPORT(object);
-
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -125,8 +123,6 @@ jingle_transport_get_property (GObject *object, guint prop_id, GValue *value, GP
{
JingleTransport *transport;
g_return_if_fail(JINGLE_IS_TRANSPORT(object));
-
- transport = JINGLE_TRANSPORT(object);
switch (prop_id) {
default:
diff --git a/libpurple/protocols/jabber/libxmpp.c b/libpurple/protocols/jabber/libxmpp.c
index 73e425cbbe..17bbd019e4 100644
--- a/libpurple/protocols/jabber/libxmpp.c
+++ b/libpurple/protocols/jabber/libxmpp.c
@@ -41,7 +41,7 @@
#include "si.h"
#include "message.h"
#include "presence.h"
-#include "google.h"
+#include "google/google.h"
#include "pep.h"
#include "usermood.h"
#include "usertune.h"
@@ -253,6 +253,7 @@ init_plugin(PurplePlugin *plugin)
{
PurpleAccountUserSplit *split;
PurpleAccountOption *option;
+ GList *encryption_values = NULL;
/* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
split = purple_account_user_split_new(_("Domain"), NULL, '@');
@@ -263,13 +264,26 @@ init_plugin(PurplePlugin *plugin)
purple_account_user_split_set_reverse(split, FALSE);
prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
- option = purple_account_option_bool_new(_("Require SSL/TLS"), "require_tls", JABBER_DEFAULT_REQUIRE_TLS);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
+#define ADD_VALUE(list, desc, v) { \
+ PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \
+ kvp->key = g_strdup((desc)); \
+ kvp->value = g_strdup((v)); \
+ list = g_list_prepend(list, kvp); \
+}
+
+ ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
+ ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
+ ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
+#if 0
+ ADD_VALUE(encryption_values, "None", "none");
+#endif
+ encryption_values = g_list_reverse(encryption_values);
+
+#undef ADD_VALUE
- option = purple_account_option_bool_new(_("Force old (port 5223) SSL"), "old_ssl", FALSE);
+ option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
+ option);
option = purple_account_option_bool_new(
_("Allow plaintext auth over unencrypted streams"),
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
index 32fe4d312f..db68b6e784 100644
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -30,7 +30,7 @@
#include "buddy.h"
#include "chat.h"
#include "data.h"
-#include "google.h"
+#include "google/google.h"
#include "message.h"
#include "xmlnode.h"
#include "pep.h"
@@ -296,7 +296,6 @@ static void handle_error(JabberMessage *jm)
}
static void handle_buzz(JabberMessage *jm) {
- PurpleBuddy *buddy;
PurpleAccount *account;
/* Delayed buzz MUST NOT be accepted */
@@ -309,7 +308,7 @@ static void handle_buzz(JabberMessage *jm) {
account = purple_connection_get_account(jm->js->gc);
- if ((buddy = purple_find_buddy(account, jm->from)) == NULL)
+ if (purple_find_buddy(account, jm->from) == NULL)
return; /* Do not accept buzzes from unknown people */
/* xmpp only has 1 attention type, so index is 0 */
@@ -587,8 +586,10 @@ void jabber_message_parse(JabberStream *js, xmlnode *packet)
jm->thread_id = xmlnode_get_data(child);
} else if(!strcmp(child->name, "body") && !strcmp(xmlns, NS_XMPP_CLIENT)) {
if(!jm->body) {
- char *msg = xmlnode_to_str(child, NULL);
- jm->body = purple_strdup_withhtml(msg);
+ char *msg = xmlnode_get_data(child);
+ char *escaped = purple_markup_escape_text(msg, -1);
+ jm->body = purple_strdup_withhtml(escaped);
+ g_free(escaped);
g_free(msg);
}
} else if(!strcmp(child->name, "html") && !strcmp(xmlns, NS_XHTML_IM)) {
diff --git a/libpurple/protocols/jabber/oob.c b/libpurple/protocols/jabber/oob.c
index 63c2213291..430d17ac7e 100644
--- a/libpurple/protocols/jabber/oob.c
+++ b/libpurple/protocols/jabber/oob.c
@@ -185,7 +185,7 @@ static void jabber_oob_xfer_recv_denied(PurpleXfer *xfer) {
jabber_oob_xfer_recv_error(xfer, "406");
}
-static void jabber_oob_xfer_recv_canceled(PurpleXfer *xfer) {
+static void jabber_oob_xfer_recv_cancelled(PurpleXfer *xfer) {
jabber_oob_xfer_recv_error(xfer, "404");
}
@@ -233,7 +233,7 @@ void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type,
purple_xfer_set_init_fnc(xfer, jabber_oob_xfer_init);
purple_xfer_set_end_fnc(xfer, jabber_oob_xfer_end);
purple_xfer_set_request_denied_fnc(xfer, jabber_oob_xfer_recv_denied);
- purple_xfer_set_cancel_recv_fnc(xfer, jabber_oob_xfer_recv_canceled);
+ purple_xfer_set_cancel_recv_fnc(xfer, jabber_oob_xfer_recv_cancelled);
purple_xfer_set_read_fnc(xfer, jabber_oob_xfer_read);
purple_xfer_set_start_fnc(xfer, jabber_oob_xfer_start);
diff --git a/libpurple/protocols/jabber/parser.c b/libpurple/protocols/jabber/parser.c
index 2c0dae610f..7e6e622c58 100644
--- a/libpurple/protocols/jabber/parser.c
+++ b/libpurple/protocols/jabber/parser.c
@@ -93,10 +93,25 @@ jabber_parser_element_start_libxml(void *user_data,
}
}
- if (js->stream_id == NULL)
+ if (js->stream_id == NULL) {
+#if 0
+ /* This was underspecified in rfc3920 as only being a SHOULD, so
+ * we cannot rely on it. See #12331 and Oracle's server.
+ */
purple_connection_error_reason(js->gc,
PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
_("XMPP stream missing ID"));
+#else
+ /* Instead, let's make up a placeholder stream ID, which we need
+ * to do because we flag on it being NULL as a special case
+ * in this parsing code.
+ */
+ js->stream_id = g_strdup("");
+ purple_debug_info("jabber", "Server failed to specify a stream "
+ "ID (underspecified in rfc3920, but intended "
+ "to be a MUST; digest legacy auth may fail.");
+#endif
+ }
} else {
if(js->current)
diff --git a/libpurple/protocols/jabber/presence.c b/libpurple/protocols/jabber/presence.c
index 3c84c7e151..895c417fc8 100644
--- a/libpurple/protocols/jabber/presence.c
+++ b/libpurple/protocols/jabber/presence.c
@@ -34,7 +34,8 @@
#include "buddy.h"
#include "chat.h"
-#include "google.h"
+#include "google/google.h"
+#include "google/google_presence.h"
#include "presence.h"
#include "iq.h"
#include "jutil.h"
diff --git a/libpurple/protocols/jabber/roster.c b/libpurple/protocols/jabber/roster.c
index 5fe56165a7..b5acb7cf35 100644
--- a/libpurple/protocols/jabber/roster.c
+++ b/libpurple/protocols/jabber/roster.c
@@ -27,7 +27,8 @@
#include "buddy.h"
#include "chat.h"
-#include "google.h"
+#include "google/google.h"
+#include "google/google_roster.h"
#include "presence.h"
#include "roster.h"
#include "iq.h"
@@ -76,12 +77,9 @@ static void roster_request_cb(JabberStream *js, const char *from,
void jabber_roster_request(JabberStream *js)
{
- PurpleAccount *account;
JabberIq *iq;
xmlnode *query;
- account = purple_connection_get_account(js->gc);
-
iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:roster");
query = xmlnode_get_child(iq->node, "query");
diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c
index a9f147e14b..d42640bcc3 100644
--- a/libpurple/protocols/jabber/si.c
+++ b/libpurple/protocols/jabber/si.c
@@ -1666,12 +1666,8 @@ PurpleXfer *jabber_si_new_xfer(PurpleConnection *gc, const char *who)
void jabber_si_xfer_send(PurpleConnection *gc, const char *who, const char *file)
{
- JabberStream *js;
-
PurpleXfer *xfer;
- js = gc->proto_data;
-
xfer = jabber_si_new_xfer(gc, who);
if (file)
@@ -1734,7 +1730,7 @@ void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
/* if they've already sent us this file transfer with the same damn id
* then we're gonna ignore it, until I think of something better to do
* with it */
- if((xfer = jabber_si_xfer_find(js, stream_id, from)))
+ if(jabber_si_xfer_find(js, stream_id, from) != NULL)
return;
jsx = g_new0(JabberSIXfer, 1);
diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c
index c1a511c551..fd01527c3b 100644
--- a/libpurple/protocols/msn/contact.c
+++ b/libpurple/protocols/msn/contact.c
@@ -527,16 +527,20 @@ msn_get_contact_list_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
g_return_if_fail(session != NULL);
if (resp != NULL) {
+#ifdef MSN_PARTIAL_LISTS
const char *abLastChange;
const char *dynamicItemLastChange;
+#endif
purple_debug_misc("msn", "Got the contact list!\n");
msn_parse_contact_list(session, resp->xml);
+#ifdef MSN_PARTIAL_LISTS
abLastChange = purple_account_get_string(session->account,
"ablastChange", NULL);
dynamicItemLastChange = purple_account_get_string(session->account,
- "dynamicItemLastChange", NULL);
+ "DynamicItemLastChanged", NULL);
+#endif
if (state->partner_scenario == MSN_PS_INITIAL) {
#ifdef MSN_PARTIAL_LISTS
@@ -684,20 +688,20 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node)
xmlnode *annotation;
MsnUser *user;
- if (!(contactId = xmlnode_get_child(contactNode,"contactId"))
- || !(contactInfo = xmlnode_get_child(contactNode, "contactInfo"))
- || !(contactType = xmlnode_get_child(contactInfo, "contactType")))
- continue;
-
g_free(passport);
g_free(Name);
- g_free(alias);
g_free(uid);
g_free(type);
g_free(mobile_number);
+ g_free(alias);
passport = Name = uid = type = mobile_number = alias = NULL;
mobile = FALSE;
+ if (!(contactId = xmlnode_get_child(contactNode,"contactId"))
+ || !(contactInfo = xmlnode_get_child(contactNode, "contactInfo"))
+ || !(contactType = xmlnode_get_child(contactInfo, "contactType")))
+ continue;
+
uid = xmlnode_get_data(contactId);
type = xmlnode_get_data(contactType);
@@ -836,6 +840,7 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node)
g_free(uid);
g_free(type);
g_free(mobile_number);
+ g_free(alias);
}
static gboolean
@@ -885,7 +890,7 @@ msn_parse_addressbook(MsnSession *session, xmlnode *node)
msn_parse_addressbook_groups(session, groups);
}
- /*add a default No group to set up the no group Membership*/
+ /* Add an "Other Contacts" group for buddies who aren't in a group */
msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID,
MSN_INDIVIDUALS_GROUP_NAME);
purple_debug_misc("msn", "AB group_id:%s name:%s\n",
@@ -895,7 +900,7 @@ msn_parse_addressbook(MsnSession *session, xmlnode *node)
purple_blist_add_group(g, NULL);
}
- /*add a default No group to set up the no group Membership*/
+ /* Add a "Non-IM Contacts" group */
msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
purple_debug_misc("msn", "AB group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL) {
@@ -1564,7 +1569,7 @@ msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state,
if (list == MSN_LIST_PL) {
partner_scenario = MSN_PS_CONTACT_API;
- if (user && user->networkid != MSN_NETWORK_PASSPORT)
+ if (user->networkid != MSN_NETWORK_PASSPORT)
member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML,
"EmailMember", "Email",
user->member_id_on_pending_list);
diff --git a/libpurple/protocols/msn/directconn.h b/libpurple/protocols/msn/directconn.h
index 18f1babe76..2aae22ec69 100644
--- a/libpurple/protocols/msn/directconn.h
+++ b/libpurple/protocols/msn/directconn.h
@@ -131,7 +131,7 @@ msn_dc_enqueue_msg(MsnDirectConn *dc, MsnMessage *msg);
* Creates, initializes, and returns a new MsnDirectConn structure.
*/
MsnDirectConn *
-msn_dc_new(MsnSlpCall *slplink);
+msn_dc_new(MsnSlpCall *slpcall);
/*
* Destroys an MsnDirectConn structure. Frees every buffer allocated earlier
diff --git a/libpurple/protocols/msn/httpconn.c b/libpurple/protocols/msn/httpconn.c
index ba44841091..708cbcc362 100644
--- a/libpurple/protocols/msn/httpconn.c
+++ b/libpurple/protocols/msn/httpconn.c
@@ -239,6 +239,9 @@ msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf,
}
else
{
+ /* I'll be honest, I don't fully understand all this, but this
+ * causes crashes, Stu. */
+#if 0
MsnServConn *servconn;
/* It's going to die. */
@@ -246,10 +249,9 @@ msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf,
servconn = httpconn->servconn;
- /* I'll be honest, I don't fully understand all this, but this
- * causes crashes, Stu. */
- /* if (servconn != NULL)
- servconn->wasted = TRUE; */
+ if (servconn != NULL)
+ servconn->wasted = TRUE;
+#endif
g_free(full_session_id);
g_free(session_id);
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
index 61c9e682f6..f4c4f033e1 100644
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -728,7 +728,6 @@ show_send_to_mobile_cb(PurpleBlistNode *node, gpointer ignored)
{
PurpleBuddy *buddy;
PurpleConnection *gc;
- MsnSession *session;
MsnMobileData *data;
PurpleAccount *account;
const char *name;
@@ -740,8 +739,6 @@ show_send_to_mobile_cb(PurpleBlistNode *node, gpointer ignored)
gc = purple_account_get_connection(account);
name = purple_buddy_get_name(buddy);
- session = gc->proto_data;
-
data = g_new0(MsnMobileData, 1);
data->gc = gc;
data->passport = name;
@@ -2208,11 +2205,9 @@ static void
msn_remove_group(PurpleConnection *gc, PurpleGroup *group)
{
MsnSession *session;
- MsnCmdProc *cmdproc;
const char *gname;
session = gc->proto_data;
- cmdproc = session->notification->cmdproc;
gname = purple_group_get_name(group);
purple_debug_info("msn", "Remove group %s\n", gname);
diff --git a/libpurple/protocols/msn/msnutils.c b/libpurple/protocols/msn/msnutils.c
index 846f5111e2..fb5a434bb5 100644
--- a/libpurple/protocols/msn/msnutils.c
+++ b/libpurple/protocols/msn/msnutils.c
@@ -539,7 +539,7 @@ msn_handle_chl(char *input, char *output)
chlStringParts = (unsigned int *)buf;
/* this is magic */
- for (i = 0; i < (strlen(buf) / 4); i += 2) {
+ for (i = 0; i < (len / 4); i += 2) {
long long temp;
chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]);
diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c
index 24a3c7a628..5b1c02e1f6 100644
--- a/libpurple/protocols/msn/notification.c
+++ b/libpurple/protocols/msn/notification.c
@@ -93,7 +93,6 @@ connect_cb(MsnServConn *servconn)
MsnCmdProc *cmdproc;
MsnSession *session;
MsnTransaction *trans;
- PurpleAccount *account;
GString *vers;
const char *ver_str;
int i;
@@ -102,7 +101,6 @@ connect_cb(MsnServConn *servconn)
cmdproc = servconn->cmdproc;
session = servconn->session;
- account = session->account;
vers = g_string_new("");
@@ -188,10 +186,8 @@ static void
usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
MsnSession *session;
- PurpleAccount *account;
session = cmdproc->session;
- account = session->account;
if (!g_ascii_strcasecmp(cmd->params[1], "OK"))
{
@@ -1020,7 +1016,6 @@ iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
MsnSession *session;
PurpleAccount *account;
- PurpleConnection *gc;
MsnUser *user;
MsnObject *msnobj = NULL;
unsigned long clientid, extcaps;
@@ -1031,7 +1026,6 @@ iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
session = cmdproc->session;
account = session->account;
- gc = purple_account_get_connection(account);
state = cmd->params[1];
passport = cmd->params[2];
@@ -1245,7 +1239,6 @@ nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
MsnSession *session;
PurpleAccount *account;
- PurpleConnection *gc;
MsnUser *user;
MsnObject *msnobj;
unsigned long clientid, extcaps;
@@ -1255,7 +1248,6 @@ nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
session = cmdproc->session;
account = session->account;
- gc = purple_account_get_connection(account);
state = cmd->params[0];
passport = cmd->params[1];
@@ -1439,11 +1431,13 @@ rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
MsnSession *session;
MsnSwitchBoard *swboard;
const char *session_id;
+ const char *auth_key;
char *host;
int port;
session = cmdproc->session;
session_id = cmd->params[0];
+ auth_key = cmd->params[3];
msn_parse_socket(cmd->params[1], &host, &port);
@@ -1453,8 +1447,8 @@ rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
swboard = msn_switchboard_new(session);
msn_switchboard_set_invited(swboard, TRUE);
- msn_switchboard_set_session_id(swboard, cmd->params[0]);
- msn_switchboard_set_auth_key(swboard, cmd->params[3]);
+ msn_switchboard_set_session_id(swboard, session_id);
+ msn_switchboard_set_auth_key(swboard, auth_key);
swboard->im_user = g_strdup(cmd->params[4]);
/* msn_switchboard_add_user(swboard, cmd->params[4]); */
@@ -1694,14 +1688,12 @@ ubx_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
size_t len)
{
MsnSession *session;
- PurpleAccount *account;
MsnUser *user;
const char *passport;
xmlnode *payloadNode;
char *psm_str, *str;
session = cmdproc->session;
- account = session->account;
passport = cmd->params[0];
if (g_str_equal(passport, session->user->passport))
@@ -1946,7 +1938,9 @@ profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
MsnSession *session;
const char *value;
+#ifdef MSN_PARTIAL_LISTS
const char *clLastChange;
+#endif
session = cmdproc->session;
@@ -1989,9 +1983,9 @@ profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
if ((value = msn_message_get_header_value(msg, "EmailEnabled")) != NULL)
session->passport_info.email_enabled = (gboolean)atol(value);
+#ifdef MSN_PARTIAL_LISTS
/*starting retrieve the contact list*/
clLastChange = purple_account_get_string(session->account, "CLLastChange", NULL);
-#ifdef MSN_PARTIAL_LISTS
/* msn_userlist_load defeats all attempts at trying to detect blist sync issues */
msn_userlist_load(session);
msn_get_contact_list(session, MSN_PS_INITIAL, clLastChange);
@@ -2195,7 +2189,7 @@ system_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
if ((type_s = g_hash_table_lookup(table, "Type")) != NULL)
{
int type = atoi(type_s);
- char buf[MSN_BUF_LEN];
+ char buf[MSN_BUF_LEN] = "";
int minutes;
switch (type)
diff --git a/libpurple/protocols/msn/session.c b/libpurple/protocols/msn/session.c
index 5091877542..fa24530b17 100644
--- a/libpurple/protocols/msn/session.c
+++ b/libpurple/protocols/msn/session.c
@@ -283,7 +283,7 @@ msn_login_timeout_cb(gpointer data)
void
msn_session_activate_login_timeout(MsnSession *session)
{
- if (!session->logged_in) {
+ if (!session->logged_in && session->connected) {
session->login_timeout =
purple_timeout_add_seconds(MSN_LOGIN_FQY_TIMEOUT,
msn_login_timeout_cb, session);
diff --git a/libpurple/protocols/msn/slp.c b/libpurple/protocols/msn/slp.c
index 70c39a6fef..a2490573d3 100644
--- a/libpurple/protocols/msn/slp.c
+++ b/libpurple/protocols/msn/slp.c
@@ -941,7 +941,8 @@ got_error(MsnSlpCall *slpcall,
purple_debug_error("msn", "Received non-OK result: %s\n",
error ? error : "Unknown");
- if (type && !strcmp(type, "application/x-msnmsgr-transreqbody")) {
+ if (type && (!strcmp(type, "application/x-msnmsgr-transreqbody")
+ || !strcmp(type, "application/x-msnmsgr-transrespbody"))) {
MsnDirectConn *dc = slpcall->slplink->dc;
if (dc) {
msn_dc_fallback_to_sb(dc);
@@ -1265,8 +1266,6 @@ msn_release_buddy_icon_request(MsnUserList *userlist)
if (userlist->buddy_icon_window > 0)
{
GQueue *queue;
- PurpleAccount *account;
- const char *username;
queue = userlist->buddy_icon_requests;
@@ -1275,9 +1274,6 @@ msn_release_buddy_icon_request(MsnUserList *userlist)
user = g_queue_pop_head(queue);
- account = userlist->session->account;
- username = user->passport;
-
userlist->buddy_icon_window--;
request_user_display(user);
@@ -1349,31 +1345,21 @@ static void
got_user_display(MsnSlpCall *slpcall,
const guchar *data, gsize size)
{
- MsnUserList *userlist;
+ MsnSlpLink *slplink;
const char *info;
PurpleAccount *account;
g_return_if_fail(slpcall != NULL);
+ slplink = slpcall->slplink;
info = slpcall->data_info;
if (purple_debug_is_verbose())
- purple_debug_info("msn", "Got User Display: %s\n", slpcall->slplink->remote_user);
+ purple_debug_info("msn", "Got User Display: %s\n", slplink->remote_user);
- userlist = slpcall->slplink->session->userlist;
- account = slpcall->slplink->session->account;
+ account = slplink->session->account;
- purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user,
+ purple_buddy_icons_set_for_user(account, slplink->remote_user,
g_memdup(data, size), size, info);
-
-#if 0
- /* Free one window slot */
- userlist->buddy_icon_window++;
-
- purple_debug_info("msn", "got_user_display(): buddy_icon_window++ yields =%d\n",
- userlist->buddy_icon_window);
-
- msn_release_buddy_icon_request(userlist);
-#endif
}
static void
diff --git a/libpurple/protocols/msn/slplink.c b/libpurple/protocols/msn/slplink.c
index e7569c9378..49a9fa3570 100644
--- a/libpurple/protocols/msn/slplink.c
+++ b/libpurple/protocols/msn/slplink.c
@@ -632,7 +632,7 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *d
slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
if (slpmsg == NULL)
{
- /* Probably the transfer was canceled */
+ /* Probably the transfer was cancelled */
purple_debug_error("msn", "Couldn't find slpmsg\n");
return;
}
diff --git a/libpurple/protocols/msn/soap.c b/libpurple/protocols/msn/soap.c
index c7d2a64075..87071aa28c 100644
--- a/libpurple/protocols/msn/soap.c
+++ b/libpurple/protocols/msn/soap.c
@@ -68,7 +68,6 @@ typedef struct _MsnSoapConnection {
GQueue *queue;
MsnSoapRequest *current_request;
- gboolean unsafe_debug;
} MsnSoapConnection;
static gboolean msn_soap_connection_run(gpointer data);
@@ -80,7 +79,6 @@ msn_soap_connection_new(MsnSession *session, const char *host)
conn->session = session;
conn->host = g_strdup(host);
conn->queue = g_queue_new();
- conn->unsafe_debug = purple_debug_is_unsafe();
return conn;
}
@@ -509,7 +507,7 @@ msn_soap_read_cb(gpointer data, gint fd, PurpleInputCondition cond)
purple_debug_info("soap", "read: %s\n", g_strerror(perrno));
if (conn->current_request && conn->current_request->secure &&
- !conn->unsafe_debug)
+ !purple_debug_is_unsafe())
purple_debug_misc("soap", "Received secure request.\n");
else if (count != 0)
purple_debug_misc("soap", "current %s\n", conn->buf->str + cursor);
@@ -659,7 +657,7 @@ msn_soap_connection_run(gpointer data)
g_string_append(conn->buf, "\r\n");
g_string_append(conn->buf, body);
- if (req->secure && !conn->unsafe_debug)
+ if (req->secure && !purple_debug_is_unsafe())
purple_debug_misc("soap", "Sending secure request.\n");
else
purple_debug_misc("soap", "%s\n", conn->buf->str);
diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c
index a582093573..9e789ef7f7 100644
--- a/libpurple/protocols/msn/switchboard.c
+++ b/libpurple/protocols/msn/switchboard.c
@@ -767,12 +767,8 @@ bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
static void
iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
- PurpleAccount *account;
- PurpleConnection *gc;
MsnSwitchBoard *swboard;
- account = cmdproc->session->account;
- gc = account->gc;
swboard = cmdproc->data;
swboard->total_users = atoi(cmd->params[2]);
@@ -784,16 +780,12 @@ static void
joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
MsnSession *session;
- PurpleAccount *account;
- PurpleConnection *gc;
MsnSwitchBoard *swboard;
const char *passport;
passport = cmd->params[0];
session = cmdproc->session;
- account = session->account;
- gc = account->gc;
swboard = cmdproc->data;
msn_switchboard_add_user(swboard, passport);
diff --git a/libpurple/protocols/oscar/Makefile.am b/libpurple/protocols/oscar/Makefile.am
index 5dfcba37df..4cf5e4995b 100644
--- a/libpurple/protocols/oscar/Makefile.am
+++ b/libpurple/protocols/oscar/Makefile.am
@@ -6,10 +6,11 @@ EXTRA_DIST = \
pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
OSCARSOURCES = \
+ authorization.c \
bstream.c \
clientlogin.c \
+ encoding.c \
family_admin.c \
- family_advert.c \
family_alert.c \
family_auth.c \
family_bart.c \
@@ -19,14 +20,11 @@ OSCARSOURCES = \
family_chatnav.c \
family_icq.c \
family_icbm.c \
- family_invite.c \
family_locate.c \
- family_odir.c \
family_oservice.c \
family_popup.c \
family_feedbag.c \
family_stats.c \
- family_translate.c \
family_userlookup.c \
flap_connection.c \
misc.c \
@@ -44,7 +42,9 @@ OSCARSOURCES = \
snac.c \
snactypes.h \
tlv.c \
- util.c
+ userinfo.c \
+ util.c \
+ visibility.c
AM_CFLAGS = $(st)
diff --git a/libpurple/protocols/oscar/Makefile.mingw b/libpurple/protocols/oscar/Makefile.mingw
index e9b7edd5fd..fa70dd433f 100644
--- a/libpurple/protocols/oscar/Makefile.mingw
+++ b/libpurple/protocols/oscar/Makefile.mingw
@@ -41,10 +41,11 @@ LIB_PATHS += -L$(GTK_TOP)/lib \
## SOURCES, OBJECTS
##
C_SRC = \
+ authorization.c \
bstream.c \
clientlogin.c \
+ encoding.c \
family_admin.c \
- family_advert.c \
family_alert.c \
family_auth.c \
family_bart.c \
@@ -52,16 +53,13 @@ C_SRC = \
family_buddy.c \
family_chat.c \
family_chatnav.c \
- family_icq.c \
+ family_feedbag.c \
family_icbm.c \
- family_invite.c \
+ family_icq.c \
family_locate.c \
- family_odir.c \
- family_popup.c \
family_oservice.c \
- family_feedbag.c \
+ family_popup.c \
family_stats.c \
- family_translate.c \
family_userlookup.c \
flap_connection.c \
misc.c \
@@ -75,7 +73,9 @@ C_SRC = \
rxhandlers.c \
snac.c \
tlv.c \
- util.c
+ userinfo.c \
+ util.c \
+ visibility.c
OBJECTS = $(C_SRC:%.c=%.o)
diff --git a/libpurple/protocols/oscar/authorization.c b/libpurple/protocols/oscar/authorization.c
new file mode 100644
index 0000000000..877605c3a2
--- /dev/null
+++ b/libpurple/protocols/oscar/authorization.c
@@ -0,0 +1,153 @@
+/*
+ * Purple's oscar protocol plugin
+ * This file is the legal property of its developers.
+ * Please see the AUTHORS file distributed alongside this file.
+ *
+ * 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 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
+*/
+
+/*
+ * Everything related to OSCAR authorization requests.
+ */
+
+#include "oscar.h"
+#include "request.h"
+
+static void
+oscar_auth_request(struct name_data *data, char *msg)
+{
+ PurpleConnection *gc;
+ OscarData *od;
+ PurpleAccount *account;
+ PurpleBuddy *buddy;
+ PurpleGroup *group;
+ const char *bname, *gname;
+
+ gc = data->gc;
+ od = purple_connection_get_protocol_data(gc);
+ account = purple_connection_get_account(gc);
+ buddy = purple_find_buddy(account, data->name);
+ if (buddy != NULL)
+ group = purple_buddy_get_group(buddy);
+ else
+ group = NULL;
+
+ if (group != NULL)
+ {
+ bname = purple_buddy_get_name(buddy);
+ gname = purple_group_get_name(group);
+ purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
+ bname, gname);
+ aim_ssi_sendauthrequest(od, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
+ if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
+ {
+ aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);
+
+ /* Mobile users should always be online */
+ if (bname[0] == '+') {
+ purple_prpl_got_user_status(account,
+ purple_buddy_get_name(buddy),
+ OSCAR_STATUS_ID_AVAILABLE, NULL);
+ purple_prpl_got_user_status(account,
+ purple_buddy_get_name(buddy),
+ OSCAR_STATUS_ID_MOBILE, NULL);
+ }
+ }
+ }
+
+ oscar_free_name_data(data);
+}
+
+static void
+oscar_auth_grant(gpointer cbdata)
+{
+ struct name_data *data = cbdata;
+ PurpleConnection *gc = data->gc;
+ OscarData *od = purple_connection_get_protocol_data(gc);
+
+ aim_ssi_sendauthreply(od, data->name, 0x01, NULL);
+
+ oscar_free_name_data(data);
+}
+
+static void
+oscar_auth_dontgrant(struct name_data *data, char *msg)
+{
+ PurpleConnection *gc = data->gc;
+ OscarData *od = purple_connection_get_protocol_data(gc);
+
+ aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given."));
+
+ oscar_free_name_data(data);
+}
+
+static void
+oscar_auth_dontgrant_msgprompt(gpointer cbdata)
+{
+ struct name_data *data = cbdata;
+ purple_request_input(data->gc, NULL, _("Authorization Denied Message:"),
+ NULL, _("No reason given."), TRUE, FALSE, NULL,
+ _("_OK"), G_CALLBACK(oscar_auth_dontgrant),
+ _("_Cancel"), G_CALLBACK(oscar_free_name_data),
+ purple_connection_get_account(data->gc), data->name, NULL,
+ data);
+}
+
+/* When you ask other people for authorization */
+void
+oscar_auth_sendrequest(PurpleConnection *gc, const char *name)
+{
+ struct name_data *data;
+
+ data = g_new0(struct name_data, 1);
+ data->gc = gc;
+ data->name = g_strdup(name);
+
+ purple_request_input(data->gc, NULL, _("Authorization Request Message:"),
+ NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
+ _("_OK"), G_CALLBACK(oscar_auth_request),
+ _("_Cancel"), G_CALLBACK(oscar_free_name_data),
+ purple_connection_get_account(gc), name, NULL,
+ data);
+}
+
+void
+oscar_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored)
+{
+ PurpleBuddy *buddy;
+ PurpleConnection *gc;
+
+ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+
+ buddy = (PurpleBuddy *) node;
+ gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+ oscar_auth_sendrequest(gc, purple_buddy_get_name(buddy));
+}
+
+/* When other people ask you for authorization */
+void
+oscar_auth_recvrequest(PurpleConnection *gc, gchar *name, gchar *nick, gchar *reason)
+{
+ PurpleAccount* account = purple_connection_get_account(gc);
+ struct name_data *data = g_new(struct name_data, 1);
+
+ data->gc = gc;
+ data->name = name;
+ data->nick = nick;
+
+ purple_account_request_authorization(account, data->name, NULL, data->nick,
+ reason, purple_find_buddy(account, data->name) != NULL,
+ oscar_auth_grant, oscar_auth_dontgrant_msgprompt, data);
+} \ No newline at end of file
diff --git a/libpurple/protocols/oscar/bstream.c b/libpurple/protocols/oscar/bstream.c
index cee0c87b54..31acac2724 100644
--- a/libpurple/protocols/oscar/bstream.c
+++ b/libpurple/protocols/oscar/bstream.c
@@ -24,7 +24,7 @@
#include "oscar.h"
-int byte_stream_new(ByteStream *bs, guint32 len)
+int byte_stream_new(ByteStream *bs, size_t len)
{
if (bs == NULL)
return -1;
@@ -32,9 +32,8 @@ int byte_stream_new(ByteStream *bs, guint32 len)
return byte_stream_init(bs, g_malloc(len), len);
}
-int byte_stream_init(ByteStream *bs, guint8 *data, int len)
+int byte_stream_init(ByteStream *bs, guint8 *data, size_t len)
{
-
if (bs == NULL)
return -1;
@@ -50,7 +49,7 @@ void byte_stream_destroy(ByteStream *bs)
g_free(bs->data);
}
-int byte_stream_empty(ByteStream *bs)
+int byte_stream_bytes_left(ByteStream *bs)
{
return bs->len - bs->offset;
}
@@ -60,229 +59,172 @@ int byte_stream_curpos(ByteStream *bs)
return bs->offset;
}
-int byte_stream_setpos(ByteStream *bs, unsigned int off)
+int byte_stream_setpos(ByteStream *bs, size_t off)
{
-
- if (off > bs->len)
- return -1;
+ g_return_val_if_fail(off <= bs->len, -1);
bs->offset = off;
-
return off;
}
void byte_stream_rewind(ByteStream *bs)
{
-
byte_stream_setpos(bs, 0);
-
- return;
}
/*
* N can be negative, which can be used for going backwards
- * in a bstream. I'm not sure if libfaim actually does
- * this anywhere...
+ * in a bstream.
*/
int byte_stream_advance(ByteStream *bs, int n)
{
-
- if ((byte_stream_curpos(bs) + n < 0) || (byte_stream_empty(bs) < n))
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_curpos(bs) + n >= 0, 0);
+ g_return_val_if_fail(n <= byte_stream_bytes_left(bs), 0);
bs->offset += n;
-
return n;
}
guint8 byte_stream_get8(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 1)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
bs->offset++;
-
return aimutil_get8(bs->data + bs->offset - 1);
}
guint16 byte_stream_get16(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 2)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
bs->offset += 2;
-
return aimutil_get16(bs->data + bs->offset - 2);
}
guint32 byte_stream_get32(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 4)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
bs->offset += 4;
-
return aimutil_get32(bs->data + bs->offset - 4);
}
guint8 byte_stream_getle8(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 1)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
bs->offset++;
-
return aimutil_getle8(bs->data + bs->offset - 1);
}
guint16 byte_stream_getle16(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 2)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
bs->offset += 2;
-
return aimutil_getle16(bs->data + bs->offset - 2);
}
guint32 byte_stream_getle32(ByteStream *bs)
{
-
- if (byte_stream_empty(bs) < 4)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
bs->offset += 4;
-
return aimutil_getle32(bs->data + bs->offset - 4);
}
-static void byte_stream_getrawbuf_nocheck(ByteStream *bs, guint8 *buf, int len)
+static void byte_stream_getrawbuf_nocheck(ByteStream *bs, guint8 *buf, size_t len)
{
memcpy(buf, bs->data + bs->offset, len);
bs->offset += len;
}
-int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, int len)
+int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, size_t len)
{
-
- if (byte_stream_empty(bs) < len)
- return 0;
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
byte_stream_getrawbuf_nocheck(bs, buf, len);
return len;
}
-guint8 *byte_stream_getraw(ByteStream *bs, int len)
+guint8 *byte_stream_getraw(ByteStream *bs, size_t len)
{
guint8 *ob;
- if (byte_stream_empty(bs) < len)
- return NULL;
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
ob = g_malloc(len);
-
byte_stream_getrawbuf_nocheck(bs, ob, len);
-
return ob;
}
-char *byte_stream_getstr(ByteStream *bs, int len)
+char *byte_stream_getstr(ByteStream *bs, size_t len)
{
char *ob;
- if (byte_stream_empty(bs) < len)
- return NULL;
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
ob = g_malloc(len + 1);
-
byte_stream_getrawbuf_nocheck(bs, (guint8 *)ob, len);
-
ob[len] = '\0';
-
return ob;
}
int byte_stream_put8(ByteStream *bs, guint8 v)
{
-
- if (byte_stream_empty(bs) < 1)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
bs->offset += aimutil_put8(bs->data + bs->offset, v);
-
return 1;
}
int byte_stream_put16(ByteStream *bs, guint16 v)
{
-
- if (byte_stream_empty(bs) < 2)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
bs->offset += aimutil_put16(bs->data + bs->offset, v);
-
return 2;
}
int byte_stream_put32(ByteStream *bs, guint32 v)
{
-
- if (byte_stream_empty(bs) < 4)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
bs->offset += aimutil_put32(bs->data + bs->offset, v);
-
return 1;
}
int byte_stream_putle8(ByteStream *bs, guint8 v)
{
-
- if (byte_stream_empty(bs) < 1)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
bs->offset += aimutil_putle8(bs->data + bs->offset, v);
-
return 1;
}
int byte_stream_putle16(ByteStream *bs, guint16 v)
{
-
- if (byte_stream_empty(bs) < 2)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
bs->offset += aimutil_putle16(bs->data + bs->offset, v);
-
return 2;
}
int byte_stream_putle32(ByteStream *bs, guint32 v)
{
-
- if (byte_stream_empty(bs) < 4)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
bs->offset += aimutil_putle32(bs->data + bs->offset, v);
-
return 1;
}
-int byte_stream_putraw(ByteStream *bs, const guint8 *v, int len)
+int byte_stream_putraw(ByteStream *bs, const guint8 *v, size_t len)
{
-
- if (byte_stream_empty(bs) < len)
- return 0; /* XXX throw an exception */
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
memcpy(bs->data + bs->offset, v, len);
bs->offset += len;
-
return len;
}
@@ -291,19 +233,14 @@ int byte_stream_putstr(ByteStream *bs, const char *str)
return byte_stream_putraw(bs, (guint8 *)str, strlen(str));
}
-int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, int len)
+int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, size_t len)
{
-
- if (byte_stream_empty(srcbs) < len)
- return 0; /* XXX throw exception (underrun) */
-
- if (byte_stream_empty(bs) < len)
- return 0; /* XXX throw exception (overflow) */
+ g_return_val_if_fail(byte_stream_bytes_left(srcbs) >= len, 0);
+ g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
memcpy(bs->data + bs->offset, srcbs->data + srcbs->offset, len);
bs->offset += len;
srcbs->offset += len;
-
return len;
}
diff --git a/libpurple/protocols/oscar/encoding.c b/libpurple/protocols/oscar/encoding.c
new file mode 100644
index 0000000000..985f2cb295
--- /dev/null
+++ b/libpurple/protocols/oscar/encoding.c
@@ -0,0 +1,235 @@
+/*
+ * Purple's oscar protocol plugin
+ * This file is the legal property of its developers.
+ * Please see the AUTHORS file distributed alongside this file.
+ *
+ * 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 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
+*/
+
+#include "encoding.h"
+
+static gchar *
+encoding_extract(const char *encoding)
+{
+ char *begin, *end;
+
+ if (encoding == NULL) {
+ return NULL;
+ }
+
+ if (!g_str_has_prefix(encoding, "text/aolrtf; charset=") &&
+ !g_str_has_prefix(encoding, "text/x-aolrtf; charset=") &&
+ !g_str_has_prefix(encoding, "text/plain; charset=")) {
+ return g_strdup(encoding);
+ }
+
+ begin = strchr(encoding, '"');
+ end = strrchr(encoding, '"');
+
+ if ((begin == NULL) || (end == NULL) || (begin >= end)) {
+ return g_strdup(encoding);
+ }
+
+ return g_strndup(begin+1, (end-1) - begin);
+}
+
+gchar *
+oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen)
+{
+ gchar *utf8 = NULL;
+ const gchar *glib_encoding = NULL;
+ gchar *extracted_encoding = encoding_extract(encoding);
+
+ if (extracted_encoding == NULL || *extracted_encoding == '\0') {
+ purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");
+ } else if (!g_ascii_strcasecmp(extracted_encoding, "iso-8859-1")) {
+ glib_encoding = "iso-8859-1";
+ } else if (!g_ascii_strcasecmp(extracted_encoding, "ISO-8859-1-Windows-3.1-Latin-1") || !g_ascii_strcasecmp(extracted_encoding, "us-ascii")) {
+ glib_encoding = "Windows-1252";
+ } else if (!g_ascii_strcasecmp(extracted_encoding, "unicode-2-0")) {
+ glib_encoding = "UTF-16BE";
+ } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) {
+ purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", attempting to convert to UTF-8 anyway\n", extracted_encoding);
+ glib_encoding = extracted_encoding;
+ }
+
+ if (glib_encoding != NULL) {
+ utf8 = g_convert(text, textlen, "UTF-8", glib_encoding, NULL, NULL, NULL);
+ }
+
+ /*
+ * If utf8 is still NULL then either the encoding is utf-8 or
+ * we have been unable to convert the text to utf-8 from the encoding
+ * that was specified. So we check if the text is valid utf-8 then
+ * just copy it.
+ */
+ if (utf8 == NULL) {
+ if (textlen != 0 && *text != '\0' && !g_utf8_validate(text, textlen, NULL))
+ utf8 = g_strdup(_("(There was an error receiving this message. The buddy you are speaking with is probably using a different encoding than expected. If you know what encoding he is using, you can specify it in the advanced account options for your AIM/ICQ account.)"));
+ else
+ utf8 = g_strndup(text, textlen);
+ }
+
+ g_free(extracted_encoding);
+ return utf8;
+}
+
+gchar *
+oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg)
+{
+ const char *charset = NULL;
+ char *ret = NULL;
+
+ if (msg == NULL)
+ return NULL;
+
+ if (g_utf8_validate(msg, -1, NULL))
+ return g_strdup(msg);
+
+ if (od->icq)
+ charset = purple_account_get_string(account, "encoding", NULL);
+
+ if(charset && *charset)
+ ret = g_convert(msg, -1, "UTF-8", charset, NULL, NULL, NULL);
+
+ if(!ret)
+ ret = purple_utf8_try_convert(msg);
+
+ return ret;
+}
+
+static gchar *
+oscar_convert_to_utf8(const gchar *data, gsize datalen, const char *charsetstr, gboolean fallback)
+{
+ gchar *ret = NULL;
+ GError *err = NULL;
+
+ if ((charsetstr == NULL) || (*charsetstr == '\0'))
+ return NULL;
+
+ if (g_ascii_strcasecmp("UTF-8", charsetstr)) {
+ if (fallback)
+ ret = g_convert_with_fallback(data, datalen, "UTF-8", charsetstr, "?", NULL, NULL, &err);
+ else
+ ret = g_convert(data, datalen, "UTF-8", charsetstr, NULL, NULL, &err);
+ if (err != NULL) {
+ purple_debug_warning("oscar", "Conversion from %s failed: %s.\n",
+ charsetstr, err->message);
+ g_error_free(err);
+ }
+ } else {
+ if (g_utf8_validate(data, datalen, NULL))
+ ret = g_strndup(data, datalen);
+ else
+ purple_debug_warning("oscar", "String is not valid UTF-8.\n");
+ }
+
+ return ret;
+}
+
+gchar *
+oscar_decode_im(PurpleAccount *account, const char *sourcebn, guint16 charset, const gchar *data, gsize datalen)
+{
+ gchar *ret = NULL;
+ /* charsetstr1 is always set to what the correct encoding should be. */
+ const gchar *charsetstr1, *charsetstr2, *charsetstr3 = NULL;
+
+ if ((datalen == 0) || (data == NULL))
+ return NULL;
+
+ if (charset == AIM_CHARSET_UNICODE) {
+ charsetstr1 = "UTF-16BE";
+ charsetstr2 = "UTF-8";
+ } else if (charset == AIM_CHARSET_LATIN_1) {
+ if ((sourcebn != NULL) && oscar_util_valid_name_icq(sourcebn))
+ charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+ else
+ charsetstr1 = "ISO-8859-1";
+ charsetstr2 = "UTF-8";
+ } else if (charset == AIM_CHARSET_ASCII) {
+ /* Should just be "ASCII" */
+ charsetstr1 = "ASCII";
+ charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+ } else if (charset == 0x000d) {
+ /* iChat sending unicode over a Direct IM connection = UTF-8 */
+ /* Mobile AIM client on multiple devices (including Blackberry Tour, Nokia 3100, and LG VX6000) = ISO-8859-1 */
+ charsetstr1 = "UTF-8";
+ charsetstr2 = "ISO-8859-1";
+ charsetstr3 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+ } else {
+ /* Unknown, hope for valid UTF-8... */
+ charsetstr1 = "UTF-8";
+ charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
+ }
+
+ purple_debug_info("oscar", "Parsing IM, charset=0x%04hx, datalen=%" G_GSIZE_FORMAT ", choice1=%s, choice2=%s, choice3=%s\n",
+ charset, datalen, charsetstr1, charsetstr2, (charsetstr3 ? charsetstr3 : ""));
+
+ ret = oscar_convert_to_utf8(data, datalen, charsetstr1, FALSE);
+ if (ret == NULL) {
+ if (charsetstr3 != NULL) {
+ /* Try charsetstr2 without allowing substitutions, then fall through to charsetstr3 if needed */
+ ret = oscar_convert_to_utf8(data, datalen, charsetstr2, FALSE);
+ if (ret == NULL)
+ ret = oscar_convert_to_utf8(data, datalen, charsetstr3, TRUE);
+ } else {
+ /* Try charsetstr2, allowing substitutions */
+ ret = oscar_convert_to_utf8(data, datalen, charsetstr2, TRUE);
+ }
+ }
+ if (ret == NULL) {
+ char *str, *salvage, *tmp;
+
+ str = g_malloc(datalen + 1);
+ strncpy(str, data, datalen);
+ str[datalen] = '\0';
+ salvage = purple_utf8_salvage(str);
+ tmp = g_strdup_printf(_("(There was an error receiving this message. Either you and %s have different encodings selected, or %s has a buggy client.)"),
+ sourcebn, sourcebn);
+ ret = g_strdup_printf("%s %s", salvage, tmp);
+ g_free(tmp);
+ g_free(str);
+ g_free(salvage);
+ }
+
+ return ret;
+}
+
+static guint16
+get_simplest_charset(const char *utf8)
+{
+ while (*utf8)
+ {
+ if ((unsigned char)(*utf8) > 0x7f) {
+ /* not ASCII! */
+ return AIM_CHARSET_UNICODE;
+ }
+ utf8++;
+ }
+ return AIM_CHARSET_ASCII;
+}
+
+gchar *
+oscar_encode_im(const gchar *msg, gsize *result_len, guint16 *charset, gchar **charsetstr)
+{
+ guint16 msg_charset = get_simplest_charset(msg);
+ if (charset != NULL) {
+ *charset = msg_charset;
+ }
+ if (charsetstr != NULL) {
+ *charsetstr = msg_charset == AIM_CHARSET_ASCII ? "us-ascii" : "unicode-2-0";
+ }
+ return g_convert(msg, -1, msg_charset == AIM_CHARSET_ASCII ? "ASCII" : "UTF-16BE", "UTF-8", NULL, result_len, NULL);
+}
diff --git a/libpurple/protocols/oscar/encoding.h b/libpurple/protocols/oscar/encoding.h
new file mode 100644
index 0000000000..5f47ec47bf
--- /dev/null
+++ b/libpurple/protocols/oscar/encoding.h
@@ -0,0 +1,46 @@
+/*
+ * Purple's oscar protocol plugin
+ * This file is the legal property of its developers.
+ * Please see the AUTHORS file distributed alongside this file.
+ *
+ * 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 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
+*/
+
+#ifndef _ENCODING_H_
+#define _ENCODING_H_
+
+#include "oscar.h"
+#include "oscarcommon.h"
+
+gchar * oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen);
+gchar * oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg);
+
+/**
+ * This attemps to decode an incoming IM into a UTF8 string.
+ *
+ * We try decoding using two different character sets. The charset
+ * specified in the IM determines the order in which we attempt to
+ * decode. We do this because there are lots of broken ICQ clients
+ * that don't correctly send non-ASCII messages. And if Purple isn't
+ * able to deal with that crap, then people complain like banshees.
+ */
+gchar * oscar_decode_im(PurpleAccount *account, const char *sourcebn, guint16 charset, const gchar *data, gsize datalen);
+
+/**
+ * Figure out what encoding to use when sending a given outgoing message.
+ */
+gchar * oscar_encode_im(const gchar *msg, gsize *result_len, guint16 *charset, gchar **charsetstr);
+
+#endif \ No newline at end of file
diff --git a/libpurple/protocols/oscar/family_admin.c b/libpurple/protocols/oscar/family_admin.c
index c276f12cb9..d199a789c1 100644
--- a/libpurple/protocols/oscar/family_admin.c
+++ b/libpurple/protocols/oscar/family_admin.c
@@ -47,7 +47,7 @@ aim_admin_getinfo(OscarData *od, FlapConnection *conn, guint16 info)
byte_stream_put16(&bs, 0x0000);
snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -68,7 +68,7 @@ infochange(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fr
perms = byte_stream_get16(bs);
tlvcount = byte_stream_get16(bs);
- while (tlvcount && byte_stream_empty(bs)) {
+ while (tlvcount && byte_stream_bytes_left(bs)) {
guint16 type, length;
type = byte_stream_get16(bs);
@@ -127,7 +127,7 @@ aim_admin_setnick(OscarData *od, FlapConnection *conn, const char *newnick)
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -154,7 +154,7 @@ aim_admin_changepasswd(OscarData *od, FlapConnection *conn, const char *newpw, c
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -177,7 +177,7 @@ aim_admin_setemail(OscarData *od, FlapConnection *conn, const char *newemail)
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ADMIN, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
}
diff --git a/libpurple/protocols/oscar/family_advert.c b/libpurple/protocols/oscar/family_advert.c
deleted file mode 100644
index fcd1677ce6..0000000000
--- a/libpurple/protocols/oscar/family_advert.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Purple's oscar protocol plugin
- * This file is the legal property of its developers.
- * Please see the AUTHORS file distributed alongside this file.
- *
- * 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 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
-*/
-
-/*
- * Family 0x0005 - Advertisements.
- *
- */
-
-#include "oscar.h"
-
-void
-aim_ads_requestads(OscarData *od, FlapConnection *conn)
-{
- aim_genericreq_n(od, conn, SNAC_FAMILY_ADVERT, 0x0002);
-}
-
-static int snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
-{
- return 0;
-}
-
-int adverts_modfirst(OscarData *od, aim_module_t *mod)
-{
-
- mod->family = SNAC_FAMILY_ADVERT;
- mod->version = 0x0001;
- mod->toolid = 0x0001;
- mod->toolversion = 0x0001;
- mod->flags = 0;
- strncpy(mod->name, "advert", sizeof(mod->name));
- mod->snachandler = snachandler;
-
- return 0;
-}
diff --git a/libpurple/protocols/oscar/family_alert.c b/libpurple/protocols/oscar/family_alert.c
index df6f909d7a..58f535a7a2 100644
--- a/libpurple/protocols/oscar/family_alert.c
+++ b/libpurple/protocols/oscar/family_alert.c
@@ -73,7 +73,7 @@ aim_email_sendcookies(OscarData *od)
byte_stream_put16(&bs, 0x0631);
snacid = aim_cachesnac(od, SNAC_FAMILY_ALERT, 0x0006, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
@@ -189,7 +189,7 @@ aim_email_activate(OscarData *od)
byte_stream_put32(&bs, 0x00000000);
snacid = aim_cachesnac(od, SNAC_FAMILY_ALERT, 0x0016, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ALERT, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
diff --git a/libpurple/protocols/oscar/family_auth.c b/libpurple/protocols/oscar/family_auth.c
index db7a1a0920..ac011df63d 100644
--- a/libpurple/protocols/oscar/family_auth.c
+++ b/libpurple/protocols/oscar/family_auth.c
@@ -56,17 +56,10 @@ static int
aim_encode_password(const char *password, guint8 *encoded)
{
guint8 encoding_table[] = {
-#if 0 /* old v1 table */
- 0xf3, 0xb3, 0x6c, 0x99,
- 0x95, 0x3f, 0xac, 0xb6,
- 0xc5, 0xfa, 0x6b, 0x63,
- 0x69, 0x6c, 0xc3, 0x9f
-#else /* v2.1 table, also works for ICQ */
0xf3, 0x26, 0x81, 0xc4,
0x39, 0x86, 0xdb, 0x92,
0x71, 0xa3, 0xb9, 0xe6,
0x53, 0x7a, 0x95, 0x7c
-#endif
};
unsigned int i;
@@ -234,7 +227,7 @@ aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *
frame = flap_frame_new(od, 0x02, 1152);
snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0002, 0x0000, NULL, 0);
- aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0002, 0x0000, snacid);
+ aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0002, snacid);
aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
@@ -385,12 +378,6 @@ parse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame,
if (aim_tlv_gettlv(tlvlist, 0x0043, 1))
info->latestbeta.name = aim_tlv_getstr(tlvlist, 0x0043, 1);
-#if 0
- if (aim_tlv_gettlv(tlvlist, 0x0048, 1)) {
- /* beta serial */
- }
-#endif
-
if (aim_tlv_gettlv(tlvlist, 0x0044, 1))
info->latestrelease.build = aim_tlv_get32(tlvlist, 0x0044, 1);
if (aim_tlv_gettlv(tlvlist, 0x0045, 1))
@@ -400,27 +387,12 @@ parse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame,
if (aim_tlv_gettlv(tlvlist, 0x0047, 1))
info->latestrelease.name = aim_tlv_getstr(tlvlist, 0x0047, 1);
-#if 0
- if (aim_tlv_gettlv(tlvlist, 0x0049, 1)) {
- /* lastest release serial */
- }
-#endif
-
/*
* URL to change password.
*/
if (aim_tlv_gettlv(tlvlist, 0x0054, 1))
info->chpassurl = aim_tlv_getstr(tlvlist, 0x0054, 1);
-#if 0
- /*
- * Unknown. Seen on an @mac.com username with value of 0x003f
- */
- if (aim_tlv_gettlv(tlvlist, 0x0055, 1)) {
- /* Unhandled */
- }
-#endif
-
od->authinfo = info;
if ((userfunc = aim_callhandler(od, snac ? snac->family : SNAC_FAMILY_AUTH, snac ? snac->subtype : 0x0003)))
@@ -504,7 +476,7 @@ aim_request_login(OscarData *od, FlapConnection *conn, const char *sn)
frame = flap_frame_new(od, 0x02, 10+2+2+strlen(sn)+8);
snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0006, 0x0000, NULL, 0);
- aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0006, 0x0000, snacid);
+ aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0006, snacid);
aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
@@ -602,7 +574,7 @@ aim_auth_securid_send(OscarData *od, const char *securid)
frame = flap_frame_new(od, 0x02, 10+2+len);
snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_RESPONSE, 0x0000, NULL, 0);
- aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_RESPONSE, 0x0000, 0);
+ aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_RESPONSE, 0);
byte_stream_put16(&frame->data, len);
byte_stream_putstr(&frame->data, securid);
diff --git a/libpurple/protocols/oscar/family_bart.c b/libpurple/protocols/oscar/family_bart.c
index ee388456bd..cd7ca43839 100644
--- a/libpurple/protocols/oscar/family_bart.c
+++ b/libpurple/protocols/oscar/family_bart.c
@@ -56,7 +56,7 @@ aim_bart_upload(OscarData *od, const guint8 *icon, guint16 iconlen)
byte_stream_putraw(&bs, icon, iconlen);
snacid = aim_cachesnac(od, SNAC_FAMILY_BART, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
@@ -121,7 +121,7 @@ aim_bart_request(OscarData *od, const char *bn, guint8 iconcsumtype, const guint
byte_stream_putraw(&bs, iconcsum, iconcsumlen);
snacid = aim_cachesnac(od, SNAC_FAMILY_BART, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_BART, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
diff --git a/libpurple/protocols/oscar/family_bos.c b/libpurple/protocols/oscar/family_bos.c
index 2790b2ed82..16defd2076 100644
--- a/libpurple/protocols/oscar/family_bos.c
+++ b/libpurple/protocols/oscar/family_bos.c
@@ -68,98 +68,6 @@ static int rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFr
return ret;
}
-/*
- * Subtype 0x0004 - Set group permission mask.
- *
- * Normally 0x1f (all classes).
- *
- * The group permission mask allows you to keep users of a certain
- * class or classes from talking to you. The mask should be
- * a bitwise OR of all the user classes you want to see you.
- *
- */
-void
-aim_bos_setgroupperm(OscarData *od, FlapConnection *conn, guint32 mask)
-{
- aim_genericreq_l(od, conn, SNAC_FAMILY_BOS, 0x0004, &mask);
-}
-
-/*
- * Stubtypes 0x0005, 0x0006, 0x0007, and 0x0008 - Modify permit/deny lists.
- *
- * Changes your visibility depending on changetype:
- *
- * AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
- * AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
- * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
- * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
- *
- * list should be a list of "Buddy Name One&BuddyNameTwo&" etc.
- *
- * Equivelents to options in WinAIM:
- * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
- * with only your name on it.
- * - Allow only users on my Buddy List: Send an
- * AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
- * buddy list
- * - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
- * with everyone listed that you want to see you.
- * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
- * yourself in the list
- * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
- * the list of users to be blocked
- *
- * XXX ye gods.
- */
-int aim_bos_changevisibility(OscarData *od, FlapConnection *conn, int changetype, const char *denylist)
-{
- ByteStream bs;
- int packlen = 0;
- guint16 subtype;
- char *localcpy = NULL, *tmpptr = NULL;
- int i;
- int listcount;
- aim_snacid_t snacid;
-
- if (!denylist)
- return -EINVAL;
-
- if (changetype == AIM_VISIBILITYCHANGE_PERMITADD)
- subtype = 0x05;
- else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE)
- subtype = 0x06;
- else if (changetype == AIM_VISIBILITYCHANGE_DENYADD)
- subtype = 0x07;
- else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE)
- subtype = 0x08;
- else
- return -EINVAL;
-
- localcpy = g_strdup(denylist);
-
- listcount = aimutil_itemcnt(localcpy, '&');
- packlen = aimutil_tokslen(localcpy, 99, '&') + listcount-1;
-
- byte_stream_new(&bs, packlen);
-
- for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
- tmpptr = aimutil_itemindex(localcpy, i, '&');
-
- byte_stream_put8(&bs, strlen(tmpptr));
- byte_stream_putstr(&bs, tmpptr);
-
- g_free(tmpptr);
- }
- g_free(localcpy);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_BOS, subtype, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BOS, subtype, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
static int
snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
diff --git a/libpurple/protocols/oscar/family_buddy.c b/libpurple/protocols/oscar/family_buddy.c
index 7efd60e520..a58232a058 100644
--- a/libpurple/protocols/oscar/family_buddy.c
+++ b/libpurple/protocols/oscar/family_buddy.c
@@ -88,117 +88,6 @@ rights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame,
}
/*
- * Subtype 0x0004 (SNAC_SUBTYPE_BUDDY_ADDBUDDY) - Add buddy to list.
- *
- * Adds a single buddy to your buddy list after login.
- * XXX This should just be an extension of setbuddylist()
- *
- */
-int
-aim_buddylist_addbuddy(OscarData *od, FlapConnection *conn, const char *sn)
-{
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!sn || !strlen(sn))
- return -EINVAL;
-
- byte_stream_new(&bs, 1+strlen(sn));
-
- byte_stream_put8(&bs, strlen(sn));
- byte_stream_putstr(&bs, sn);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, sn, strlen(sn)+1);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
- * Subtype 0x0004 (SNAC_SUBTYPE_BUDDY_ADDBUDDY) - Add multiple buddies to your buddy list.
- *
- * This just builds the "set buddy list" command then queues it.
- *
- * buddy_list = "Buddy Name One&BuddyNameTwo&";
- *
- * XXX Clean this up.
- *
- */
-int
-aim_buddylist_set(OscarData *od, FlapConnection *conn, const char *buddy_list)
-{
- ByteStream bs;
- aim_snacid_t snacid;
- int len = 0;
- char *localcpy = NULL;
- char *tmpptr = NULL;
-
- if (!buddy_list || !(localcpy = g_strdup(buddy_list)))
- return -EINVAL;
-
- for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
- purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT
- ")\n", tmpptr, strlen(tmpptr));
- len += 1 + strlen(tmpptr);
- tmpptr = strtok(NULL, "&");
- }
-
- byte_stream_new(&bs, len);
-
- strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
-
- for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
-
- purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT
- ")\n", tmpptr, strlen(tmpptr));
-
- byte_stream_put8(&bs, strlen(tmpptr));
- byte_stream_putstr(&bs, tmpptr);
- tmpptr = strtok(NULL, "&");
- }
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- g_free(localcpy);
-
- return 0;
-}
-
-/*
- * Subtype 0x0005 (SNAC_SUBTYPE_BUDDY_REMBUDDY) - Remove buddy from list.
- *
- * XXX generalise to support removing multiple buddies (basically, its
- * the same as setbuddylist() but with a different snac subtype).
- *
- */
-int
-aim_buddylist_removebuddy(OscarData *od, FlapConnection *conn, const char *sn)
-{
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!sn || !strlen(sn))
- return -EINVAL;
-
- byte_stream_new(&bs, 1 + strlen(sn));
-
- byte_stream_put8(&bs, strlen(sn));
- byte_stream_putstr(&bs, sn);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0005, 0x0000, sn, strlen(sn)+1);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0005, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
* Subtypes 0x000b (SNAC_SUBTYPE_BUDDY_ONCOMING) and 0x000c (SNAC_SUBTYPE_BUDDY_OFFGOING) - Change in buddy status
*
* Oncoming Buddy notifications contain a subset of the
diff --git a/libpurple/protocols/oscar/family_chat.c b/libpurple/protocols/oscar/family_chat.c
index 9e25b22cc3..89fa331c0c 100644
--- a/libpurple/protocols/oscar/family_chat.c
+++ b/libpurple/protocols/oscar/family_chat.c
@@ -47,74 +47,6 @@ flap_connection_destroy_chat(OscarData *od, FlapConnection *conn)
return;
}
-char *
-aim_chat_getname(FlapConnection *conn)
-{
- struct chatconnpriv *ccp;
-
- if (!conn)
- return NULL;
-
- if (conn->type != SNAC_FAMILY_CHAT)
- return NULL;
-
- ccp = (struct chatconnpriv *)conn->internal;
-
- return ccp->name;
-}
-
-/* XXX get this into conn.c -- evil!! */
-FlapConnection *
-aim_chat_getconn(OscarData *od, const char *name)
-{
- GSList *cur;
-
- for (cur = od->oscar_connections; cur; cur = cur->next)
- {
- FlapConnection *conn;
- struct chatconnpriv *ccp;
-
- conn = cur->data;
- ccp = (struct chatconnpriv *)conn->internal;
-
- if (conn->type != SNAC_FAMILY_CHAT)
- continue;
- if (!conn->internal)
- {
- purple_debug_misc("oscar", "%sfaim: chat: chat connection with no name! (fd = %d)\n",
- conn->gsc ? "(ssl) " : "", conn->gsc ? conn->gsc->fd : conn->fd);
- continue;
- }
-
- if (strcmp(ccp->name, name) == 0)
- return conn;
- }
-
- return NULL;
-}
-
-int
-aim_chat_attachname(FlapConnection *conn, guint16 exchange, const char *roomname, guint16 instance)
-{
- struct chatconnpriv *ccp;
-
- if (!conn || !roomname)
- return -EINVAL;
-
- if (conn->internal)
- g_free(conn->internal);
-
- ccp = g_new(struct chatconnpriv, 1);
-
- ccp->exchange = exchange;
- ccp->name = g_strdup(roomname);
- ccp->instance = instance;
-
- conn->internal = (void *)ccp;
-
- return 0;
-}
-
int
aim_chat_readroominfo(ByteStream *bs, struct aim_chat_roominfo *outinfo)
{
@@ -129,19 +61,6 @@ aim_chat_readroominfo(ByteStream *bs, struct aim_chat_roominfo *outinfo)
return 0;
}
-int
-aim_chat_leaveroom(OscarData *od, const char *name)
-{
- FlapConnection *conn;
-
- if (!(conn = aim_chat_getconn(od, name)))
- return -ENOENT;
-
- flap_connection_close(od, conn);
-
- return 0;
-}
-
/*
* Subtype 0x0002 - General room information. Lots of stuff.
*
@@ -153,21 +72,12 @@ aim_chat_leaveroom(OscarData *od, const char *name)
static int
infoupdate(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- aim_userinfo_t *userinfo = NULL;
aim_rxcallback_t userfunc;
int ret = 0;
- int usercount;
guint8 detaillevel = 0;
- char *roomname;
struct aim_chat_roominfo roominfo;
- guint16 tlvcount = 0;
GSList *tlvlist;
- aim_tlv_t *tlv;
- char *roomdesc;
- guint16 flags;
- guint32 creationtime;
guint16 maxmsglen, maxvisiblemsglen;
- guint16 unknown_d2, unknown_d5;
aim_chat_readroominfo(bs, &roominfo);
@@ -178,139 +88,27 @@ infoupdate(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fr
return 1;
}
- tlvcount = byte_stream_get16(bs);
-
/*
* Everything else are TLVs.
*/
tlvlist = aim_tlvlist_read(bs);
/*
- * TLV type 0x006a is the room name in Human Readable Form.
- */
- roomname = aim_tlv_getstr(tlvlist, 0x006a, 1);
-
- /*
- * Type 0x006f: Number of occupants.
- */
- usercount = aim_tlv_get16(tlvlist, 0x006f, 1);
-
- /*
- * Type 0x0073: Occupant list.
- */
- tlv = aim_tlv_gettlv(tlvlist, 0x0073, 1);
- if (tlv != NULL)
- {
- int curoccupant = 0;
- ByteStream occbs;
-
- /* Allocate enough userinfo structs for all occupants */
- userinfo = g_new0(aim_userinfo_t, usercount);
-
- byte_stream_init(&occbs, tlv->value, tlv->length);
-
- while (curoccupant < usercount)
- aim_info_extract(od, &occbs, &userinfo[curoccupant++]);
- }
-
- /*
- * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG)
- */
- flags = aim_tlv_get16(tlvlist, 0x00c9, 1);
-
- /*
- * Type 0x00ca: Creation time (4 bytes)
- */
- creationtime = aim_tlv_get32(tlvlist, 0x00ca, 1);
-
- /*
* Type 0x00d1: Maximum Message Length
*/
maxmsglen = aim_tlv_get16(tlvlist, 0x00d1, 1);
/*
- * Type 0x00d2: Unknown. (2 bytes)
- */
- unknown_d2 = aim_tlv_get16(tlvlist, 0x00d2, 1);
-
- /*
- * Type 0x00d3: Room Description
- */
- roomdesc = aim_tlv_getstr(tlvlist, 0x00d3, 1);
-
-#if 0
- /*
- * Type 0x000d4: Unknown (flag only)
- */
- if (aim_tlv_gettlv(tlvlist, 0x000d4, 1)) {
- /* Unhandled */
- }
-#endif
-
- /*
- * Type 0x00d5: Unknown. (1 byte)
- */
- unknown_d5 = aim_tlv_get8(tlvlist, 0x00d5, 1);
-
-#if 0
- /*
- * Type 0x00d6: Encoding 1 ("us-ascii")
- */
- if (aim_tlv_gettlv(tlvlist, 0x000d6, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d7: Language 1 ("en")
- */
- if (aim_tlv_gettlv(tlvlist, 0x000d7, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d8: Encoding 2 ("us-ascii")
- */
- if (aim_tlv_gettlv(tlvlist, 0x000d8, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d9: Language 2 ("en")
- */
- if (aim_tlv_gettlv(tlvlist, 0x000d9, 1)) {
- /* Unhandled */
- }
-#endif
-
- /*
* Type 0x00da: Maximum visible message length
*/
maxvisiblemsglen = aim_tlv_get16(tlvlist, 0x00da, 1);
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) {
- ret = userfunc(od, conn,
- frame,
- &roominfo,
- roomname,
- usercount,
- userinfo,
- roomdesc,
- flags,
- creationtime,
- maxmsglen,
- unknown_d2,
- unknown_d5,
- maxvisiblemsglen);
+ ret = userfunc(od, conn, frame, maxmsglen, maxvisiblemsglen);
}
g_free(roominfo.name);
- while (usercount > 0)
- aim_info_free(&userinfo[--usercount]);
-
- g_free(userinfo);
- g_free(roomname);
- g_free(roomdesc);
aim_tlvlist_free(tlvlist);
return ret;
@@ -324,7 +122,7 @@ userlistchange(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame
aim_rxcallback_t userfunc;
int curcount = 0, ret = 0;
- while (byte_stream_empty(bs)) {
+ while (byte_stream_bytes_left(bs)) {
curcount++;
userinfo = g_realloc(userinfo, curcount * sizeof(aim_userinfo_t));
aim_info_extract(od, bs, &userinfo[curcount-1]);
@@ -434,7 +232,7 @@ aim_chat_send_im(OscarData *od, FlapConnection *conn, guint16 flags, const gchar
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_CHAT, 0x0005, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_CHAT, 0x0005, snacid, &bs);
byte_stream_destroy(&bs);
@@ -523,16 +321,6 @@ incomingim_ch3(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame
aim_info_extract(od, &tbs, &userinfo);
}
-#if 0
- /*
- * Type 0x0001: If present, it means it was a message to the
- * room (as opposed to a whisper).
- */
- if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) {
- /* Unhandled */
- }
-#endif
-
/*
* Type 0x0005: Message Block. Conains more TLVs.
*/
diff --git a/libpurple/protocols/oscar/family_chatnav.c b/libpurple/protocols/oscar/family_chatnav.c
index 6a57ef1417..6df24b2dde 100644
--- a/libpurple/protocols/oscar/family_chatnav.c
+++ b/libpurple/protocols/oscar/family_chatnav.c
@@ -139,7 +139,7 @@ int aim_chatnav_createroom(OscarData *od, FlapConnection *conn, const char *name
aim_tlvlist_free(tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_CHATNAV, 0x0008, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_CHATNAV, 0x0008, snacid, &bs);
byte_stream_destroy(&bs);
@@ -185,32 +185,6 @@ parseinfo_perms(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFram
exchanges[curexchange-1].number = byte_stream_get16(&tbs);
innerlist = aim_tlvlist_read(&tbs);
-#if 0
- /*
- * Type 0x000a: Unknown.
- *
- * Usually three bytes: 0x0114 (exchange 1) or 0x010f (others).
- *
- */
- if (aim_tlv_gettlv(innerlist, 0x000a, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x000d: Unknown.
- */
- if (aim_tlv_gettlv(innerlist, 0x000d, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x0004: Unknown
- */
- if (aim_tlv_gettlv(innerlist, 0x0004, 1)) {
- /* Unhandled */
- }
-#endif
-
/*
* Type 0x0002: Unknown
*/
@@ -234,36 +208,6 @@ parseinfo_perms(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFram
if (aim_tlv_gettlv(innerlist, 0x00c9, 1))
exchanges[curexchange-1].flags = aim_tlv_get16(innerlist, 0x00c9, 1);
-#if 0
- /*
- * Type 0x00ca: Creation Date
- */
- if (aim_tlv_gettlv(innerlist, 0x00ca, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d0: Mandatory Channels?
- */
- if (aim_tlv_gettlv(innerlist, 0x00d0, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d1: Maximum Message length
- */
- if (aim_tlv_gettlv(innerlist, 0x00d1, 1)) {
- /* Unhandled */
- }
-
- /*
- * Type 0x00d2: Maximum Occupancy?
- */
- if (aim_tlv_gettlv(innerlist, 0x00d2, 1)) {
- /* Unhandled */
- }
-#endif
-
/*
* Type 0x00d3: Exchange Description
*/
@@ -272,15 +216,6 @@ parseinfo_perms(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFram
else
exchanges[curexchange-1].name = NULL;
-#if 0
- /*
- * Type 0x00d4: Exchange Description URL
- */
- if (aim_tlv_gettlv(innerlist, 0x00d4, 1)) {
- /* Unhandled */
- }
-#endif
-
/*
* Type 0x00d5: Creation Permissions
*
@@ -327,15 +262,6 @@ parseinfo_perms(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFram
else
exchanges[curexchange-1].lang2 = NULL;
-#if 0
- /*
- * Type 0x00da: Unknown
- */
- if (aim_tlv_gettlv(innerlist, 0x00da, 1)) {
- /* Unhandled */
- }
-#endif
-
aim_tlvlist_free(innerlist);
}
diff --git a/libpurple/protocols/oscar/family_feedbag.c b/libpurple/protocols/oscar/family_feedbag.c
index 37e9518cd3..c685f51ec8 100644
--- a/libpurple/protocols/oscar/family_feedbag.c
+++ b/libpurple/protocols/oscar/family_feedbag.c
@@ -660,10 +660,8 @@ int aim_ssi_cleanlist(OscarData *od)
if (!cur->name) {
if (cur->type == AIM_SSI_TYPE_BUDDY)
aim_ssi_delbuddy(od, NULL, NULL);
- else if (cur->type == AIM_SSI_TYPE_PERMIT)
- aim_ssi_delpermit(od, NULL);
- else if (cur->type == AIM_SSI_TYPE_DENY)
- aim_ssi_deldeny(od, NULL);
+ else if (cur->type == AIM_SSI_TYPE_PERMIT || cur->type == AIM_SSI_TYPE_DENY || cur->type == AIM_SSI_TYPE_ICQDENY)
+ aim_ssi_del_from_private_list(od, NULL, cur->type);
} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) {
char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name);
aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE);
@@ -748,51 +746,31 @@ int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList
return aim_ssi_sync(od);
}
-/**
- * Add a permit buddy to the list.
- *
- * @param od The oscar odion.
- * @param name The name of the item..
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_ssi_addpermit(OscarData *od, const char *name)
+int
+aim_ssi_add_to_private_list(OscarData *od, const char* name, guint16 list_type)
{
-
if (!od || !name || !od->ssi.received_data)
return -EINVAL;
- /* Make sure the master group exists */
if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
- aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
-
- /* Add that bad boy */
- aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL);
+ aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, list_type, NULL);
- /* Sync our local list with the server list */
+ aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, list_type, NULL);
return aim_ssi_sync(od);
}
-/**
- * Add a deny buddy to the list.
- *
- * @param od The oscar odion.
- * @param name The name of the item..
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_ssi_adddeny(OscarData *od, const char *name)
+int
+aim_ssi_del_from_private_list(OscarData* od, const char* name, guint16 list_type)
{
+ struct aim_ssi_item *del;
- if (!od || !name || !od->ssi.received_data)
+ if (!od)
return -EINVAL;
- /* Make sure the master group exists */
- if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL)
- aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
-
- /* Add that bad boy */
- aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL);
+ if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, list_type)))
+ return -EINVAL;
- /* Sync our local list with the server list */
+ aim_ssi_itemlist_del(&od->ssi.local, del);
return aim_ssi_sync(od);
}
@@ -860,56 +838,6 @@ int aim_ssi_delgroup(OscarData *od, const char *group)
}
/**
- * Deletes a permit buddy from the list.
- *
- * @param od The oscar odion.
- * @param name The name of the item, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_ssi_delpermit(OscarData *od, const char *name)
-{
- struct aim_ssi_item *del;
-
- if (!od)
- return -EINVAL;
-
- /* Find the item */
- if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT)))
- return -EINVAL;
-
- /* Remove the item from the list */
- aim_ssi_itemlist_del(&od->ssi.local, del);
-
- /* Sync our local list with the server list */
- return aim_ssi_sync(od);
-}
-
-/**
- * Deletes a deny buddy from the list.
- *
- * @param od The oscar odion.
- * @param name The name of the item, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_ssi_deldeny(OscarData *od, const char *name)
-{
- struct aim_ssi_item *del;
-
- if (!od)
- return -EINVAL;
-
- /* Find the item */
- if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, AIM_SSI_TYPE_DENY)))
- return -EINVAL;
-
- /* Remove the item from the list */
- aim_ssi_itemlist_del(&od->ssi.local, del);
-
- /* Sync our local list with the server list */
- return aim_ssi_sync(od);
-}
-
-/**
* Move a buddy from one group to another group. This basically just deletes the
* buddy and re-adds it.
*
@@ -1030,17 +958,16 @@ int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn)
* Stores your permit/deny setting on the server, and starts using it.
*
* @param od The oscar odion.
- * @param permdeny Your permit/deny setting. Can be one of the following:
+ * @param permdeny Your permit/deny setting. For ICQ accounts, it actually affects your visibility
+ * and has nothing to do with blocking. Can be one of the following:
* 1 - Allow all users
* 2 - Block all users
* 3 - Allow only the users below
* 4 - Block only the users below
* 5 - Allow only users on my buddy list
- * @param vismask A bitmask of the class of users to whom you want to be
- * visible. See the AIM_FLAG_BLEH #defines in oscar.h
* @return Return 0 if no errors, otherwise return the error number.
*/
-int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask)
+int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny)
{
struct aim_ssi_item *tmp;
@@ -1059,9 +986,6 @@ int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask)
/* Need to add the 0x00ca TLV to the TLV chain */
aim_tlvlist_replace_8(&tmp->data, 0x00ca, permdeny);
- /* Need to add the 0x00cb TLV to the TLV chain */
- aim_tlvlist_replace_32(&tmp->data, 0x00cb, vismask);
-
/* Sync our local list with the server list */
return aim_ssi_sync(od);
}
@@ -1231,41 +1155,6 @@ int aim_ssi_reqdata(OscarData *od)
}
/*
- * Subtype 0x0005 - Request SSI Data when you have a timestamp and revision
- * number.
- *
- * The data will only be sent if it is newer than the posted local
- * timestamp and revision.
- *
- * Note that the client should never increment the revision, only the server.
- *
- */
-int aim_ssi_reqifchanged(OscarData *od, time_t timestamp, guint16 numitems)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)))
- return -EINVAL;
-
- 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);
-
- byte_stream_destroy(&bs);
-
- /* Free any current data, just in case */
- aim_ssi_freelist(od);
-
- return 0;
-}
-
-/*
* Subtype 0x0006 - SSI Data.
*/
static int parsedata(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -1281,7 +1170,7 @@ static int parsedata(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fla
od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */
/* Read in the list */
- while (byte_stream_empty(bs) > 4) { /* last four bytes are timestamp */
+ while (byte_stream_bytes_left(bs) > 4) { /* last four bytes are timestamp */
if ((namelen = byte_stream_get16(bs)))
name = byte_stream_getstr(bs, namelen);
else
@@ -1378,7 +1267,7 @@ static int aim_ssi_addmoddel(OscarData *od)
}
snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, snacid, &bs);
byte_stream_destroy(&bs);
@@ -1399,7 +1288,7 @@ static int parseadd(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
guint16 len, gid, bid, type;
GSList *data;
- while (byte_stream_empty(bs)) {
+ while (byte_stream_bytes_left(bs)) {
if ((len = byte_stream_get16(bs)))
name = byte_stream_getstr(bs, len);
else
@@ -1437,7 +1326,7 @@ static int parsemod(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
GSList *data;
struct aim_ssi_item *item;
- while (byte_stream_empty(bs)) {
+ while (byte_stream_bytes_left(bs)) {
if ((len = byte_stream_get16(bs)))
name = byte_stream_getstr(bs, len);
else
@@ -1489,7 +1378,7 @@ static int parsedel(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
guint16 gid, bid;
struct aim_ssi_item *del;
- while (byte_stream_empty(bs)) {
+ while (byte_stream_bytes_left(bs)) {
byte_stream_advance(bs, byte_stream_get16(bs));
gid = byte_stream_get16(bs);
bid = byte_stream_get16(bs);
@@ -1522,7 +1411,7 @@ static int parseack(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
/* Read in the success/failure flags from the ack SNAC */
cur = od->ssi.pending;
- while (cur && (byte_stream_empty(bs)>0)) {
+ while (cur && (byte_stream_bytes_left(bs)>0)) {
cur->ack = byte_stream_get16(bs);
cur = cur->next;
}
@@ -1678,45 +1567,6 @@ int aim_ssi_modend(OscarData *od)
}
/*
- * Subtype 0x0014 - Grant authorization
- *
- * Authorizes a contact so they can add you to their contact list.
- *
- */
-int aim_ssi_sendauth(OscarData *od, char *bn, char *msg)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !bn)
- return -EINVAL;
-
- byte_stream_new(&bs, 1+strlen(bn) + 2+(msg ? strlen(msg)+1 : 0) + 2);
-
- /* Username */
- byte_stream_put8(&bs, strlen(bn));
- byte_stream_putstr(&bs, bn);
-
- /* Message (null terminated) */
- byte_stream_put16(&bs, msg ? strlen(msg) : 0);
- if (msg) {
- byte_stream_putstr(&bs, msg);
- byte_stream_put8(&bs, 0x00);
- }
-
- /* Unknown */
- byte_stream_put16(&bs, 0x0000);
-
- 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;
-}
-
-/*
* Subtype 0x0015 - Receive an authorization grant
*/
static int receiveauthgrant(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -1783,7 +1633,7 @@ int aim_ssi_sendauthrequest(OscarData *od, char *bn, const char *msg)
byte_stream_put16(&bs, 0x0000);
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);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREQ, snacid, &bs);
byte_stream_destroy(&bs);
@@ -1863,7 +1713,7 @@ int aim_ssi_sendauthreply(OscarData *od, char *bn, guint8 reply, const char *msg
byte_stream_put16(&bs, 0x0000);
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);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_SENDAUTHREP, snacid, &bs);
byte_stream_destroy(&bs);
@@ -1935,6 +1785,16 @@ static int receiveadded(OscarData *od, FlapConnection *conn, aim_module_t *mod,
return ret;
}
+/*
+ * If we're on ICQ, then AIM_SSI_TYPE_DENY is used for the "permanently invisible" list.
+ * AIM_SSI_TYPE_ICQDENY is used for blocking users instead.
+ */
+guint16
+aim_ssi_getdenyentrytype(OscarData* od)
+{
+ return od->icq ? AIM_SSI_TYPE_ICQDENY : AIM_SSI_TYPE_DENY;
+}
+
static int
snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
diff --git a/libpurple/protocols/oscar/family_icbm.c b/libpurple/protocols/oscar/family_icbm.c
index 2f2adb4899..73a3aa7862 100644
--- a/libpurple/protocols/oscar/family_icbm.c
+++ b/libpurple/protocols/oscar/family_icbm.c
@@ -44,6 +44,7 @@
* Make sure flap_connection_findbygroup is used by all functions.
*/
+#include "encoding.h"
#include "oscar.h"
#include "peer.h"
@@ -108,69 +109,6 @@ void aim_icbm_makecookie(guchar *cookie)
}
/*
- * Takes a msghdr (and a length) and returns a client type
- * code. Note that this is *only a guess* and has a low likelihood
- * of actually being accurate.
- *
- * Its based on experimental data, with the help of Eric Warmenhoven
- * who seems to have collected a wide variety of different AIM clients.
- *
- *
- * Heres the current collection:
- * 0501 0003 0101 0101 01 AOL Mobile Communicator, WinAIM 1.0.414
- * 0501 0003 0101 0201 01 WinAIM 2.0.847, 2.1.1187, 3.0.1464,
- * 4.3.2229, 4.4.2286
- * 0501 0004 0101 0102 0101 WinAIM 4.1.2010, libfaim (right here)
- * 0501 0003 0101 02 WinAIM 5
- * 0501 0001 01 iChat x.x, mobile buddies
- * 0501 0001 0101 01 AOL v6.0, CompuServe 2000 v6.0, any TOC client
- * 0501 0002 0106 WinICQ 5.45.1.3777.85
- *
- * Note that in this function, only the feature bytes are tested, since
- * the rest will always be the same.
- *
- */
-guint16 aim_im_fingerprint(const guint8 *msghdr, int len)
-{
- static const struct {
- guint16 clientid;
- int len;
- guint8 data[10];
- } fingerprints[] = {
- /* AOL Mobile Communicator, WinAIM 1.0.414 */
- { AIM_CLIENTTYPE_MC,
- 3, {0x01, 0x01, 0x01}},
-
- /* WinAIM 2.0.847, 2.1.1187, 3.0.1464, 4.3.2229, 4.4.2286 */
- { AIM_CLIENTTYPE_WINAIM,
- 3, {0x01, 0x01, 0x02}},
-
- /* WinAIM 4.1.2010, libfaim */
- { AIM_CLIENTTYPE_WINAIM41,
- 4, {0x01, 0x01, 0x01, 0x02}},
-
- /* AOL v6.0, CompuServe 2000 v6.0, any TOC client */
- { AIM_CLIENTTYPE_AOL_TOC,
- 1, {0x01}},
-
- { 0, 0, {0x00}}
- };
- int i;
-
- if (!msghdr || (len <= 0))
- return AIM_CLIENTTYPE_UNKNOWN;
-
- for (i = 0; fingerprints[i].len; i++) {
- if (fingerprints[i].len != len)
- continue;
- if (memcmp(fingerprints[i].data, msghdr, fingerprints[i].len) == 0)
- return fingerprints[i].clientid;
- }
-
- return AIM_CLIENTTYPE_UNKNOWN;
-}
-
-/*
* Subtype 0x0001 - Error
*/
static int
@@ -287,7 +225,7 @@ int aim_im_setparams(OscarData *od, struct aim_icbmparameters *params)
byte_stream_put32(&bs, params->minmsginterval);
snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
@@ -345,40 +283,14 @@ static int aim_im_paraminfo(OscarData *od, FlapConnection *conn, aim_module_t *m
*
* Possible flags:
* AIM_IMFLAGS_AWAY -- Marks the message as an autoresponse
- * AIM_IMFLAGS_ACK -- Requests that the server send an ack
- * when the message is received (of type SNAC_FAMILY_ICBM/0x000c)
* AIM_IMFLAGS_OFFLINE--If destination is offline, store it until they are
* online (probably ICQ only).
*
- * Generally, you should use the lowest encoding possible to send
- * your message. If you only use basic punctuation and the generic
- * Latin alphabet, use ASCII7 (no flags). If you happen to use non-ASCII7
- * characters, but they are all clearly defined in ISO-8859-1, then
- * use that. Keep in mind that not all characters in the PC ASCII8
- * character set are defined in the ISO standard. For those cases (most
- * notably when the (r) symbol is used), you must use the full UNICODE
- * encoding for your message. In UNICODE mode, _all_ characters must
- * occupy 16bits, including ones that are not special. (Remember that
- * the first 128 UNICODE symbols are equivalent to ASCII7, however they
- * must be prefixed with a zero high order byte.)
- *
- * I strongly discourage the use of UNICODE mode, mainly because none
- * of the clients I use can parse those messages (and besides that,
- * wchars are difficult and non-portable to handle in most UNIX environments).
- * If you really need to include special characters, use the HTML UNICODE
- * entities. These are of the form &#2026; where 2026 is the hex
- * representation of the UNICODE index (in this case, UNICODE
- * "Horizontal Ellipsis", or 133 in in ASCII8).
- *
* Implementation note: Since this is one of the most-used functions
* in all of libfaim, it is written with performance in mind. As such,
* it is not as clear as it could be in respect to how this message is
* supposed to be layed out. Most obviously, tlvlists should be used
* instead of writing out the bytes manually.
- *
- * XXX - more precise verification that we never send SNACs larger than 8192
- * XXX - check SNAC size for multipart
- *
*/
int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
{
@@ -387,7 +299,6 @@ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
ByteStream data;
guchar cookie[8];
int msgtlvlen;
- static const guint8 deffeatures[] = { 0x01, 0x01, 0x01, 0x02 };
if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
return -EINVAL;
@@ -395,37 +306,17 @@ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
if (!args)
return -EINVAL;
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- if (args->mpmsg->numparts == 0)
- return -EINVAL;
- } else {
- if (!args->msg || (args->msglen <= 0))
- return -EINVAL;
+ if (!args->msg || (args->msglen <= 0))
+ return -EINVAL;
- if (args->msglen > MAXMSGLEN)
- return -E2BIG;
- }
+ if (args->msglen > MAXMSGLEN)
+ return -E2BIG;
/* Painfully calculate the size of the message TLV */
msgtlvlen = 1 + 1; /* 0501 */
-
- if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES)
- msgtlvlen += 2 + args->featureslen;
- else
- msgtlvlen += 2 + sizeof(deffeatures);
-
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- aim_mpmsg_section_t *sec;
-
- for (sec = args->mpmsg->parts; sec; sec = sec->next) {
- msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
- msgtlvlen += 4 /* charset */ + sec->datalen;
- }
-
- } else {
- msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
- msgtlvlen += 4 /* charset */ + args->msglen;
- }
+ msgtlvlen += 2 + args->featureslen;
+ msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
+ msgtlvlen += 4 /* charset */ + args->msglen;
byte_stream_new(&data, msgtlvlen + 128);
@@ -441,52 +332,31 @@ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
/* Features TLV (type 0x0501) */
byte_stream_put16(&data, 0x0501);
- if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) {
- byte_stream_put16(&data, args->featureslen);
- byte_stream_putraw(&data, args->features, args->featureslen);
- } else {
- byte_stream_put16(&data, sizeof(deffeatures));
- byte_stream_putraw(&data, deffeatures, sizeof(deffeatures));
- }
-
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- aim_mpmsg_section_t *sec;
+ byte_stream_put16(&data, args->featureslen);
+ byte_stream_putraw(&data, args->features, args->featureslen);
- /* Insert each message part in a TLV (type 0x0101) */
- for (sec = args->mpmsg->parts; sec; sec = sec->next) {
- byte_stream_put16(&data, 0x0101);
- byte_stream_put16(&data, sec->datalen + 4);
- byte_stream_put16(&data, sec->charset);
- byte_stream_put16(&data, sec->charsubset);
- byte_stream_putraw(&data, (guchar *)sec->data, sec->datalen);
- }
-
- } else {
+ /* Insert message text in a TLV (type 0x0101) */
+ byte_stream_put16(&data, 0x0101);
- /* Insert message text in a TLV (type 0x0101) */
- byte_stream_put16(&data, 0x0101);
+ /* Message block length */
+ byte_stream_put16(&data, args->msglen + 0x04);
- /* Message block length */
- byte_stream_put16(&data, args->msglen + 0x04);
+ /* Character set */
+ byte_stream_put16(&data, args->charset);
+ /* Character subset -- we always use 0 here */
+ byte_stream_put16(&data, 0x0);
- /* Character set */
- byte_stream_put16(&data, args->charset);
- byte_stream_put16(&data, args->charsubset);
-
- /* Message. Not terminated */
- byte_stream_putraw(&data, (guchar *)args->msg, args->msglen);
- }
+ /* Message. Not terminated */
+ byte_stream_putraw(&data, (guchar *)args->msg, args->msglen);
/* Set the Autoresponse flag */
if (args->flags & AIM_IMFLAGS_AWAY) {
byte_stream_put16(&data, 0x0004);
byte_stream_put16(&data, 0x0000);
} else {
- if (args->flags & AIM_IMFLAGS_ACK) {
- /* Set the Request Acknowledge flag */
- byte_stream_put16(&data, 0x0003);
- byte_stream_put16(&data, 0x0000);
- }
+ /* Set the Request Acknowledge flag */
+ byte_stream_put16(&data, 0x0003);
+ byte_stream_put16(&data, 0x0000);
if (args->flags & AIM_IMFLAGS_OFFLINE) {
/* Allow this message to be queued as an offline message */
@@ -521,7 +391,7 @@ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
/* XXX - should be optional */
snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, args->destbn, strlen(args->destbn)+1);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &data);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &data);
byte_stream_destroy(&data);
/* clean out SNACs over 60sec old */
@@ -531,33 +401,6 @@ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
}
/*
- * Simple wrapper for aim_im_sendch1_ext()
- *
- * You cannot use aim_send_im if you need the HASICON flag. You must
- * use aim_im_sendch1_ext directly for that.
- *
- * aim_send_im also cannot be used if you require UNICODE messages, because
- * that requires an explicit message length. Use aim_im_sendch1_ext().
- *
- */
-int aim_im_sendch1(OscarData *od, const char *bn, guint16 flags, const char *msg)
-{
- struct aim_sendimext_args args;
-
- args.destbn = bn;
- args.flags = flags;
- args.msg = msg;
- args.msglen = strlen(msg);
- args.charset = 0x0000;
- args.charsubset = 0x0000;
-
- /* Make these don't get set by accident -- they need aim_im_sendch1_ext */
- args.flags &= ~(AIM_IMFLAGS_CUSTOMFEATURES | AIM_IMFLAGS_HASICON | AIM_IMFLAGS_MULTIPART);
-
- return aim_im_sendch1_ext(od, &args);
-}
-
-/*
* Subtype 0x0006 - Send a chat invitation.
*/
int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, guint16 exchange, const char *roomname, guint16 instance)
@@ -628,7 +471,7 @@ int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, gu
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
@@ -698,100 +541,7 @@ int aim_im_sendch2_icon(OscarData *od, const char *bn, const guint8 *icon, int i
byte_stream_put16(&bs, 0x0003);
byte_stream_put16(&bs, 0x0000);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
- * Subtype 0x0006 - Send a rich text message.
- *
- * This only works for ICQ 2001b (thats 2001 not 2000). Better, only
- * send it to clients advertising the RTF capability. In fact, if you send
- * it to a client that doesn't support that capability, the server will gladly
- * bounce it back to you.
- *
- * You'd think this would be in icq.c, but, well, I'm trying to stick with
- * the one-group-per-file scheme as much as possible. This could easily
- * be an exception, since Rendezvous IMs are external of the Oscar core,
- * and therefore are undefined. Really I just need to think of a good way to
- * make an interface similar to what AOL actually uses. But I'm not using COM.
- *
- */
-int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- guchar cookie[8];
- const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* OSCAR_CAPABILITY_ICQRTF capability in string form */
- int servdatalen;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
- return -EINVAL;
-
- if (!args || !args->destbn || !args->rtfmsg)
- return -EINVAL;
-
- servdatalen = 2+2+16+2+4+1+2 + 2+2+4+4+4 + 2+4+2+strlen(args->rtfmsg)+1 + 4+4+4+strlen(rtfcap)+1;
-
- aim_icbm_makecookie(cookie);
-
- byte_stream_new(&bs, 128+servdatalen);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
-
- /* ICBM header */
- aim_im_puticbm(&bs, cookie, 0x0002, args->destbn);
-
- /* TLV t(0005) - Encompasses everything below. */
- 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(&bs, 0x000a);
- byte_stream_put16(&bs, 0x0002);
- byte_stream_put16(&bs, 0x0001);
-
- /* t(000f) l(0000) v() */
- byte_stream_put16(&bs, 0x000f);
- byte_stream_put16(&bs, 0x0000);
-
- /* Service Data TLV */
- 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, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
@@ -844,7 +594,7 @@ aim_im_sendch2_cancel(PeerConnection *peer_conn)
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -879,7 +629,7 @@ aim_im_sendch2_connected(PeerConnection *peer_conn)
byte_stream_putraw(&bs, peer_conn->cookie, 8);
byte_stream_putcaps(&bs, peer_conn->type);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -934,7 +684,7 @@ aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *bn,
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -997,7 +747,7 @@ aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *bn, c
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -1044,17 +794,6 @@ aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char
aim_tlvlist_add_noval(&inner_tlvlist, 0x000f);
/* TODO: Send 0x0016 and 0x0017 */
-#if 0
- /* TODO: If the following is ever enabled, ensure that it is
- * not sent with a receive redirect or stage 3 proxy
- * redirect for a file receive (same conditions for
- * sending 0x000f above)
- */
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en");
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii");
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file.");
-#endif
-
if (filename != NULL)
{
ByteStream inner_bs;
@@ -1083,7 +822,7 @@ aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -1136,17 +875,6 @@ aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *
aim_tlvlist_add_raw(&inner_tlvlist, 0x0016, 4, ip_comp);
aim_tlvlist_add_16(&inner_tlvlist, 0x0017, ~pin);
-#if 0
- /* TODO: If the following is ever enabled, ensure that it is
- * not sent with a receive redirect or stage 3 proxy
- * redirect for a file receive (same conditions for
- * sending 0x000f above)
- */
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en");
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii");
- aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file.");
-#endif
-
if (filename != NULL)
{
ByteStream filename_bs;
@@ -1176,530 +904,57 @@ aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *
aim_tlvlist_free(inner_tlvlist);
aim_tlvlist_free(outer_tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-}
-
-/**
- * Subtype 0x0006 - Request the status message of the given ICQ user.
- *
- * @param od The oscar session.
- * @param bn The UIN of the user of whom you wish to request info.
- * @param type The type of info you wish to request. This should be the current
- * state of the user, as one of the AIM_ICQ_STATE_* defines.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_im_sendch2_geticqaway(OscarData *od, const char *bn, int type)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- guchar cookie[8];
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)) || !bn)
- return -EINVAL;
-
- aim_icbm_makecookie(cookie);
-
- byte_stream_new(&bs, 8+2+1+strlen(bn) + 4+0x5e + 4);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
-
- /* ICBM header */
- aim_im_puticbm(&bs, cookie, 0x0002, bn);
-
- /* TLV t(0005) - Encompasses almost everything below. */
- byte_stream_put16(&bs, 0x0005); /* T */
- byte_stream_put16(&bs, 0x005e); /* L */
- { /* V */
- byte_stream_put16(&bs, 0x0000);
-
- /* Cookie */
- byte_stream_putraw(&bs, cookie, 8);
-
- /* Put the 16 byte server relay capability */
- byte_stream_putcaps(&bs, OSCAR_CAPABILITY_ICQSERVERRELAY);
-
- /* TLV t(000a) */
- byte_stream_put16(&bs, 0x000a);
- byte_stream_put16(&bs, 0x0002);
- byte_stream_put16(&bs, 0x0001);
-
- /* TLV t(000f) */
- byte_stream_put16(&bs, 0x000f);
- byte_stream_put16(&bs, 0x0000);
-
- /* TLV t(2711) */
- byte_stream_put16(&bs, 0x2711);
- byte_stream_put16(&bs, 0x0036);
- { /* V */
- 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(&bs, 0x03ec);
- else if(type & AIM_ICQ_STATE_DND)
- byte_stream_putle16(&bs, 0x03eb);
- else if(type & AIM_ICQ_STATE_OUT)
- byte_stream_putle16(&bs, 0x03ea);
- else if(type & AIM_ICQ_STATE_BUSY)
- byte_stream_putle16(&bs, 0x03e9);
- else if(type & AIM_ICQ_STATE_AWAY)
- 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(&bs, 0x0003);
- byte_stream_put16(&bs, 0x0000);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an ICQ-esque ICBM.
- *
- * This can be used to send an ICQ authorization reply (deny or grant). It is the "old way."
- * The new way is to use SSI. I like the new way a lot better. This seems like such a hack,
- * mostly because it's in network byte order. Figuring this stuff out sometimes takes a while,
- * but thats ok, because it gives me time to try to figure out what kind of drugs the AOL people
- * were taking when they merged the two protocols.
- *
- * @param bn The destination buddy name.
- * @param type The type of message. 0x0007 for authorization denied. 0x0008 for authorization granted.
- * @param message The message you want to send, it should be null terminated.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_im_sendch4(OscarData *od, const char *bn, guint16 type, const char *message)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- guchar cookie[8];
-
- if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))
- return -EINVAL;
-
- if (!bn || !type || !message)
- return -EINVAL;
-
- byte_stream_new(&bs, 8+3+strlen(bn)+12+strlen(message)+1+4);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0);
-
- aim_icbm_makecookie(cookie);
-
- /* ICBM header */
- aim_im_puticbm(&bs, cookie, 0x0004, bn);
-
- /*
- * TLV t(0005)
- *
- * ICQ data (the UIN and the message).
- */
- byte_stream_put16(&bs, 0x0005);
- byte_stream_put16(&bs, 4 + 2+2+strlen(message)+1);
-
- /*
- * Your UIN
- */
- byte_stream_putuid(&bs, od);
-
- /*
- * TLV t(type) l(strlen(message)+1) v(message+NULL)
- */
- 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(&bs, 0x0006);
- byte_stream_put16(&bs, 0x0000);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, snacid, &bs);
byte_stream_destroy(&bs);
-
- return 0;
}
-/*
- * XXX - I don't see when this would ever get called...
- */
-static int outgoingim(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
-{
- int ret = 0;
- aim_rxcallback_t userfunc;
- guchar cookie[8];
- guint16 channel;
- GSList *tlvlist;
- char *bn;
- int bnlen;
- guint16 icbmflags = 0;
- guint8 flag1 = 0, flag2 = 0;
- gchar *msg = NULL;
- aim_tlv_t *msgblock;
-
- /* ICBM Cookie. */
- aim_icbm_makecookie(cookie);
-
- /* Channel ID */
- channel = byte_stream_get16(bs);
-
- if (channel != 0x01) {
- purple_debug_misc("oscar", "icbm: ICBM received on unsupported channel. Ignoring. (chan = %04x)\n", channel);
- return 0;
- }
-
- bnlen = byte_stream_get8(bs);
- bn = byte_stream_getstr(bs, bnlen);
-
- tlvlist = aim_tlvlist_read(bs);
-
- if (aim_tlv_gettlv(tlvlist, 0x0003, 1))
- icbmflags |= AIM_IMFLAGS_ACK;
- if (aim_tlv_gettlv(tlvlist, 0x0004, 1))
- icbmflags |= AIM_IMFLAGS_AWAY;
-
- if ((msgblock = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
- ByteStream mbs;
- int featurelen, msglen;
-
- byte_stream_init(&mbs, msgblock->value, msgblock->length);
-
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
- for (featurelen = byte_stream_get16(&mbs); featurelen; featurelen--)
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
-
- msglen = byte_stream_get16(&mbs) - 4; /* final block length */
-
- flag1 = byte_stream_get16(&mbs);
- flag2 = byte_stream_get16(&mbs);
-
- msg = byte_stream_getstr(&mbs, msglen);
- }
-
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, channel, bn, msg, icbmflags, flag1, flag2);
-
- g_free(bn);
- g_free(msg);
- aim_tlvlist_free(tlvlist);
-
- return ret;
-}
-
-/*
- * Ahh, the joys of nearly ridiculous over-engineering.
- *
- * Not only do AIM ICBM's support multiple channels. Not only do they
- * support multiple character sets. But they support multiple character
- * sets / encodings within the same ICBM.
- *
- * These multipart messages allow for complex space savings techniques, which
- * seem utterly unnecessary by today's standards. In fact, there is only
- * one client still in popular use that still uses this method: AOL for the
- * Macintosh, Version 5.0. Obscure, yes, I know.
- *
- * In modern (non-"legacy") clients, if the user tries to send a character
- * that is not ISO-8859-1 or ASCII, the client will send the entire message
- * as UNICODE, meaning that every character in the message will occupy the
- * full 16 bit UNICODE field, even if the high order byte would be zero.
- * Multipart messages prevent this wasted space by allowing the client to
- * only send the characters in UNICODE that need to be sent that way, and
- * the rest of the message can be sent in whatever the native character
- * set is (probably ASCII).
- *
- * An important note is that sections will be displayed in the order that
- * they appear in the ICBM. There is no facility for merging or rearranging
- * sections at run time. So if you have, say, ASCII then UNICODE then ASCII,
- * you must supply two ASCII sections with a UNICODE in the middle, and incur
- * the associated overhead.
- *
- * Normally I would have laughed and given a firm 'no' to supporting this
- * seldom-used feature, but something is attracting me to it. In the future,
- * it may be possible to abuse this to send mixed-media messages to other
- * open source clients (like encryption or something) -- see faimtest for
- * examples of how to do this.
- *
- * I would definitely recommend avoiding this feature unless you really
- * know what you are doing, and/or you have something neat to do with it.
- *
- */
-int aim_mpmsg_init(OscarData *od, aim_mpmsg_t *mpm)
-{
-
- memset(mpm, 0, sizeof(aim_mpmsg_t));
-
- return 0;
-}
-
-static int mpmsg_addsection(OscarData *od, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, gchar *data, guint16 datalen)
-{
- aim_mpmsg_section_t *sec;
-
- sec = g_malloc(sizeof(aim_mpmsg_section_t));
-
- sec->charset = charset;
- sec->charsubset = charsubset;
- sec->data = data;
- sec->datalen = datalen;
- sec->next = NULL;
-
- if (!mpm->parts)
- mpm->parts = sec;
- else {
- aim_mpmsg_section_t *cur;
-
- for (cur = mpm->parts; cur->next; cur = cur->next)
- ;
- cur->next = sec;
- }
-
- mpm->numparts++;
-
- return 0;
-}
-
-int aim_mpmsg_addraw(OscarData *od, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, const gchar *data, guint16 datalen)
-{
- gchar *dup;
-
- dup = g_malloc(datalen);
- memcpy(dup, data, datalen);
-
- if (mpmsg_addsection(od, mpm, charset, charsubset, dup, datalen) == -1) {
- g_free(dup);
- return -1;
- }
-
- return 0;
-}
-
-/* XXX - should provide a way of saying ISO-8859-1 specifically */
-int aim_mpmsg_addascii(OscarData *od, aim_mpmsg_t *mpm, const char *ascii)
-{
- gchar *dup;
-
- if (!(dup = g_strdup(ascii)))
- return -1;
-
- if (mpmsg_addsection(od, mpm, 0x0000, 0x0000, dup, strlen(ascii)) == -1) {
- g_free(dup);
- return -1;
- }
-
- return 0;
-}
-
-int aim_mpmsg_addunicode(OscarData *od, aim_mpmsg_t *mpm, const guint16 *unicode, guint16 unicodelen)
-{
- gchar *buf;
- ByteStream bs;
- int i;
-
- buf = g_malloc(unicodelen * 2);
-
- byte_stream_init(&bs, (guchar *)buf, unicodelen * 2);
-
- /* We assume unicode is in /host/ byte order -- convert to network */
- for (i = 0; i < unicodelen; i++)
- byte_stream_put16(&bs, unicode[i]);
-
- if (mpmsg_addsection(od, mpm, 0x0002, 0x0000, buf, byte_stream_curpos(&bs)) == -1) {
- g_free(buf);
- return -1;
- }
-
- return 0;
-}
-
-void aim_mpmsg_free(OscarData *od, aim_mpmsg_t *mpm)
-{
- aim_mpmsg_section_t *cur;
-
- for (cur = mpm->parts; cur; ) {
- aim_mpmsg_section_t *tmp;
-
- tmp = cur->next;
- g_free(cur->data);
- g_free(cur);
- cur = tmp;
- }
-
- mpm->numparts = 0;
- mpm->parts = NULL;
-
- return;
-}
-
-/*
- * Start by building the multipart structures, then pick the first
- * human-readable section and stuff it into args->msg so no one gets
- * suspicious.
- */
-static int incomingim_ch1_parsemsgs(OscarData *od, aim_userinfo_t *userinfo, guint8 *data, int len, struct aim_incomingim_ch1_args *args)
+static void
+incomingim_ch1_parsemsg(OscarData *od, aim_userinfo_t *userinfo, ByteStream *message, struct aim_incomingim_ch1_args *args)
{
- /* Should this be ASCII -> UNICODE -> Custom */
- static const guint16 charsetpri[] = {
- AIM_CHARSET_ASCII, /* ASCII first */
- AIM_CHARSET_LATIN_1, /* then ISO-8859-1 */
- AIM_CHARSET_UNICODE, /* UNICODE as last resort */
- };
- static const int charsetpricount = 3;
- int i;
- ByteStream mbs;
- aim_mpmsg_section_t *sec;
-
- byte_stream_init(&mbs, data, len);
-
- while (byte_stream_empty(&mbs)) {
- guint16 msglen, flag1, flag2;
- gchar *msgbuf;
-
- byte_stream_get8(&mbs); /* 01 */
- byte_stream_get8(&mbs); /* 01 */
-
- /* Message string length, including character set info. */
- msglen = byte_stream_get16(&mbs);
- if (msglen > byte_stream_empty(&mbs))
- {
- purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
- break;
- }
-
- /* Character set info */
- flag1 = byte_stream_get16(&mbs);
- flag2 = byte_stream_get16(&mbs);
-
- /* Message. */
- msglen -= 4;
-
- /*
- * For now, we don't care what the encoding is. Just copy
- * it into a multipart struct and deal with it later. However,
- * always pad the ending with a NULL. This makes it easier
- * to treat ASCII sections as strings. It won't matter for
- * UNICODE or binary data, as you should never read past
- * the specified data length, which will not include the pad.
- *
- * XXX - There's an API bug here. For sending, the UNICODE is
- * given in host byte order (aim_mpmsg_addunicode), but here
- * the received messages are given in network byte order.
- *
- */
- msgbuf = (gchar *)byte_stream_getraw(&mbs, msglen);
- mpmsg_addsection(od, &args->mpmsg, flag1, flag2, msgbuf, msglen);
-
- } /* while */
-
- args->icbmflags |= AIM_IMFLAGS_MULTIPART; /* always set */
-
+ PurpleAccount *account = purple_connection_get_account(od->gc);
/*
- * Clients that support multiparts should never use args->msg, as it
- * will point to an arbitrary section.
- *
- * Here, we attempt to provide clients that do not support multipart
- * messages with something to look at -- hopefully a human-readable
- * string. But, failing that, a UNICODE message, or nothing at all.
- *
- * Which means that even if args->msg is NULL, it does not mean the
- * message was blank.
- *
+ * We're interested in the inner TLV 0x101, which contains precious, precious message.
*/
- for (i = 0; i < charsetpricount; i++) {
- for (sec = args->mpmsg.parts; sec; sec = sec->next) {
-
- if (sec->charset != charsetpri[i])
- continue;
-
- /* Great. We found one. Fill it in. */
- args->charset = sec->charset;
- args->charsubset = sec->charsubset;
-
- /* Set up the simple flags */
- switch (args->charsubset)
- {
- case 0x0000:
- /* standard subencoding? */
- break;
- case 0x000b:
- args->icbmflags |= AIM_IMFLAGS_SUBENC_MACINTOSH;
- break;
- case 0xffff:
- /* no subencoding */
- break;
- default:
- break;
- }
-
- args->msg = sec->data;
- args->msglen = sec->datalen;
-
- return 0;
+ while (byte_stream_bytes_left(message) >= 4) {
+ guint16 type = byte_stream_get16(message);
+ guint16 length = byte_stream_get16(message);
+ if (type == 0x101) {
+ gchar *msg;
+ guint16 msglen = length - 4; /* charset + charsubset */
+ guint16 charset = byte_stream_get16(message);
+ byte_stream_advance(message, 2); /* charsubset */
+
+ msg = byte_stream_getstr(message, msglen);
+ args->msg = oscar_decode_im(account, userinfo->bn, charset, msg, msglen);
+ } else {
+ byte_stream_advance(message, length);
}
}
-
- /* No human-readable sections found. Oh well. */
- args->charset = args->charsubset = 0xffff;
- args->msg = NULL;
- args->msglen = 0;
-
- return 0;
}
-static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, ByteStream *bs, guint8 *cookie)
+static int
+incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, guint16 channel, aim_userinfo_t *userinfo, ByteStream *bs, guint8 *cookie)
{
- guint16 type, length, magic1, msglen = 0;
+ guint16 type, length;
aim_rxcallback_t userfunc;
int ret = 0;
- int rev = 0;
struct aim_incomingim_ch1_args args;
unsigned int endpos;
memset(&args, 0, sizeof(args));
- aim_mpmsg_init(od, &args.mpmsg);
-
/*
* This used to be done using tlvchains. For performance reasons,
* I've changed it to process the TLVs in-place. This avoids lots
* of per-IM memory allocations.
*/
- while (byte_stream_empty(bs) >= 4)
+ while (byte_stream_bytes_left(bs) >= 4)
{
type = byte_stream_get16(bs);
length = byte_stream_get16(bs);
- if (length > byte_stream_empty(bs))
+ if (length > byte_stream_bytes_left(bs))
{
purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
break;
@@ -1708,93 +963,20 @@ static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod
endpos = byte_stream_curpos(bs) + length;
if (type == 0x0002) { /* Message Block */
-
- /*
- * This TLV consists of the following:
- * - 0501 -- Unknown
- * - Features: Don't know how to interpret these
- * - 0101 -- Unknown
- * - Message
- *
- * Slick and possible others reverse 'Features' and 'Messages' section.
- * Thus, the TLV could have following layout:
- * - 0101 -- Unknown (possibly magic for message section)
- * - Message
- * - 0501 -- Unknown (possibly magic for features section)
- * - Features: Don't know how to interpret these
- */
-
- magic1 = byte_stream_get16(bs); /* 0501 or 0101 */
- if (magic1 == 0x101) /* Bad, message comes before attributes */
- {
- /* Jump to the features section */
- msglen = byte_stream_get16(bs);
- bs->offset += msglen;
- rev = 1;
-
- magic1 = byte_stream_get16(bs); /* 0501 */
- }
-
- if (magic1 != 0x501)
- {
- purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
- break;
- }
-
- args.featureslen = byte_stream_get16(bs);
- if (args.featureslen > byte_stream_empty(bs))
- {
- purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
- break;
- }
- if (args.featureslen == 0)
- {
- args.features = NULL;
- }
- else
- {
- args.features = byte_stream_getraw(bs, args.featureslen);
- args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES;
- }
-
- if (rev)
- {
- /* Fix buffer back to message */
- bs->offset -= args.featureslen + 2 + 2 + msglen + 2 + 2;
- }
-
- magic1 = byte_stream_get16(bs); /* 01 01 */
- if (magic1 != 0x101) /* Bad, message comes before attributes */
- {
- purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
- break;
- }
- msglen = byte_stream_get16(bs);
-
- /*
- * The rest of the TLV contains one or more message
- * blocks...
- */
- incomingim_ch1_parsemsgs(od, userinfo, bs->data + bs->offset - 2 - 2 /* XXX evil!!! */, msglen + 2 + 2, &args);
-
+ ByteStream tlv02;
+ byte_stream_init(&tlv02, bs->data + bs->offset, length);
+ incomingim_ch1_parsemsg(od, userinfo, &tlv02, &args);
} else if (type == 0x0003) { /* Server Ack Requested */
-
args.icbmflags |= AIM_IMFLAGS_ACK;
-
} else if (type == 0x0004) { /* Message is Auto Response */
-
args.icbmflags |= AIM_IMFLAGS_AWAY;
-
} else if (type == 0x0006) { /* Message was received offline. */
-
/*
* This flag is set on incoming offline messages for both
* AIM and ICQ accounts.
*/
args.icbmflags |= AIM_IMFLAGS_OFFLINE;
-
} else if (type == 0x0008) { /* I-HAVE-A-REALLY-PURTY-ICON Flag */
-
args.iconlen = byte_stream_get32(bs);
byte_stream_get16(bs); /* 0x0001 */
args.iconsum = byte_stream_get16(bs);
@@ -1812,39 +994,16 @@ static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod
*/
if (args.iconlen)
args.icbmflags |= AIM_IMFLAGS_HASICON;
-
} else if (type == 0x0009) {
-
args.icbmflags |= AIM_IMFLAGS_BUDDYREQ;
-
} else if (type == 0x000b) { /* Non-direct connect typing notification */
-
args.icbmflags |= AIM_IMFLAGS_TYPINGNOT;
-
} else if (type == 0x0016) {
-
/*
* UTC timestamp for when the message was sent. Only
* provided for offline messages.
*/
args.timestamp = byte_stream_get32(bs);
-
- } else if (type == 0x0017) {
-
- if (length > byte_stream_empty(bs))
- {
- purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn);
- break;
- }
- g_free(args.extdata);
- args.extdatalen = length;
- if (args.extdatalen == 0)
- args.extdata = NULL;
- else
- args.extdata = byte_stream_getraw(bs, args.extdatalen);
-
- } else {
- purple_debug_misc("oscar", "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length);
}
/*
@@ -1862,10 +1021,7 @@ static int incomingim_ch1(OscarData *od, FlapConnection *conn, aim_module_t *mod
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
ret = userfunc(od, conn, frame, channel, userinfo, &args);
- aim_mpmsg_free(od, &args.mpmsg);
- g_free(args.features);
- g_free(args.extdata);
-
+ g_free(args.msg);
return ret;
}
@@ -1891,7 +1047,7 @@ incomingim_ch2_buddylist(OscarData *od, FlapConnection *conn, aim_module_t *mod,
* ...
* ...
*/
- while (byte_stream_empty(servdata))
+ while (byte_stream_bytes_left(servdata))
{
guint16 gnlen, numb;
int i;
@@ -1963,7 +1119,7 @@ incomingim_ch2_chat(OscarData *od, FlapConnection *conn, aim_module_t *mod, Flap
static void
incomingim_ch2_icqserverrelay_free(OscarData *od, IcbmArgsCh2 *args)
{
- g_free((char *)args->info.rtfmsg.rtfmsg);
+ g_free((char *)args->info.rtfmsg.msg);
}
/*
@@ -1977,33 +1133,34 @@ incomingim_ch2_icqserverrelay_free(OscarData *od, IcbmArgsCh2 *args)
static void
incomingim_ch2_icqserverrelay(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata)
{
- guint16 hdrlen, anslen, msglen;
-
- if (byte_stream_empty(servdata) < 24)
- /* Someone sent us a short server relay ICBM. Weird. (Maybe?) */
- return;
+ guint16 hdrlen, msglen;
- hdrlen = byte_stream_getle16(servdata);
- byte_stream_advance(servdata, hdrlen);
+ args->destructor = (void *)incomingim_ch2_icqserverrelay_free;
- hdrlen = byte_stream_getle16(servdata);
+#define SKIP_HEADER(expected_hdrlen) \
+ hdrlen = byte_stream_getle16(servdata); \
+ if (hdrlen != expected_hdrlen) { \
+ purple_debug_warning("oscar", "Expected to find a header with length " #expected_hdrlen "; ignoring message"); \
+ return; \
+ } \
byte_stream_advance(servdata, hdrlen);
- args->info.rtfmsg.msgtype = byte_stream_getle16(servdata);
+ SKIP_HEADER(0x001b);
+ SKIP_HEADER(0x000e);
- anslen = byte_stream_getle32(servdata);
- byte_stream_advance(servdata, anslen);
+ args->info.rtfmsg.msgtype = byte_stream_get8(servdata);
+ /*
+ * Copied from http://iserverd.khstu.ru/oscar/message.html:
+ * xx byte message flags
+ * xx xx word (LE) status code
+ * xx xx word (LE) priority code
+ *
+ * We don't need any of these, so just skip them.
+ */
+ byte_stream_advance(servdata, 1 + 2 + 2);
msglen = byte_stream_getle16(servdata);
- args->info.rtfmsg.rtfmsg = byte_stream_getstr(servdata, msglen);
-
- args->info.rtfmsg.fgcolor = byte_stream_getle32(servdata);
- args->info.rtfmsg.bgcolor = byte_stream_getle32(servdata);
-
- hdrlen = byte_stream_getle32(servdata);
- byte_stream_advance(servdata, hdrlen);
-
- args->destructor = (void *)incomingim_ch2_icqserverrelay_free;
+ args->info.rtfmsg.msg = byte_stream_getstr(servdata, msglen);
}
static void
@@ -2163,7 +1320,7 @@ static int incomingim_ch2(OscarData *od, FlapConnection *conn, aim_module_t *mod
/*
* Terminate connection/error code. 0x0001 means the other user
- * canceled the connection.
+ * cancelled the connection.
*/
if (aim_tlv_gettlv(list2, 0x000b, 1))
args.errorcode = aim_tlv_get16(list2, 0x000b, 1);
@@ -2188,20 +1345,6 @@ static int incomingim_ch2(OscarData *od, FlapConnection *conn, aim_module_t *mod
if (aim_tlv_gettlv(list2, 0x000e, 1))
args.language = aim_tlv_getstr(list2, 0x000e, 1);
-#if 0
- /*
- * Unknown -- no value
- *
- * Maybe means we should connect directly to transfer the file?
- * Also used in ICQ Lite Beta 4.0 URLs. Also empty.
- */
- /* I don't think this indicates a direct transfer; this flag is
- * also present in a stage 1 proxied file send request -- Jonathan */
- if (aim_tlv_gettlv(list2, 0x000f, 1)) {
- /* Unhandled */
- }
-#endif
-
/*
* Flag meaning we should proxy the file transfer through an AIM server
*/
@@ -2396,38 +1539,6 @@ static int incomingim(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fl
return ret;
}
-/*
- * Subtype 0x0008 - Send a warning to bn.
- *
- * Flags:
- * AIM_WARN_ANON Send as an anonymous (doesn't count as much)
- *
- * returns -1 on error (couldn't alloc packet), 0 on success.
- *
- */
-int aim_im_warn(OscarData *od, FlapConnection *conn, const char *bn, guint32 flags)
-{
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!od || !conn || !bn)
- return -EINVAL;
-
- byte_stream_new(&bs, strlen(bn)+3);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0008, 0x0000, bn, strlen(bn)+1);
-
- byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000);
- byte_stream_put8(&bs, strlen(bn));
- byte_stream_putstr(&bs, bn);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0008, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
/* Subtype 0x000a */
static int missedcall(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
@@ -2436,7 +1547,7 @@ static int missedcall(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fl
guint16 channel, nummissed, reason;
aim_userinfo_t userinfo;
- while (byte_stream_empty(bs)) {
+ while (byte_stream_bytes_left(bs)) {
channel = byte_stream_get16(bs);
aim_info_extract(od, bs, &userinfo);
@@ -2456,9 +1567,7 @@ static int missedcall(OscarData *od, FlapConnection *conn, aim_module_t *mod, Fl
* Subtype 0x000b
*
* Possible codes:
- * AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support"
* AIM_TRANSFER_DENY_DECLINE -- "client has declined transfer"
- * AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers"
*
*/
int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, guint16 code)
@@ -2485,186 +1594,57 @@ int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, gui
aim_tlvlist_write(&bs, &tlvlist);
aim_tlvlist_free(tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x000b, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x000b, snacid, &bs);
byte_stream_destroy(&bs);
return 0;
}
-static void parse_status_note_text(OscarData *od, guchar *cookie, char *bn, ByteStream *bs)
+/*
+ * Subtype 0x000b.
+ * Send confirmation for a channel 2 message (Miranda wants it by default).
+ */
+void
+aim_im_send_icq_confirmation(OscarData *od, const char *bn, const guchar *cookie)
{
- struct aim_icq_info *info;
- struct aim_icq_info *prev_info;
- char *response;
- char *encoding;
- char *stripped_encoding;
- char *status_note_title;
- char *status_note_text;
- char *stripped_status_note_text;
- char *status_note;
- guint32 length;
- guint16 version;
- guint32 capability;
- guint8 message_type;
- guint16 status_code;
- guint16 text_length;
- guint32 request_length;
- guint32 response_length;
- guint32 encoding_length;
- PurpleAccount *account;
- PurpleBuddy *buddy;
- PurplePresence *presence;
- PurpleStatus *status;
-
- for (prev_info = NULL, info = od->icq_info; info != NULL; prev_info = info, info = info->next)
- {
- if (memcmp(&info->icbm_cookie, cookie, 8) == 0)
- {
- if (prev_info == NULL)
- od->icq_info = info->next;
- else
- prev_info->next = info->next;
-
- break;
- }
- }
-
- if (info == NULL)
- return;
-
- status_note_title = info->status_note_title;
- g_free(info);
-
- length = byte_stream_getle16(bs);
- if (length != 27) {
- purple_debug_misc("oscar", "clientautoresp: incorrect header "
- "size; expected 27, received %u.\n", length);
- g_free(status_note_title);
- return;
- }
-
- version = byte_stream_getle16(bs);
- if (version != 9) {
- purple_debug_misc("oscar", "clientautoresp: incorrect version; "
- "expected 9, received %u.\n", version);
- g_free(status_note_title);
- return;
- }
-
- capability = aim_locate_getcaps(od, bs, 0x10);
- if (capability != OSCAR_CAPABILITY_EMPTY) {
- purple_debug_misc("oscar", "clientautoresp: plugin ID is not null.\n");
- g_free(status_note_title);
- return;
- }
-
- byte_stream_advance(bs, 2); /* unknown */
- byte_stream_advance(bs, 4); /* client capabilities flags */
- byte_stream_advance(bs, 1); /* unknown */
- byte_stream_advance(bs, 2); /* downcouner? */
-
- length = byte_stream_getle16(bs);
- if (length != 14) {
- purple_debug_misc("oscar", "clientautoresp: incorrect header "
- "size; expected 14, received %u.\n", length);
- g_free(status_note_title);
- return;
- }
-
- byte_stream_advance(bs, 2); /* downcounter? */
- byte_stream_advance(bs, 12); /* unknown */
-
- message_type = byte_stream_get8(bs);
- if (message_type != 0x1a) {
- purple_debug_misc("oscar", "clientautoresp: incorrect message "
- "type; expected 0x1a, received 0x%x.\n", message_type);
- g_free(status_note_title);
- return;
- }
-
- byte_stream_advance(bs, 1); /* message flags */
-
- status_code = byte_stream_getle16(bs);
- if (status_code != 0) {
- purple_debug_misc("oscar", "clientautoresp: incorrect status "
- "code; expected 0, received %u.\n", status_code);
- g_free(status_note_title);
- return;
- }
-
- byte_stream_advance(bs, 2); /* priority code */
-
- text_length = byte_stream_getle16(bs);
- byte_stream_advance(bs, text_length); /* text */
-
- length = byte_stream_getle16(bs);
- byte_stream_advance(bs, 18); /* unknown */
-
- request_length = byte_stream_getle32(bs);
- if (length != 18 + 4 + request_length + 17) {
- purple_debug_misc("oscar", "clientautoresp: incorrect block; "
- "expected length is %u, got %u.\n",
- 18 + 4 + request_length + 17, length);
- g_free(status_note_title);
- return;
- }
-
- byte_stream_advance(bs, request_length); /* x request */
- byte_stream_advance(bs, 17); /* unknown */
-
- length = byte_stream_getle32(bs);
- response_length = byte_stream_getle32(bs);
- response = byte_stream_getstr(bs, response_length);
- encoding_length = byte_stream_getle32(bs);
- if (length != 4 + response_length + 4 + encoding_length) {
- purple_debug_misc("oscar", "clientautoresp: incorrect block; "
- "expected length is %u, got %u.\n",
- 4 + response_length + 4 + encoding_length, length);
- g_free(status_note_title);
- g_free(response);
- return;
- }
-
- encoding = byte_stream_getstr(bs, encoding_length);
-
- account = purple_connection_get_account(od->gc);
-
- stripped_encoding = oscar_encoding_extract(encoding);
- status_note_text = oscar_encoding_to_utf8(account, stripped_encoding, response, response_length);
- stripped_status_note_text = purple_markup_strip_html(status_note_text);
-
- if (stripped_status_note_text != NULL && stripped_status_note_text[0] != 0)
- status_note = g_strdup_printf("%s: %s", status_note_title, stripped_status_note_text);
- else
- status_note = g_strdup(status_note_title);
+ ByteStream bs;
+ aim_snacid_t snacid;
+ guint32 header_size, data_size;
+ guint16 cookie2 = (guint16)g_random_int();
- g_free(status_note_title);
- g_free(response);
- g_free(encoding);
- g_free(stripped_encoding);
- g_free(status_note_text);
- g_free(stripped_status_note_text);
+ purple_debug_misc("oscar", "Sending message ack to %s\n", bn);
- buddy = purple_find_buddy(account, bn);
- if (buddy == NULL)
- {
- purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", bn);
- g_free(status_note);
- return;
- }
-
- purple_debug_misc("oscar", "clientautoresp: setting status "
- "message to \"%s\".\n", status_note);
+ header_size = 8 + 2 + 1 + strlen(bn) + 2;
+ data_size = 2 + 1 + 16 + 4*2 + 2*3 + 4*3 + 1*2 + 2*3 + 1;
+ byte_stream_new(&bs, header_size + data_size);
- presence = purple_buddy_get_presence(buddy);
- status = purple_presence_get_active_status(presence);
+ /* The message header. */
+ aim_im_puticbm(&bs, cookie, 0x0002, bn);
+ byte_stream_put16(&bs, 0x0003); /* reason */
- purple_prpl_got_user_status(account, bn,
- purple_status_get_id(status),
- "message", status_note, NULL);
+ /* The actual message. */
+ byte_stream_putle16(&bs, 0x1b); /* subheader #1 length */
+ byte_stream_put8(&bs, 0x08); /* protocol version */
+ byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY);
+ byte_stream_put32(&bs, 0x3); /* client features */
+ byte_stream_put32(&bs, 0x0004); /* DC type */
+ byte_stream_put16(&bs, cookie2); /* a cookie, chosen by fair dice roll */
+ byte_stream_putle16(&bs, 0x0e); /* header #2 len? */
+ byte_stream_put16(&bs, cookie2); /* the same cookie again */
+ byte_stream_put32(&bs, 0); /* unknown */
+ byte_stream_put32(&bs, 0); /* unknown */
+ byte_stream_put32(&bs, 0); /* unknown */
+ byte_stream_put8(&bs, 0x01); /* plain text message */
+ byte_stream_put8(&bs, 0x00); /* no message flags */
+ byte_stream_put16(&bs, 0x0000); /* no icq status */
+ byte_stream_put16(&bs, 0x0100); /* priority */
+ byte_stream_putle16(&bs, 1); /* query message len */
+ byte_stream_put8(&bs, 0x00); /* empty query message */
- g_free(status_note);
+ snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x000b, 0x0000, NULL, 0);
+ flap_connection_send_snac(od, flap_connection_findbygroup(od, SNAC_FAMILY_ICBM), SNAC_FAMILY_ICBM, 0x000b, snacid, &bs);
+ byte_stream_destroy(&bs);
}
/*
@@ -2819,16 +1799,10 @@ static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod
}
/*
- * Subtype 0x000c - Receive an ack after sending an ICBM.
- *
- * You have to have send the message with the AIM_IMFLAGS_ACK flag set
- * (TLV t(0003)). The ack contains the ICBM header of the message you
- * sent.
- *
+ * Subtype 0x000c - Receive an ack after sending an ICBM. The ack contains the ICBM header of the message you sent.
*/
static int msgack(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- aim_rxcallback_t userfunc;
guint16 ch;
guchar *cookie;
char *bn;
@@ -2838,8 +1812,7 @@ static int msgack(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFr
ch = byte_stream_get16(bs);
bn = byte_stream_getstr(bs, byte_stream_get8(bs));
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, ch, bn);
+ purple_debug_info("oscar", "Sent message to %s.\n", bn);
g_free(bn);
g_free(cookie);
@@ -2914,7 +1887,7 @@ int aim_im_sendmtn(OscarData *od, guint16 channel, const char *bn, guint16 event
*/
byte_stream_put16(&bs, event);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0014, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0014, snacid, &bs);
byte_stream_destroy(&bs);
@@ -3002,7 +1975,7 @@ int icq_im_xstatus_request(OscarData *od, const char *sn)
aim_tlvlist_write(&bs, &outer_tlvlist);
purple_debug_misc("oscar", "X-Status Request\n");
- flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, TRUE);
+ flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, snacid, &bs, TRUE);
aim_tlvlist_free(outer_tlvlist);
byte_stream_destroy(&header);
@@ -3088,9 +2061,9 @@ int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie)
aim_im_puticbm(&bs, cookie, 0x0002, sn);
byte_stream_put16(&bs, 0x0003);
byte_stream_putraw(&bs, plugindata, sizeof(plugindata));
- byte_stream_putraw(&bs, (const guint8 *)statxml, strlen(statxml));
+ byte_stream_putraw(&bs, (const guint8*)statxml, strlen(statxml));
- flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs, TRUE);
+ flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x000b, snacid, &bs, TRUE);
g_free(statxml);
g_free(msg);
@@ -3135,8 +2108,6 @@ snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
return error(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x0005)
return aim_im_paraminfo(od, conn, mod, frame, snac, bs);
- else if (snac->subtype == 0x0006)
- return outgoingim(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x0007)
return incomingim(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x000a)
diff --git a/libpurple/protocols/oscar/family_icq.c b/libpurple/protocols/oscar/family_icq.c
index 3c796a299e..92008e8319 100644
--- a/libpurple/protocols/oscar/family_icq.c
+++ b/libpurple/protocols/oscar/family_icq.c
@@ -23,77 +23,104 @@
*
*/
+#include "encoding.h"
#include "oscar.h"
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
-int aim_icq_reqofflinemsgs(OscarData *od)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- int bslen;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
- return -EINVAL;
-
- purple_debug_info("oscar", "Requesting offline messages\n");
-
- bslen = 2 + 4 + 2 + 2;
-
- byte_stream_new(&bs, 4 + bslen);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
+#define AIM_ICQ_INFO_REQUEST 0x04b2
+#define AIM_ICQ_ALIAS_REQUEST 0x04ba
- /* For simplicity, don't bother using a tlvlist */
- byte_stream_put16(&bs, 0x0001);
- byte_stream_put16(&bs, bslen);
-
- byte_stream_putle16(&bs, bslen - 2);
- byte_stream_putuid(&bs, od);
- byte_stream_putle16(&bs, 0x003c); /* I command thee. */
- byte_stream_putle16(&bs, snacid); /* eh. */
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+static
+int compare_icq_infos(gconstpointer a, gconstpointer b)
+{
+ const struct aim_icq_info* aa = a;
+ const guint16* bb = b;
+ return aa->reqid - *bb;
+}
- byte_stream_destroy(&bs);
+static void aim_icq_freeinfo(struct aim_icq_info *info) {
+ int i;
- return 0;
+ if (!info)
+ return;
+ g_free(info->nick);
+ g_free(info->first);
+ g_free(info->last);
+ g_free(info->email);
+ g_free(info->homecity);
+ g_free(info->homestate);
+ g_free(info->homephone);
+ g_free(info->homefax);
+ g_free(info->homeaddr);
+ g_free(info->mobile);
+ g_free(info->homezip);
+ g_free(info->personalwebpage);
+ if (info->email2)
+ for (i = 0; i < info->numaddresses; i++)
+ g_free(info->email2[i]);
+ g_free(info->email2);
+ g_free(info->workcity);
+ g_free(info->workstate);
+ g_free(info->workphone);
+ g_free(info->workfax);
+ g_free(info->workaddr);
+ g_free(info->workzip);
+ g_free(info->workcompany);
+ g_free(info->workdivision);
+ g_free(info->workposition);
+ g_free(info->workwebpage);
+ g_free(info->info);
+ g_free(info->status_note_title);
+ g_free(info->auth_request_reason);
}
-int aim_icq_ackofflinemsgs(OscarData *od)
+static
+int error(OscarData *od, aim_modsnac_t *error_snac, ByteStream *bs)
{
- ByteStream bs;
- FlapFrame *frame;
- aim_snacid_t snacid;
- int bslen;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
- return -EINVAL;
-
- purple_debug_info("oscar", "Acknowledged receipt of offline messages\n");
-
- bslen = 2 + 4 + 2 + 2;
-
- byte_stream_new(&bs, 4 + bslen);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
-
- /* For simplicity, don't bother using a tlvlist */
- byte_stream_put16(&bs, 0x0001);
- byte_stream_put16(&bs, bslen);
-
- byte_stream_putle16(&bs, bslen - 2);
- byte_stream_putuid(&bs, od);
- byte_stream_putle16(&bs, 0x003e); /* I command thee. */
- byte_stream_putle16(&bs, snacid); /* eh. */
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
+ aim_snac_t *original_snac = aim_remsnac(od, error_snac->id);
+ guint16 *request_type;
+ GSList *original_info_ptr;
+ struct aim_icq_info *original_info;
+ guint16 reason;
+ gchar *uin;
+
+ if (!original_snac || (original_snac->family != SNAC_FAMILY_ICQ) || !original_snac->data) {
+ purple_debug_misc("oscar", "icq: the original snac for the error packet was not found");
+ g_free(original_snac);
+ return 0;
+ }
+
+ request_type = original_snac->data;
+ original_info_ptr = g_slist_find_custom(od->icq_info, &original_snac->id, compare_icq_infos);
+ original_info = original_info_ptr->data;
+
+ if (!original_info_ptr) {
+ purple_debug_misc("oscar", "icq: the request info for the error packet was not found");
+ g_free(original_snac);
+ return 0;
+ }
+
+ reason = byte_stream_get16(bs);
+ uin = g_strdup_printf("%u", original_info->uin);
+ switch (*request_type) {
+ case AIM_ICQ_INFO_REQUEST:
+ oscar_user_info_display_error(od, reason, uin);
+ break;
+ case AIM_ICQ_ALIAS_REQUEST:
+ /* Couldn't retrieve an alias for the buddy requesting authorization; have to make do with UIN only. */
+ if (original_info->for_auth_request)
+ oscar_auth_recvrequest(od->gc, uin, NULL, original_info->auth_request_reason);
+ break;
+ default:
+ purple_debug_misc("oscar", "icq: got an error packet with unknown request type %u", *request_type);
+ break;
+ }
- return 0;
+ aim_icq_freeinfo(original_info);
+ od->icq_info = g_slist_remove(od->icq_info, original_info_ptr);
+ g_free(original_snac->data);
+ g_free(original_snac);
+ return 1;
}
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
int
aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware)
@@ -130,7 +157,7 @@ aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware)
byte_stream_putle8(&bs, 0x00);
byte_stream_putle8(&bs, !auth_required);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
@@ -180,7 +207,7 @@ int aim_icq_changepasswd(OscarData *od, const char *passwd)
byte_stream_putraw(&bs, (const guint8 *)passwd, passwdlen);
byte_stream_putle8(&bs, '\0');
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
@@ -194,6 +221,7 @@ int aim_icq_getallinfo(OscarData *od, const char *uin)
aim_snacid_t snacid;
int bslen;
struct aim_icq_info *info;
+ guint16 request_type = AIM_ICQ_INFO_REQUEST;
if (!uin || uin[0] < '0' || uin[0] > '9')
return -EINVAL;
@@ -205,7 +233,7 @@ int aim_icq_getallinfo(OscarData *od, const char *uin)
byte_stream_new(&bs, 4 + bslen);
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
+ snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, &request_type, sizeof(request_type));
/* For simplicity, don't bother using a tlvlist */
byte_stream_put16(&bs, 0x0001);
@@ -215,10 +243,10 @@ int aim_icq_getallinfo(OscarData *od, const char *uin)
byte_stream_putuid(&bs, od);
byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
byte_stream_putle16(&bs, snacid); /* eh. */
- byte_stream_putle16(&bs, 0x04b2); /* shrug. */
+ byte_stream_putle16(&bs, request_type); /* shrug. */
byte_stream_putle32(&bs, atoi(uin));
- flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs, FALSE);
+ flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, snacid, &bs, FALSE);
byte_stream_destroy(&bs);
@@ -226,19 +254,19 @@ int aim_icq_getallinfo(OscarData *od, const char *uin)
info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
info->reqid = snacid;
info->uin = atoi(uin);
- info->next = od->icq_info;
- od->icq_info = info;
+ od->icq_info = g_slist_prepend(od->icq_info, info);
return 0;
}
-int aim_icq_getalias(OscarData *od, const char *uin)
+int aim_icq_getalias(OscarData *od, const char *uin, gboolean for_auth_request, char *auth_request_reason)
{
FlapConnection *conn;
ByteStream bs;
aim_snacid_t snacid;
int bslen;
struct aim_icq_info *info;
+ guint16 request_type = AIM_ICQ_ALIAS_REQUEST;
if (!uin || uin[0] < '0' || uin[0] > '9')
return -EINVAL;
@@ -252,7 +280,7 @@ int aim_icq_getalias(OscarData *od, const char *uin)
byte_stream_new(&bs, 4 + bslen);
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
+ snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, &request_type, sizeof(request_type));
/* For simplicity, don't bother using a tlvlist */
byte_stream_put16(&bs, 0x0001);
@@ -262,10 +290,10 @@ int aim_icq_getalias(OscarData *od, const char *uin)
byte_stream_putuid(&bs, od);
byte_stream_putle16(&bs, 0x07d0); /* I command thee. */
byte_stream_putle16(&bs, snacid); /* eh. */
- byte_stream_putle16(&bs, 0x04ba); /* shrug. */
+ byte_stream_putle16(&bs, request_type); /* shrug. */
byte_stream_putle32(&bs, atoi(uin));
- flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs, FALSE);
+ flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, snacid, &bs, FALSE);
byte_stream_destroy(&bs);
@@ -273,88 +301,12 @@ int aim_icq_getalias(OscarData *od, const char *uin)
info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
info->reqid = snacid;
info->uin = atoi(uin);
- info->next = od->icq_info;
- od->icq_info = info;
-
- return 0;
-}
-
-int aim_icq_getsimpleinfo(OscarData *od, const char *uin)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- int bslen;
-
- if (!uin || uin[0] < '0' || uin[0] > '9')
- return -EINVAL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
- return -EINVAL;
-
- bslen = 2 + 4 + 2 + 2 + 2 + 4;
-
- byte_stream_new(&bs, 4 + bslen);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
-
- /* For simplicity, don't bother using a tlvlist */
- byte_stream_put16(&bs, 0x0001);
- byte_stream_put16(&bs, bslen);
-
- byte_stream_putle16(&bs, bslen - 2);
- byte_stream_putuid(&bs, od);
- 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_snac_with_priority(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs, FALSE);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-#if 0
-int aim_icq_sendxmlreq(OscarData *od, const char *xml)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- int bslen;
-
- if (!xml || !strlen(xml))
- return -EINVAL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ)))
- return -EINVAL;
-
- bslen = 2 + 10 + 2 + strlen(xml) + 1;
-
- byte_stream_new(&bs, 4 + bslen);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ICQ, 0x0002, 0x0000, NULL, 0);
-
- /* For simplicity, don't bother using a tlvlist */
- byte_stream_put16(&bs, 0x0001);
- byte_stream_put16(&bs, bslen);
-
- byte_stream_putle16(&bs, bslen - 2);
- byte_stream_putuid(&bs, od);
- 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_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
+ info->for_auth_request = for_auth_request;
+ info->auth_request_reason = g_strdup(auth_request_reason);
+ od->icq_info = g_slist_prepend(od->icq_info, info);
return 0;
}
-#endif
/*
* Send an SMS message. This is the non-US way. The US-way is to IM
@@ -446,7 +398,7 @@ int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char
byte_stream_putstr(&bs, xml);
byte_stream_put8(&bs, 0x00);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_ICQ, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
@@ -456,49 +408,35 @@ int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char
return 0;
}
-static void aim_icq_freeinfo(struct aim_icq_info *info) {
- int i;
-
- if (!info)
- return;
- g_free(info->nick);
- g_free(info->first);
- g_free(info->last);
- g_free(info->email);
- g_free(info->homecity);
- g_free(info->homestate);
- g_free(info->homephone);
- g_free(info->homefax);
- g_free(info->homeaddr);
- g_free(info->mobile);
- g_free(info->homezip);
- g_free(info->personalwebpage);
- if (info->email2)
- for (i = 0; i < info->numaddresses; i++)
- g_free(info->email2[i]);
- g_free(info->email2);
- g_free(info->workcity);
- g_free(info->workstate);
- g_free(info->workphone);
- g_free(info->workfax);
- g_free(info->workaddr);
- g_free(info->workzip);
- g_free(info->workcompany);
- g_free(info->workdivision);
- g_free(info->workposition);
- g_free(info->workwebpage);
- g_free(info->info);
- g_free(info->status_note_title);
- g_free(info);
+static int
+gotalias(OscarData *od, struct aim_icq_info *info)
+{
+ PurpleConnection *gc = od->gc;
+ PurpleAccount *account = purple_connection_get_account(gc);
+ gchar who[16], *utf8;
+ PurpleBuddy *b;
+
+ if (info->nick[0] && (utf8 = oscar_utf8_try_convert(account, od, info->nick))) {
+ if (info->for_auth_request) {
+ oscar_auth_recvrequest(gc, g_strdup_printf("%u", info->uin), utf8, info->auth_request_reason);
+ } else {
+ g_snprintf(who, sizeof(who), "%u", info->uin);
+ serv_got_alias(gc, who, utf8);
+ if ((b = purple_find_buddy(account, who))) {
+ purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", utf8);
+ }
+ g_free(utf8);
+ }
+ }
+ return 1;
}
/**
* Subtype 0x0003 - Response to SNAC_FAMILY_ICQ/0x002, contains an ICQesque packet.
*/
static int
-icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
+icqresponse(OscarData *od, aim_modsnac_t *snac, ByteStream *bs)
{
- int ret = 0;
GSList *tlvlist;
aim_tlv_t *datatlv;
ByteStream qbs;
@@ -520,53 +458,23 @@ icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
purple_debug_misc("oscar", "icq response: %d bytes, %u, 0x%04x, 0x%04x\n", cmdlen, ouruin, cmd, reqid);
- if (cmd == 0x0041) { /* offline message */
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
- struct aim_icq_offlinemsg msg;
- aim_rxcallback_t userfunc;
-
- memset(&msg, 0, sizeof(msg));
-
- msg.sender = byte_stream_getle32(&qbs);
- msg.year = byte_stream_getle16(&qbs);
- msg.month = byte_stream_getle8(&qbs);
- msg.day = byte_stream_getle8(&qbs);
- msg.hour = byte_stream_getle8(&qbs);
- msg.minute = byte_stream_getle8(&qbs);
- msg.type = byte_stream_getle8(&qbs);
- msg.flags = byte_stream_getle8(&qbs);
- msg.msglen = byte_stream_getle16(&qbs);
- msg.msg = byte_stream_getstr(&qbs, msg.msglen);
-
- if ((userfunc = aim_callhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSG)))
- ret = userfunc(od, conn, frame, &msg);
-
- g_free(msg.msg);
-
- } else if (cmd == 0x0042) {
- aim_rxcallback_t userfunc;
-
- if ((userfunc = aim_callhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSGCOMPLETE)))
- ret = userfunc(od, conn, frame);
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
-
- } else if (cmd == 0x07da) { /* information */
+ if (cmd == 0x07da) { /* information */
guint16 subtype;
+ GSList *info_ptr;
struct aim_icq_info *info;
- aim_rxcallback_t userfunc;
subtype = byte_stream_getle16(&qbs);
byte_stream_advance(&qbs, 1); /* 0x0a */
/* find other data from the same request */
- for (info = od->icq_info; info && (info->reqid != reqid); info = info->next);
- if (!info) {
- info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
- info->reqid = reqid;
- info->next = od->icq_info;
- od->icq_info = info;
+ info_ptr = g_slist_find_custom(od->icq_info, &reqid, compare_icq_infos);
+ if (!info_ptr) {
+ struct aim_icq_info *new_info = (struct aim_icq_info *)g_new0(struct aim_icq_info, 1);
+ new_info->reqid = reqid;
+ info_ptr = od->icq_info = g_slist_prepend(od->icq_info, new_info);
}
+ info = info_ptr->data;
switch (subtype) {
case 0x00a0: { /* hide ip status */
/* nothing */
@@ -818,10 +726,9 @@ icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
memcpy(&info->icbm_cookie, cookie, 8);
- info->next = od->icq_info;
- od->icq_info = info;
+ od->icq_info = g_slist_prepend(od->icq_info, info);
- flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, FALSE);
+ flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, snacid, &bs, FALSE);
byte_stream_destroy(&bs);
}
@@ -834,35 +741,28 @@ icqresponse(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
if (!(snac->flags & 0x0001)) {
if (subtype != 0x0104)
- if ((userfunc = aim_callhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_INFO)))
- ret = userfunc(od, conn, frame, info);
+ oscar_user_info_display_icq(od, info);
if (info->uin && info->nick)
- if ((userfunc = aim_callhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_ALIAS)))
- ret = userfunc(od, conn, frame, info);
-
- if (od->icq_info == info) {
- od->icq_info = info->next;
- } else {
- struct aim_icq_info *cur;
- for (cur=od->icq_info; (cur->next && (cur->next!=info)); cur=cur->next);
- if (cur->next)
- cur->next = cur->next->next;
- }
+ gotalias(od, info);
+
aim_icq_freeinfo(info);
+ od->icq_info = g_slist_remove(od->icq_info, info);
}
}
aim_tlvlist_free(tlvlist);
- return ret;
+ return 1;
}
static int
snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- if (snac->subtype == 0x0003)
- return icqresponse(od, conn, mod, frame, snac, bs);
+ if (snac->subtype == 0x0001)
+ return error(od, snac, bs);
+ else if (snac->subtype == 0x0003)
+ return icqresponse(od, snac, bs);
return 0;
}
@@ -870,15 +770,10 @@ snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
static void
icq_shutdown(OscarData *od, aim_module_t *mod)
{
- struct aim_icq_info *del;
-
- while (od->icq_info) {
- del = od->icq_info;
- od->icq_info = od->icq_info->next;
- aim_icq_freeinfo(del);
- }
-
- return;
+ GSList *cur;
+ for (cur = od->icq_info; cur; cur = cur->next)
+ aim_icq_freeinfo(cur->data);
+ g_slist_free(od->icq_info);
}
int
diff --git a/libpurple/protocols/oscar/family_invite.c b/libpurple/protocols/oscar/family_invite.c
deleted file mode 100644
index bd9cbd25fb..0000000000
--- a/libpurple/protocols/oscar/family_invite.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Purple's oscar protocol plugin
- * This file is the legal property of its developers.
- * Please see the AUTHORS file distributed alongside this file.
- *
- * 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 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
-*/
-
-/*
- * Family 0x0006 - This isn't really ever used by anyone anymore.
- *
- * Once upon a time, there used to be a menu item in AIM clients that
- * said something like "Invite a friend to use AIM..." and then it would
- * ask for an email address and it would sent a mail to them saying
- * how perfectly wonderful the AIM service is and why you should use it
- * and click here if you hate the person who sent this to you and want to
- * complain and yell at them in a small box with pretty fonts.
- *
- * I could've sworn libfaim had this implemented once, a long long time ago,
- * but I can't find it.
- *
- * I'm mainly adding this so that I can keep advertising that we support
- * group 6, even though we don't.
- *
- */
-
-#include "oscar.h"
-
-int invite_modfirst(OscarData *od, aim_module_t *mod)
-{
-
- mod->family = SNAC_FAMILY_INVITE;
- mod->version = 0x0001;
- mod->toolid = 0x0110;
- mod->toolversion = 0x0629;
- mod->flags = 0;
- strncpy(mod->name, "invite", sizeof(mod->name));
- mod->snachandler = NULL;
-
- return 0;
-}
diff --git a/libpurple/protocols/oscar/family_locate.c b/libpurple/protocols/oscar/family_locate.c
index 59f25077a2..8296aaca59 100644
--- a/libpurple/protocols/oscar/family_locate.c
+++ b/libpurple/protocols/oscar/family_locate.c
@@ -245,6 +245,10 @@ static const struct {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {OSCAR_CAPABILITY_HTML_MSGS,
+ {0x01, 0x38, 0xca, 0x7b, 0x76, 0x9a, 0x49, 0x15,
+ 0x88, 0xf2, 0x13, 0xfc, 0x00, 0x97, 0x9e, 0xa8}},
+
{OSCAR_CAPABILITY_LAST,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
@@ -583,7 +587,7 @@ aim_locate_getcaps(OscarData *od, ByteStream *bs, int len)
guint64 flags = 0;
int offset;
- for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x10) {
+ for (offset = 0; byte_stream_bytes_left(bs) && (offset < len); offset += 0x10) {
guint8 *cap;
int i, identified;
@@ -617,7 +621,7 @@ aim_receive_custom_icon(OscarData *od, ByteStream *bs, int len)
int offset;
const char *result = NULL;
- for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x10) {
+ for (offset = 0; byte_stream_bytes_left(bs) && (offset < len); offset += 0x10) {
/* check wheather this capability is a custom user icon */
guint8 *cap;
int i;
@@ -643,7 +647,7 @@ aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len)
guint64 flags = 0;
int offset;
- for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x02) {
+ for (offset = 0; byte_stream_bytes_left(bs) && (offset < len); offset += 0x02) {
guint8 *cap;
int i, identified;
@@ -674,16 +678,13 @@ byte_stream_putcaps(ByteStream *bs, guint64 caps)
if (!bs)
return -EINVAL;
- for (i = 0; byte_stream_empty(bs); i++) {
-
+ for (i = 0; byte_stream_bytes_left(bs); i++) {
if (aim_caps[i].flag == OSCAR_CAPABILITY_LAST)
break;
if (caps & aim_caps[i].flag)
byte_stream_putraw(bs, aim_caps[i].data, 0x10);
-
}
-
return 0;
}
@@ -804,7 +805,7 @@ aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo)
type = byte_stream_get16(bs);
length = byte_stream_get16(bs);
curpos = byte_stream_curpos(bs);
- endpos = curpos + MIN(length, byte_stream_empty(bs));
+ endpos = curpos + MIN(length, byte_stream_bytes_left(bs));
if (type == 0x0001) {
/*
@@ -1010,7 +1011,7 @@ aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo)
number2 = byte_stream_get8(bs);
length2 = byte_stream_get8(bs);
- endpos2 = byte_stream_curpos(bs) + MIN(length2, byte_stream_empty(bs));
+ endpos2 = byte_stream_curpos(bs) + MIN(length2, byte_stream_bytes_left(bs));
switch (type2) {
case 0x0000: { /* This is an official buddy icon? */
@@ -1165,68 +1166,12 @@ aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo)
return 0;
}
-/* Apparently, this is never called.
- * If you activate it, figure out a way to know what mood to pass to
- * aim_tlvlist_add_caps() below. --rlaager */
-#if 0
-/*
- * Inverse of aim_info_extract()
- */
-int
-aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info)
-{
- GSList *tlvlist = NULL;
-
- if (!bs || !info)
- return -EINVAL;
-
- byte_stream_put8(bs, strlen(info->bn));
- byte_stream_putstr(bs, info->bn);
-
- byte_stream_put16(bs, info->warnlevel);
-
- if (info->present & AIM_USERINFO_PRESENT_FLAGS)
- aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags);
- if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
- aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince);
- if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
- aim_tlvlist_add_32(&tlvlist, 0x0003, info->onlinesince);
- if (info->present & AIM_USERINFO_PRESENT_IDLE)
- aim_tlvlist_add_16(&tlvlist, 0x0004, info->idletime);
-
-/* XXX - So, ICQ_OSCAR_SUPPORT is never defined anywhere... */
-#ifdef ICQ_OSCAR_SUPPORT
- if (atoi(info->bn) != 0) {
- if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS)
- aim_tlvlist_add_16(&tlvlist, 0x0006, info->icqinfo.status);
- if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR)
- aim_tlvlist_add_32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
- }
-#endif
-
- if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES) {
- aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities, NULL);
- }
-
- if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
- aim_tlvlist_add_32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
-
- byte_stream_put16(bs, aim_tlvlist_count(tlvlist));
- aim_tlvlist_write(bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- return 0;
-}
-#endif
-
/*
* Subtype 0x0001
*/
static int
error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- int ret = 0;
- aim_rxcallback_t userfunc;
aim_snac_t *snac2;
guint16 reason;
char *bn;
@@ -1253,14 +1198,12 @@ error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame,
reason = byte_stream_get16(bs);
- /* Notify the user that we do not have info for this buddy */
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, reason, bn);
+ oscar_user_info_display_error(od, reason, bn);
g_free(snac2->data);
g_free(snac2);
- return ret;
+ return 1;
}
/*
@@ -1390,7 +1333,7 @@ aim_locate_setprofile(OscarData *od,
aim_tlvlist_write(&bs, &tlvlist);
aim_tlvlist_free(tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
@@ -1424,41 +1367,7 @@ aim_locate_setcaps(OscarData *od, guint64 caps)
aim_tlvlist_write(&bs, &tlvlist);
aim_tlvlist_free(tlvlist);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
- * Subtype 0x0005 - Request info of another AIM user.
- *
- * @param bn The buddy name whose info you wish to request.
- * @param infotype The type of info you wish to request.
- * 0x0001 - Info/profile
- * 0x0003 - Away message
- * 0x0004 - Capabilities
- */
-int
-aim_locate_getinfo(OscarData *od, const char *bn, guint16 infotype)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !bn)
- return -EINVAL;
-
- byte_stream_new(&bs, 2+1+strlen(bn));
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, NULL, 0);
-
- byte_stream_put16(&bs, infotype);
- byte_stream_put8(&bs, strlen(bn));
- byte_stream_putstr(&bs, bn);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
@@ -1470,7 +1379,6 @@ static int
userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
int ret = 0;
- aim_rxcallback_t userfunc;
aim_userinfo_t *userinfo, *userinfo2;
GSList *tlvlist;
aim_tlv_t *tlv = NULL;
@@ -1522,140 +1430,12 @@ userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fram
g_free(userinfo);
/* Show the info to the user */
- if (userinfo2 != NULL && ((userfunc = aim_callhandler(od, snac->family, snac->subtype))))
- ret = userfunc(od, conn, frame, userinfo2);
+ oscar_user_info_display_aim(od, userinfo2);
return ret;
}
/*
- * Subtype 0x0009 - Set directory profile data.
- *
- * This is not the same as aim_location_setprofile!
- * privacy: 1 to allow searching, 0 to disallow.
- *
- */
-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;
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tlvlist = NULL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
- return -EINVAL;
-
- aim_tlvlist_add_16(&tlvlist, 0x000a, privacy);
-
- if (first)
- aim_tlvlist_add_str(&tlvlist, 0x0001, first);
- if (last)
- aim_tlvlist_add_str(&tlvlist, 0x0002, last);
- if (middle)
- aim_tlvlist_add_str(&tlvlist, 0x0003, middle);
- if (maiden)
- aim_tlvlist_add_str(&tlvlist, 0x0004, maiden);
-
- if (state)
- aim_tlvlist_add_str(&tlvlist, 0x0007, state);
- if (city)
- aim_tlvlist_add_str(&tlvlist, 0x0008, city);
-
- if (nickname)
- aim_tlvlist_add_str(&tlvlist, 0x000c, nickname);
- if (zip)
- aim_tlvlist_add_str(&tlvlist, 0x000d, zip);
-
- if (street)
- aim_tlvlist_add_str(&tlvlist, 0x0021, street);
-
- byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, NULL, 0);
-
- aim_tlvlist_write(&bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
- * Subtype 0x000b - Huh? What is this?
- */
-int aim_locate_000b(OscarData *od, const char *bn)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
-
- return -EINVAL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !bn)
- return -EINVAL;
-
- byte_stream_new(&bs, 1+strlen(bn));
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, NULL, 0);
-
- byte_stream_put8(&bs, strlen(bn));
- byte_stream_putstr(&bs, bn);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-/*
- * Subtype 0x000f
- *
- * XXX pass these in better
- *
- */
-int
-aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tlvlist = NULL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
- return -EINVAL;
-
- /* ?? privacy ?? */
- aim_tlvlist_add_16(&tlvlist, 0x000a, privacy);
-
- if (interest1)
- aim_tlvlist_add_str(&tlvlist, 0x0000b, interest1);
- if (interest2)
- aim_tlvlist_add_str(&tlvlist, 0x0000b, interest2);
- if (interest3)
- aim_tlvlist_add_str(&tlvlist, 0x0000b, interest3);
- if (interest4)
- aim_tlvlist_add_str(&tlvlist, 0x0000b, interest4);
- if (interest5)
- aim_tlvlist_add_str(&tlvlist, 0x0000b, interest5);
-
- byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x000f, 0x0000, NULL, 0);
-
- aim_tlvlist_write(&bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x000f, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
- return 0;
-}
-
-/*
* Subtype 0x0015 - Request the info of a user using the short method. This is
* what iChat uses. It normally is VERY leniently rate limited.
*
@@ -1683,7 +1463,7 @@ aim_locate_getinfoshort(OscarData *od, const char *bn, guint32 flags)
byte_stream_putstr(&bs, bn);
snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, bn, strlen(bn)+1);
- flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, snacid, &bs, FALSE);
+ flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_LOCATE, 0x0015, snacid, &bs, FALSE);
byte_stream_destroy(&bs);
@@ -1731,15 +1511,6 @@ locate_modfirst(OscarData *od, aim_module_t *mod)
return 0;
}
-#if 0 //rlaager
-const char* aim_get_custom_icon_mood(gint32 no)
-{
- if (no >= G_N_ELEMENTS(aim_custom_icons) || no < 1)
- return NULL;
- return aim_custom_icons[no].mood.mood;
-}
-#endif
-
const char*
icq_get_custom_icon_description(const char *mood)
{
diff --git a/libpurple/protocols/oscar/family_odir.c b/libpurple/protocols/oscar/family_odir.c
deleted file mode 100644
index be1638fb39..0000000000
--- a/libpurple/protocols/oscar/family_odir.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Purple's oscar protocol plugin
- * This file is the legal property of its developers.
- * Please see the AUTHORS file distributed alongside this file.
- *
- * 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 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
-*/
-
-/*
- * Family 0x000f - Newer Search Method
- *
- * Used for searching for other AIM users by email address, name,
- * location, commmon interests, and a few other similar things.
- *
- */
-
-#include "oscar.h"
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * Search for an AIM buddy based on their email address.
- *
- * @param od The oscar session.
- * @param region Should be "us-ascii" unless you know what you're doing.
- * @param email The email address you want to search for.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_odir_email(OscarData *od, const char *region, const char *email)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tlvlist = NULL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region || !email)
- return -EINVAL;
-
- /* Create a TLV chain, write it to the outgoing frame, then free the chain */
- aim_tlvlist_add_str(&tlvlist, 0x001c, region);
- aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0001); /* Type of search */
- aim_tlvlist_add_str(&tlvlist, 0x0005, email);
-
- byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
-
- aim_tlvlist_write(&bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * Search for an AIM buddy based on various info
- * about the person.
- *
- * @param od The oscar session.
- * @param region Should be "us-ascii" unless you know what you're doing.
- * @param first The first name of the person you want to search for.
- * @param middle The middle name of the person you want to search for.
- * @param last The last name of the person you want to search for.
- * @param maiden The maiden name of the person you want to search for.
- * @param nick The nick name of the person you want to search for.
- * @param city The city where the person you want to search for resides.
- * @param state The state where the person you want to search for resides.
- * @param country The country where the person you want to search for resides.
- * @param zip The zip code where the person you want to search for resides.
- * @param address The street address where the person you want to seach for resides.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-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;
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tlvlist = NULL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region)
- return -EINVAL;
-
- /* Create a TLV chain, write it to the outgoing frame, then free the chain */
- aim_tlvlist_add_str(&tlvlist, 0x001c, region);
- aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0000); /* Type of search */
- if (first)
- aim_tlvlist_add_str(&tlvlist, 0x0001, first);
- if (last)
- aim_tlvlist_add_str(&tlvlist, 0x0002, last);
- if (middle)
- aim_tlvlist_add_str(&tlvlist, 0x0003, middle);
- if (maiden)
- aim_tlvlist_add_str(&tlvlist, 0x0004, maiden);
- if (country)
- aim_tlvlist_add_str(&tlvlist, 0x0006, country);
- if (state)
- aim_tlvlist_add_str(&tlvlist, 0x0007, state);
- if (city)
- aim_tlvlist_add_str(&tlvlist, 0x0008, city);
- if (nick)
- aim_tlvlist_add_str(&tlvlist, 0x000c, nick);
- if (zip)
- aim_tlvlist_add_str(&tlvlist, 0x000d, zip);
- if (address)
- aim_tlvlist_add_str(&tlvlist, 0x0021, address);
-
- byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
-
- aim_tlvlist_write(&bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * @param od The oscar session.
- * @param interest1 An interest you want to search for.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-int aim_odir_interest(OscarData *od, const char *region, const char *interest)
-{
- FlapConnection *conn;
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tlvlist = NULL;
-
- if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ODIR)) || !region)
- return -EINVAL;
-
- /* Create a TLV chain, write it to the outgoing frame, then free the chain */
- aim_tlvlist_add_str(&tlvlist, 0x001c, region);
- aim_tlvlist_add_16(&tlvlist, 0x000a, 0x0001); /* Type of search */
- if (interest)
- aim_tlvlist_add_str(&tlvlist, 0x0001, interest);
-
- byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
-
- aim_tlvlist_write(&bs, &tlvlist);
- aim_tlvlist_free(tlvlist);
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_ODIR, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_ODIR, 0x0002, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-
- return 0;
-}
-
-
-/**
- * Subtype 0x0003 - Receive Reply From a User Search
- *
- */
-static int parseresults(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
-{
- int ret = 0;
- aim_rxcallback_t userfunc;
- guint16 tmp, numresults;
- struct aim_odir *results = NULL;
-
- tmp = byte_stream_get16(bs); /* Unknown */
- tmp = byte_stream_get16(bs); /* Unknown */
- byte_stream_advance(bs, tmp);
-
- numresults = byte_stream_get16(bs); /* Number of results to follow */
-
- /* Allocate a linked list, 1 node per result */
- while (numresults) {
- struct aim_odir *new;
- GSList *tlvlist = aim_tlvlist_readnum(bs, byte_stream_get16(bs));
- new = (struct aim_odir *)g_malloc(sizeof(struct aim_odir));
- new->first = aim_tlv_getstr(tlvlist, 0x0001, 1);
- new->last = aim_tlv_getstr(tlvlist, 0x0002, 1);
- new->middle = aim_tlv_getstr(tlvlist, 0x0003, 1);
- new->maiden = aim_tlv_getstr(tlvlist, 0x0004, 1);
- new->email = aim_tlv_getstr(tlvlist, 0x0005, 1);
- new->country = aim_tlv_getstr(tlvlist, 0x0006, 1);
- new->state = aim_tlv_getstr(tlvlist, 0x0007, 1);
- new->city = aim_tlv_getstr(tlvlist, 0x0008, 1);
- new->bn = aim_tlv_getstr(tlvlist, 0x0009, 1);
- new->interest = aim_tlv_getstr(tlvlist, 0x000b, 1);
- new->nick = aim_tlv_getstr(tlvlist, 0x000c, 1);
- new->zip = aim_tlv_getstr(tlvlist, 0x000d, 1);
- new->region = aim_tlv_getstr(tlvlist, 0x001c, 1);
- new->address = aim_tlv_getstr(tlvlist, 0x0021, 1);
- new->next = results;
- results = new;
- numresults--;
- }
-
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, results);
-
- /* Now free everything from above */
- while (results) {
- struct aim_odir *del = results;
- results = results->next;
- g_free(del->first);
- g_free(del->last);
- g_free(del->middle);
- g_free(del->maiden);
- g_free(del->email);
- g_free(del->country);
- g_free(del->state);
- g_free(del->city);
- g_free(del->bn);
- g_free(del->interest);
- g_free(del->nick);
- g_free(del->zip);
- g_free(del->region);
- g_free(del->address);
- g_free(del);
- }
-
- return ret;
-}
-
-static int
-snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
-{
- if (snac->subtype == 0x0003)
- return parseresults(od, conn, mod, frame, snac, bs);
-
- return 0;
-}
-
-int
-odir_modfirst(OscarData *od, aim_module_t *mod)
-{
- mod->family = SNAC_FAMILY_ODIR;
- mod->version = 0x0001;
- mod->toolid = 0x0010;
- mod->toolversion = 0x0629;
- mod->flags = 0;
- strncpy(mod->name, "odir", sizeof(mod->name));
- mod->snachandler = snachandler;
-
- return 0;
-}
diff --git a/libpurple/protocols/oscar/family_oservice.c b/libpurple/protocols/oscar/family_oservice.c
index bd41aa439c..b566642289 100644
--- a/libpurple/protocols/oscar/family_oservice.c
+++ b/libpurple/protocols/oscar/family_oservice.c
@@ -73,7 +73,7 @@ aim_srv_clientready(OscarData *od, FlapConnection *conn)
}
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0002, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -97,7 +97,7 @@ hostonline(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fr
{
int group;
- while (byte_stream_empty(bs))
+ while (byte_stream_bytes_left(bs))
{
group = byte_stream_get16(bs);
conn->groups = g_slist_prepend(conn->groups, GUINT_TO_POINTER(group));
@@ -141,7 +141,7 @@ aim_srv_requestnew(OscarData *od, guint16 serviceid)
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -187,7 +187,7 @@ aim_chat_join(OscarData *od, guint16 exchange, const char *roomname, guint16 ins
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, &csi, sizeof(csi));
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, snacid, &bs);
byte_stream_destroy(&bs);
@@ -444,30 +444,7 @@ aim_srv_rates_addparam(OscarData *od, FlapConnection *conn)
}
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0008, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0008, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-}
-
-/* Subtype 0x0009 - Delete Rate Parameter */
-void
-aim_srv_rates_delparam(OscarData *od, FlapConnection *conn)
-{
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *tmp;
-
- byte_stream_new(&bs, 502);
-
- for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next)
- {
- struct rateclass *rateclass;
- rateclass = tmp->data;
- byte_stream_put16(&bs, rateclass->classid);
- }
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0009, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0009, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0008, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -558,40 +535,6 @@ serverpause(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *f
return ret;
}
-/*
- * Subtype 0x000c - Service Pause Acknowledgement
- *
- * It is rather important that aim_srv_sendpauseack() gets called for the exact
- * same connection that the Server Pause callback was called for, since
- * libfaim extracts the data for the SNAC from the connection structure.
- *
- * Of course, if you don't do that, more bad things happen than just what
- * libfaim can cause.
- *
- */
-void
-aim_srv_sendpauseack(OscarData *od, FlapConnection *conn)
-{
- ByteStream bs;
- aim_snacid_t snacid;
- GSList *cur;
-
- byte_stream_new(&bs, 1014);
-
- /*
- * This list should have all the groups that the original
- * Host Online / Server Ready said this host supports. And
- * we want them all back after the migration.
- */
- for (cur = conn->groups; cur != NULL; cur = cur->next)
- byte_stream_put16(&bs, GPOINTER_TO_UINT(cur->data));
-
- snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x000c, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x000c, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-}
-
/* Subtype 0x000d - Service Resume */
static int
serverresume(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -643,7 +586,7 @@ evilnotify(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fr
newevil = byte_stream_get16(bs);
- if (byte_stream_empty(bs))
+ if (byte_stream_bytes_left(bs))
aim_info_extract(od, bs, &userinfo);
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
@@ -770,36 +713,6 @@ motd(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, a
}
/*
- * Subtype 0x0014 - Set privacy flags
- *
- * Normally 0x03.
- *
- * Bit 1: Allows other AIM users to see how long you've been idle.
- * Bit 2: Allows other AIM users to see how long you've been a member.
- *
- */
-void
-aim_srv_setprivacyflags(OscarData *od, FlapConnection *conn, guint32 flags)
-{
- aim_genericreq_l(od, conn, SNAC_FAMILY_OSERVICE, 0x0014, &flags);
-}
-
-/*
- * Subtype 0x0016 - No-op
- *
- * WinAIM sends these every 4min or so to keep the connection alive. Its not
- * really necessary.
- *
- * Wha? No? Since when? I think WinAIM sends an empty channel 5
- * FLAP as a no-op...
- */
-void
-aim_srv_nop(OscarData *od, FlapConnection *conn)
-{
- aim_genericreq_n(od, conn, SNAC_FAMILY_OSERVICE, 0x0016);
-}
-
-/*
* Subtype 0x0017 - Set client versions
*
* If you've seen the clientonline/clientready SNAC you're probably
@@ -837,7 +750,7 @@ aim_srv_setversions(OscarData *od, FlapConnection *conn)
}
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0017, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0017, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0017, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -850,8 +763,8 @@ hostversions(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *
guint8 *versions;
/* This is frivolous. (Thank you SmarterChild.) */
- vercount = byte_stream_empty(bs)/4;
- versions = byte_stream_getraw(bs, byte_stream_empty(bs));
+ vercount = byte_stream_bytes_left(bs)/4;
+ versions = byte_stream_getraw(bs, byte_stream_bytes_left(bs));
g_free(versions);
/*
@@ -899,16 +812,6 @@ aim_srv_setextrainfo(OscarData *od,
AIM_ICQ_STATE_HIDEIP | AIM_ICQ_STATE_DIRECTREQUIREAUTH);
}
-#if 0
- if (other_stuff_that_isnt_implemented)
- {
- aim_tlvlist_add_raw(&tlvlist, 0x000c, 0x0025,
- chunk_of_x25_bytes_with_ip_address_etc);
- aim_tlvlist_add_raw(&tlvlist, 0x0011, 0x0005, unknown 0x01 61 10 f6 41);
- aim_tlvlist_add_16(&tlvlist, 0x0012, unknown 0x00 00);
- }
-#endif
-
if (setstatusmsg)
{
size_t statusmsglen, itmsurllen;
@@ -932,13 +835,57 @@ aim_srv_setextrainfo(OscarData *od,
aim_tlvlist_free(tlvlist);
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x001e, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x001e, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x001e, snacid, &bs);
byte_stream_destroy(&bs);
return 0;
}
+/* Send dummy DC (direct connect) information to the server.
+ * Direct connect is ICQ's counterpart for AIM's DirectIM,
+ * as far as I can tell. Anyway, we don't support it;
+ * the reason to send this packet is that some clients
+ * (Miranda, QIP) won't send us channel 2 ICBM messages
+ * unless we specify DC version >= 8.
+ *
+ * See #12044 for more information.
+ */
+void
+aim_srv_set_dc_info(OscarData *od)
+{
+ ByteStream bs, tlv0c;
+ aim_snacid_t snacid;
+ GSList *tlvlist = NULL;
+
+ /* http://iserverd.khstu.ru/oscar/snac_01_1e.html has a nice analysis of what goes in 0xc tlv.
+ * Kopete sends a dummy DC info, too, so I just copied the values from them.
+ */
+ byte_stream_new(&tlv0c, 4*2 + 1 + 2 + 4*6 + 2);
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put8(&tlv0c, 0x0); /* We don't support DC */
+ byte_stream_put16(&tlv0c, 8); /* DC version */
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put32(&tlv0c, 0x50);
+ byte_stream_put32(&tlv0c, 0x3);
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put32(&tlv0c, 0x0);
+ byte_stream_put16(&tlv0c, 0x0);
+ aim_tlvlist_add_raw(&tlvlist, 0x000c, byte_stream_curpos(&tlv0c), tlv0c.data);
+ byte_stream_destroy(&tlv0c);
+
+ byte_stream_new(&bs, aim_tlvlist_size(tlvlist));
+ aim_tlvlist_write(&bs, &tlvlist);
+ aim_tlvlist_free(tlvlist);
+
+ snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x001e, 0x0000, NULL, 0);
+ flap_connection_send_snac(od, flap_connection_findbygroup(od, SNAC_FAMILY_ICBM), SNAC_FAMILY_OSERVICE, 0x001e, snacid, &bs);
+
+ byte_stream_destroy(&bs);
+}
+
/**
* Starting this past week (26 Mar 2001, say), AOL has started sending
* this nice little extra SNAC. AFAIK, it has never been used until now.
@@ -1077,7 +1024,7 @@ aim_sendmemblock(OscarData *od, FlapConnection *conn, guint32 offset, guint32 le
}
snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0020, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0020, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0020, snacid, &bs);
byte_stream_destroy(&bs);
diff --git a/libpurple/protocols/oscar/family_userlookup.c b/libpurple/protocols/oscar/family_userlookup.c
index 9f766c142d..056e43d4e4 100644
--- a/libpurple/protocols/oscar/family_userlookup.c
+++ b/libpurple/protocols/oscar/family_userlookup.c
@@ -75,7 +75,7 @@ int aim_search_address(OscarData *od, const char *address)
byte_stream_putstr(&bs, address);
snacid = aim_cachesnac(od, SNAC_FAMILY_USERLOOKUP, 0x0002, 0x0000, address, strlen(address)+1);
- flap_connection_send_snac(od, conn, SNAC_FAMILY_USERLOOKUP, 0x0002, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, SNAC_FAMILY_USERLOOKUP, 0x0002, snacid, &bs);
byte_stream_destroy(&bs);
diff --git a/libpurple/protocols/oscar/flap_connection.c b/libpurple/protocols/oscar/flap_connection.c
index 3255e0f37a..8b4dc621d4 100644
--- a/libpurple/protocols/oscar/flap_connection.c
+++ b/libpurple/protocols/oscar/flap_connection.c
@@ -212,7 +212,7 @@ static gboolean flap_connection_send_queued(gpointer data)
* only if all high priority SNACs have been sent.
*/
void
-flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data, gboolean high_priority)
+flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, aim_snacid_t snacid, ByteStream *data, gboolean high_priority)
{
FlapFrame *frame;
guint32 length;
@@ -222,7 +222,7 @@ flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, gui
length = data != NULL ? data->offset : 0;
frame = flap_frame_new(od, 0x02, 10 + length);
- aim_putsnac(&frame->data, family, subtype, flags, snacid);
+ aim_putsnac(&frame->data, family, subtype, snacid);
if (length > 0)
{
@@ -284,9 +284,9 @@ flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, gui
}
void
-flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data)
+flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, aim_snacid_t snacid, ByteStream *data)
{
- flap_connection_send_snac_with_priority(od, conn, family, subtype, flags, snacid, data, TRUE);
+ flap_connection_send_snac_with_priority(od, conn, family, subtype, snacid, data, TRUE);
}
/**
@@ -733,7 +733,7 @@ parse_snac(OscarData *od, FlapConnection *conn, FlapFrame *frame)
aim_module_t *cur;
aim_modsnac_t snac;
- if (byte_stream_empty(&frame->data) < 10)
+ if (byte_stream_bytes_left(&frame->data) < 10)
return;
snac.family = byte_stream_get16(&frame->data);
@@ -800,7 +800,7 @@ parse_flap_ch4(OscarData *od, FlapConnection *conn, FlapFrame *frame)
GSList *tlvlist;
char *msg = NULL;
- if (byte_stream_empty(&frame->data) == 0) {
+ if (byte_stream_bytes_left(&frame->data) == 0) {
/* XXX should do something with this */
return;
}
@@ -931,18 +931,6 @@ flap_connection_recv(FlapConnection *conn)
break;
}
- /* Verify the sequence number sent by the server. */
-#if 0
- /* TODO: Need to initialize conn->seqnum_in somewhere before we can use this. */
- if (aimutil_get16(&conn->header[1]) != conn->seqnum_in++)
- {
- /* Received an out-of-order FLAP! */
- flap_connection_schedule_destroy(conn,
- OSCAR_DISCONNECT_INVALID_DATA, NULL);
- break;
- }
-#endif
-
/* Initialize a new temporary FlapFrame for incoming data */
conn->buffer_incoming.channel = aimutil_get8(&conn->header[1]);
conn->buffer_incoming.seqnum = aimutil_get16(&conn->header[2]);
@@ -1074,8 +1062,8 @@ flap_connection_send_byte_stream(ByteStream *bs, FlapConnection *conn, size_t co
return;
/* Make sure we don't send past the end of the bs */
- if (count > byte_stream_empty(bs))
- count = byte_stream_empty(bs); /* truncate to remaining space */
+ if (count > byte_stream_bytes_left(bs))
+ count = byte_stream_bytes_left(bs); /* truncate to remaining space */
if (count == 0)
return;
diff --git a/libpurple/protocols/oscar/libaim.c b/libpurple/protocols/oscar/libaim.c
index 51470bc3e0..3862930728 100644
--- a/libpurple/protocols/oscar/libaim.c
+++ b/libpurple/protocols/oscar/libaim.c
@@ -25,6 +25,7 @@
*/
#include "oscarcommon.h"
+#include "oscar.h"
static PurplePluginProtocolInfo prpl_info =
{
@@ -57,7 +58,7 @@ static PurplePluginProtocolInfo prpl_info =
oscar_add_deny, /* add_deny */
oscar_rem_permit, /* rem_permit */
oscar_rem_deny, /* rem_deny */
- oscar_set_permit_deny, /* set_permit_deny */
+ oscar_set_aim_permdeny, /* set_permit_deny */
oscar_join_chat, /* join_chat */
NULL, /* reject_chat */
oscar_get_chat_name, /* get_chat_name */
diff --git a/libpurple/protocols/oscar/libicq.c b/libpurple/protocols/oscar/libicq.c
index 49069ffd02..f7bfecaa79 100644
--- a/libpurple/protocols/oscar/libicq.c
+++ b/libpurple/protocols/oscar/libicq.c
@@ -63,11 +63,11 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* add_buddies */
oscar_remove_buddy, /* remove_buddy */
NULL, /* remove_buddies */
- oscar_add_permit, /* add_permit */
+ NULL, /* add_permit */
oscar_add_deny, /* add_deny */
- oscar_rem_permit, /* rem_permit */
+ NULL, /* rem_permit */
oscar_rem_deny, /* rem_deny */
- oscar_set_permit_deny, /* set_permit_deny */
+ NULL, /* set_permit_deny */
oscar_join_chat, /* join_chat */
NULL, /* reject_chat */
oscar_get_chat_name, /* get_chat_name */
diff --git a/libpurple/protocols/oscar/misc.c b/libpurple/protocols/oscar/misc.c
index 488c035a0c..ed6b569914 100644
--- a/libpurple/protocols/oscar/misc.c
+++ b/libpurple/protocols/oscar/misc.c
@@ -41,7 +41,7 @@ aim_genericreq_n(OscarData *od, FlapConnection *conn, guint16 family, guint16 su
{
aim_snacid_t snacid = 0x00000000;
- flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
+ flap_connection_send_snac(od, conn, family, subtype, snacid, NULL);
}
void
@@ -51,7 +51,7 @@ aim_genericreq_n_snacid(OscarData *od, FlapConnection *conn, guint16 family, gui
snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
- flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, NULL);
+ flap_connection_send_snac(od, conn, family, subtype, snacid, NULL);
}
void
@@ -72,30 +72,7 @@ aim_genericreq_l(OscarData *od, FlapConnection *conn, guint16 family, guint16 su
byte_stream_put32(&bs, *longdata);
- flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, &bs);
-
- byte_stream_destroy(&bs);
-}
-
-void
-aim_genericreq_s(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint16 *shortdata)
-{
- ByteStream bs;
- aim_snacid_t snacid;
-
- if (!shortdata)
- {
- aim_genericreq_n(od, conn, family, subtype);
- return;
- }
-
- byte_stream_new(&bs, 2);
-
- snacid = aim_cachesnac(od, family, subtype, 0x0000, NULL, 0);
-
- byte_stream_put16(&bs, *shortdata);
-
- flap_connection_send_snac(od, conn, family, subtype, 0x0000, snacid, &bs);
+ flap_connection_send_snac(od, conn, family, subtype, snacid, &bs);
byte_stream_destroy(&bs);
}
@@ -114,7 +91,7 @@ generror(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *fram
snac2 = aim_remsnac(od, snac->id);
- if (byte_stream_empty(bs))
+ if (byte_stream_bytes_left(bs))
error = byte_stream_get16(bs);
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
diff --git a/libpurple/protocols/oscar/msgcookie.c b/libpurple/protocols/oscar/msgcookie.c
index d344b0991c..19a3e43aea 100644
--- a/libpurple/protocols/oscar/msgcookie.c
+++ b/libpurple/protocols/oscar/msgcookie.c
@@ -177,18 +177,3 @@ int aim_cookie_free(OscarData *od, IcbmCookie *cookie)
return 0;
}
-
-/* XXX I hate switch */
-int aim_msgcookie_gettype(guint64 type)
-{
- /* XXX: hokey-assed. needs fixed. */
- switch(type) {
- case OSCAR_CAPABILITY_BUDDYICON: return AIM_COOKIETYPE_OFTICON;
- case OSCAR_CAPABILITY_TALK: return AIM_COOKIETYPE_OFTVOICE;
- case OSCAR_CAPABILITY_DIRECTIM: return AIM_COOKIETYPE_OFTIMAGE;
- case OSCAR_CAPABILITY_CHAT: return AIM_COOKIETYPE_CHAT;
- case OSCAR_CAPABILITY_GETFILE: return AIM_COOKIETYPE_OFTGET;
- case OSCAR_CAPABILITY_SENDFILE: return AIM_COOKIETYPE_OFTSEND;
- default: return AIM_COOKIETYPE_UNKNOWN;
- }
-}
diff --git a/libpurple/protocols/oscar/odc.c b/libpurple/protocols/oscar/odc.c
index eb741b3cb2..e2a7745128 100644
--- a/libpurple/protocols/oscar/odc.c
+++ b/libpurple/protocols/oscar/odc.c
@@ -19,6 +19,7 @@
*/
/* From the oscar PRPL */
+#include "encoding.h"
#include "oscar.h"
#include "peer.h"
@@ -89,7 +90,7 @@ peer_odc_send(PeerConnection *conn, OdcFrame *frame)
ByteStream bs;
purple_debug_info("oscar", "Outgoing ODC frame to %s with "
- "type=0x%04x, flags=0x%04x, payload length=%u\n",
+ "type=0x%04x, flags=0x%04x, payload length=%" G_GSIZE_FORMAT "\n",
conn->bn, frame->type, frame->flags, frame->payload.len);
account = purple_connection_get_account(conn->od->gc);
@@ -366,8 +367,7 @@ peer_odc_handle_payload(PeerConnection *conn, const char *msg, size_t len, int e
g_datalist_clear(&attributes);
/* Append the message up to the tag */
- utf8 = purple_plugin_oscar_decode_im_part(account, conn->bn,
- encoding, 0x0000, tmp, start - tmp);
+ utf8 = oscar_decode_im(account, conn->bn, encoding, tmp, start - tmp);
if (utf8 != NULL) {
g_string_append(newmsg, utf8);
g_free(utf8);
@@ -386,8 +386,7 @@ peer_odc_handle_payload(PeerConnection *conn, const char *msg, size_t len, int e
/* Append any remaining message data */
if (tmp <= msgend)
{
- utf8 = purple_plugin_oscar_decode_im_part(account, conn->bn,
- encoding, 0x0000, tmp, msgend - tmp);
+ utf8 = oscar_decode_im(account, conn->bn, encoding, tmp, msgend - tmp);
if (utf8 != NULL) {
g_string_append(newmsg, utf8);
g_free(utf8);
@@ -506,7 +505,7 @@ peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs)
byte_stream_getrawbuf(bs, frame->bn, 32);
purple_debug_info("oscar", "Incoming ODC frame from %s with "
- "type=0x%04x, flags=0x%04x, payload length=%u\n",
+ "type=0x%04x, flags=0x%04x, payload length=%" G_GSIZE_FORMAT "\n",
frame->bn, frame->type, frame->flags, frame->payload.len);
if (!conn->ready)
diff --git a/libpurple/protocols/oscar/oft.c b/libpurple/protocols/oscar/oft.c
index 47891cebca..aa2d84b380 100644
--- a/libpurple/protocols/oscar/oft.c
+++ b/libpurple/protocols/oscar/oft.c
@@ -240,7 +240,7 @@ void
peer_oft_close(PeerConnection *conn)
{
/*
- * If canceled by local user, and we're receiving a file, and
+ * If cancelled by local user, and we're receiving a file, and
* we're not connected/ready then send an ICBM cancel message.
*/
if ((purple_xfer_get_status(conn->xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) &&
diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c
index bf62042c6a..554877e2c5 100644
--- a/libpurple/protocols/oscar/oscar.c
+++ b/libpurple/protocols/oscar/oscar.c
@@ -37,6 +37,7 @@
#include "conversation.h"
#include "core.h"
#include "debug.h"
+#include "encoding.h"
#include "imgstore.h"
#include "network.h"
#include "notify.h"
@@ -46,27 +47,12 @@
#include "request.h"
#include "util.h"
#include "version.h"
+#include "visibility.h"
#include "oscarcommon.h"
#include "oscar.h"
#include "peer.h"
-#define OSCAR_STATUS_ID_INVISIBLE "invisible"
-#define OSCAR_STATUS_ID_OFFLINE "offline"
-#define OSCAR_STATUS_ID_AVAILABLE "available"
-#define OSCAR_STATUS_ID_AWAY "away"
-#define OSCAR_STATUS_ID_DND "dnd"
-#define OSCAR_STATUS_ID_NA "na"
-#define OSCAR_STATUS_ID_OCCUPIED "occupied"
-#define OSCAR_STATUS_ID_FREE4CHAT "free4chat"
-#define OSCAR_STATUS_ID_CUSTOM "custom"
-#define OSCAR_STATUS_ID_MOBILE "mobile"
-#define OSCAR_STATUS_ID_EVIL "evil"
-#define OSCAR_STATUS_ID_DEPRESSION "depression"
-#define OSCAR_STATUS_ID_ATHOME "athome"
-#define OSCAR_STATUS_ID_ATWORK "atwork"
-#define OSCAR_STATUS_ID_LUNCH "lunch"
-
#define AIMHASHDATA "http://pidgin.im/aim_data.php3"
#define OSCAR_CONNECT_STEPS 6
@@ -82,7 +68,8 @@ static guint64 purple_caps =
| OSCAR_CAPABILITY_TYPING
| OSCAR_CAPABILITY_ICQSERVERRELAY
| OSCAR_CAPABILITY_NEWCAPS
- | OSCAR_CAPABILITY_XTRAZ;
+ | OSCAR_CAPABILITY_XTRAZ
+ | OSCAR_CAPABILITY_HTML_MSGS;
static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02};
static guint8 features_icq[] = {0x01};
@@ -99,35 +86,6 @@ struct oscar_ask_directim_data
char *who;
};
-/*
- * Various PRPL-specific buddy info that we want to keep track of
- * Some other info is maintained by locate.c, and I'd like to move
- * the rest of this to libfaim, mostly im.c
- *
- * TODO: More of this should use the status API.
- */
-struct buddyinfo {
- gboolean typingnot;
- guint32 ipaddr;
-
- unsigned long ico_me_len;
- unsigned long ico_me_csum;
- time_t ico_me_time;
- gboolean ico_informed;
-
- unsigned long ico_len;
- unsigned long ico_csum;
- time_t ico_time;
- gboolean ico_need;
- gboolean ico_sent;
-};
-
-struct name_data {
- PurpleConnection *gc;
- gchar *name;
- gchar *nick;
-};
-
/* All the libfaim->purple callback functions */
/* Only used when connecting with the old-style BUCP login */
@@ -143,7 +101,6 @@ static int purple_parse_offgoing (OscarData *, FlapConnection *, FlapFrame *,
static int purple_parse_incoming_im(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_userinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -152,8 +109,6 @@ static int purple_conv_chat_info_update (OscarData *, FlapConnection *, FlapFram
static int purple_conv_chat_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_icon_parseicon (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_msgack (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_bosrights (OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -161,16 +116,9 @@ static int purple_connerr (OscarData *, FlapConnection *, FlapFrame *,
static int purple_parse_mtn (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_locaterights(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_locerr (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_memrequest (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_selfinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
-static int purple_offlinemsg (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_offlinemsgdone (OscarData *, FlapConnection *, FlapFrame *, ...);
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
-static int purple_icqalias (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_icqinfo (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_popup (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_ssi_parseerr (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_ssi_parserights (OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -186,10 +134,10 @@ static void purple_icons_fetch(PurpleConnection *gc);
void oscar_set_info(PurpleConnection *gc, const char *info);
static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status);
-static void oscar_set_extendedstatus(PurpleConnection *gc);
+static void oscar_set_extended_status(PurpleConnection *gc);
static gboolean purple_ssi_rerequestdata(gpointer data);
-static void oscar_free_name_data(struct name_data *data) {
+void oscar_free_name_data(struct name_data *data) {
g_free(data->name);
g_free(data->nick);
g_free(data);
@@ -204,536 +152,6 @@ const char *oscar_get_locale_charset(void) {
}
#endif
-/**
- * Determine how we can send this message. Per the warnings elsewhere
- * in this file, these little checks determine the simplest encoding
- * we can use for a given message send using it.
- */
-static guint32
-oscar_charset_check(const char *utf8)
-{
- int i = 0;
- int charset = AIM_CHARSET_ASCII;
-
- /*
- * Can we get away with using our custom encoding?
- */
- while (utf8[i])
- {
- if ((unsigned char)utf8[i] > 0x7f) {
- /* not ASCII! */
- charset = AIM_CHARSET_LATIN_1;
- break;
- }
- i++;
- }
-
- /*
- * Must we send this message as UNICODE (in the UTF-16BE encoding)?
- */
- while (utf8[i])
- {
- /* ISO-8859-1 is 0x00-0xbf in the first byte
- * followed by 0xc0-0xc3 in the second */
- if ((unsigned char)utf8[i] < 0x80) {
- i++;
- continue;
- } else if (((unsigned char)utf8[i] & 0xfc) == 0xc0 &&
- ((unsigned char)utf8[i + 1] & 0xc0) == 0x80) {
- i += 2;
- continue;
- }
- charset = AIM_CHARSET_UNICODE;
- break;
- }
-
- return charset;
-}
-
-/**
- * Take a string of the form charset="bleh" where bleh is
- * one of us-ascii, utf-8, iso-8859-1, or unicode-2-0, and
- * return a newly allocated string containing bleh.
- */
-gchar *
-oscar_encoding_extract(const char *encoding)
-{
- gchar *ret = NULL;
- char *begin, *end;
-
- g_return_val_if_fail(encoding != NULL, NULL);
-
- /* Make sure encoding begins with charset= */
- if (strncmp(encoding, "text/aolrtf; charset=", 21) &&
- strncmp(encoding, "text/x-aolrtf; charset=", 23) &&
- strncmp(encoding, "text/plain; charset=", 20))
- {
- return NULL;
- }
-
- begin = strchr(encoding, '"');
- end = strrchr(encoding, '"');
-
- if ((begin == NULL) || (end == NULL) || (begin >= end))
- return NULL;
-
- ret = g_strndup(begin+1, (end-1) - begin);
-
- return ret;
-}
-
-gchar *
-oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen)
-{
- gchar *utf8 = NULL;
-
- if ((encoding == NULL) || encoding[0] == '\0') {
- purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");
- } else if (!g_ascii_strcasecmp(encoding, "iso-8859-1")) {
- utf8 = g_convert(text, textlen, "UTF-8", "iso-8859-1", NULL, NULL, NULL);
- } else if (!g_ascii_strcasecmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1") ||
- !g_ascii_strcasecmp(encoding, "us-ascii"))
- {
- utf8 = g_convert(text, textlen, "UTF-8", "Windows-1252", NULL, NULL, NULL);
- } else if (!g_ascii_strcasecmp(encoding, "unicode-2-0")) {
- /* Some official ICQ clients are apparently total crack,
- * and have been known to save a UTF-8 string converted
- * from the locale character set to UTF-16 (not from UTF-8
- * to UTF-16!) in the away message. This hack should find
- * and do something (un)reasonable with that, and not
- * mess up too much else. */
- const gchar *charset = purple_account_get_string(account, "encoding", NULL);
- if (charset) {
- gsize len;
- utf8 = g_convert(text, textlen, charset, "UTF-16BE", &len, NULL, NULL);
- if (!utf8 || len != textlen || !g_utf8_validate(utf8, -1, NULL)) {
- g_free(utf8);
- utf8 = NULL;
- } else {
- purple_debug_info("oscar", "Used broken ICQ fallback encoding\n");
- }
- }
- if (!utf8)
- utf8 = g_convert(text, textlen, "UTF-8", "UTF-16BE", NULL, NULL, NULL);
- } else if (g_ascii_strcasecmp(encoding, "utf-8")) {
- purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", "
- "attempting to convert to UTF-8 anyway\n", encoding);
- utf8 = g_convert(text, textlen, "UTF-8", encoding, NULL, NULL, NULL);
- }
-
- /*
- * If utf8 is still NULL then either the encoding is utf-8 or
- * we have been unable to convert the text to utf-8 from the encoding
- * that was specified. So we check if the text is valid utf-8 then
- * just copy it.
- */
- if (utf8 == NULL) {
- if (textlen != 0 && *text != '\0'
- && !g_utf8_validate(text, textlen, NULL))
- utf8 = g_strdup(_("(There was an error receiving this message. The buddy you are speaking with is probably using a different encoding than expected. If you know what encoding he is using, you can specify it in the advanced account options for your AIM/ICQ account.)"));
- else
- utf8 = g_strndup(text, textlen);
- }
-
- return utf8;
-}
-
-static gchar *
-oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg)
-{
- const char *charset = NULL;
- char *ret = NULL;
-
- if (od->icq)
- charset = purple_account_get_string(account, "encoding", NULL);
-
- if(charset && *charset)
- ret = g_convert(msg, -1, "UTF-8", charset, NULL, NULL, NULL);
-
- if(!ret)
- ret = purple_utf8_try_convert(msg);
-
- return ret;
-}
-
-static gchar *
-purple_plugin_oscar_convert_to_utf8(const gchar *data, gsize datalen, const char *charsetstr, gboolean fallback)
-{
- gchar *ret = NULL;
- GError *err = NULL;
-
- if ((charsetstr == NULL) || (*charsetstr == '\0'))
- return NULL;
-
- if (g_ascii_strcasecmp("UTF-8", charsetstr)) {
- if (fallback)
- ret = g_convert_with_fallback(data, datalen, "UTF-8", charsetstr, "?", NULL, NULL, &err);
- else
- ret = g_convert(data, datalen, "UTF-8", charsetstr, NULL, NULL, &err);
- if (err != NULL) {
- purple_debug_warning("oscar", "Conversion from %s failed: %s.\n",
- charsetstr, err->message);
- g_error_free(err);
- }
- } else {
- if (g_utf8_validate(data, datalen, NULL))
- ret = g_strndup(data, datalen);
- else
- purple_debug_warning("oscar", "String is not valid UTF-8.\n");
- }
-
- return ret;
-}
-
-/**
- * This attemps to decode an incoming IM into a UTF8 string.
- *
- * We try decoding using two different character sets. The charset
- * specified in the IM determines the order in which we attempt to
- * decode. We do this because there are lots of broken ICQ clients
- * that don't correctly send non-ASCII messages. And if Purple isn't
- * able to deal with that crap, then people complain like banshees.
- * charsetstr1 is always set to what the correct encoding should be.
- */
-gchar *
-purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcebn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen)
-{
- gchar *ret = NULL;
- const gchar *charsetstr1, *charsetstr2, *charsetstr3 = NULL;
-
- if ((datalen == 0) || (data == NULL))
- return NULL;
-
- if (charset == AIM_CHARSET_UNICODE) {
- charsetstr1 = "UTF-16BE";
- charsetstr2 = "UTF-8";
- } else if (charset == AIM_CHARSET_LATIN_1) {
- if ((sourcebn != NULL) && oscar_util_valid_name_icq(sourcebn))
- charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
- else
- charsetstr1 = "ISO-8859-1";
- charsetstr2 = "UTF-8";
- } else if (charset == AIM_CHARSET_ASCII) {
- /* Should just be "ASCII" */
- charsetstr1 = "ASCII";
- charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
- } else if (charset == 0x000d) {
- /* iChat sending unicode over a Direct IM connection = UTF-8 */
- /* Mobile AIM client on multiple devices (including Blackberry Tour, Nokia 3100, and LG VX6000) = ISO-8859-1 */
- charsetstr1 = "UTF-8";
- charsetstr2 = "ISO-8859-1";
- charsetstr3 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
- } else {
- /* Unknown, hope for valid UTF-8... */
- charsetstr1 = "UTF-8";
- charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
- }
-
- purple_debug_info("oscar", "Parsing IM part, charset=0x%04hx, charsubset=0x%04hx, datalen=%" G_GSIZE_FORMAT ", choice1=%s, choice2=%s, choice3=%s\n",
- charset, charsubset, datalen, charsetstr1, charsetstr2, (charsetstr3 ? charsetstr3 : ""));
-
- ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr1, FALSE);
- if (ret == NULL) {
- if (charsetstr3 != NULL) {
- /* Try charsetstr2 without allowing substitutions, then fall through to charsetstr3 if needed */
- ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr2, FALSE);
- if (ret == NULL)
- ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr3, TRUE);
- } else {
- /* Try charsetstr2, allowing substitutions */
- ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr2, TRUE);
- }
- }
- if (ret == NULL) {
- char *str, *salvage, *tmp;
-
- str = g_malloc(datalen + 1);
- strncpy(str, data, datalen);
- str[datalen] = '\0';
- salvage = purple_utf8_salvage(str);
- tmp = g_strdup_printf(_("(There was an error receiving this message. Either you and %s have different encodings selected, or %s has a buggy client.)"),
- sourcebn, sourcebn);
- ret = g_strdup_printf("%s %s", salvage, tmp);
- g_free(tmp);
- g_free(str);
- g_free(salvage);
- }
-
- return ret;
-}
-
-/**
- * Figure out what encoding to use when sending a given outgoing message.
- */
-static void
-purple_plugin_oscar_convert_to_best_encoding(PurpleConnection *gc,
- const char *destbn, const gchar *from,
- gchar **msg, int *msglen_int,
- guint16 *charset, guint16 *charsubset)
-{
- OscarData *od = purple_connection_get_protocol_data(gc);
- PurpleAccount *account = purple_connection_get_account(gc);
- GError *err = NULL;
- aim_userinfo_t *userinfo = NULL;
- const gchar *charsetstr;
- gsize msglen;
-
- /* Attempt to send as ASCII */
- if (oscar_charset_check(from) == AIM_CHARSET_ASCII) {
- *msg = g_convert(from, -1, "ASCII", "UTF-8", NULL, &msglen, NULL);
- *charset = AIM_CHARSET_ASCII;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- /*
- * If we're sending to an ICQ user, and they are in our
- * buddy list, and they are advertising the Unicode
- * capability, and they are online, then attempt to send
- * as UTF-16BE.
- */
- if ((destbn != NULL) && oscar_util_valid_name_icq(destbn))
- userinfo = aim_locate_finduserinfo(od, destbn);
-
- if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE))
- {
- PurpleBuddy *b;
- b = purple_find_buddy(account, destbn);
- if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b)))
- {
- *msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL)
- {
- *charset = AIM_CHARSET_UNICODE;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_error("oscar", "Conversion from UTF-8 to UTF-16BE failed: %s.\n",
- err->message);
- g_error_free(err);
- err = NULL;
- }
- }
-
- /*
- * If this is AIM then attempt to send as ISO-8859-1. If this is
- * ICQ then attempt to send as the user specified character encoding.
- */
- charsetstr = "ISO-8859-1";
- if ((destbn != NULL) && oscar_util_valid_name_icq(destbn))
- charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
-
- /*
- * XXX - We need a way to only attempt to convert if we KNOW "from"
- * can be converted to "charsetstr"
- */
- *msg = g_convert(from, -1, charsetstr, "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL) {
- *charset = AIM_CHARSET_LATIN_1;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_info("oscar", "Conversion from UTF-8 to %s failed (%s). Falling back to unicode.\n",
- charsetstr, err->message);
- g_error_free(err);
- err = NULL;
-
- /*
- * Nothing else worked, so send as UTF-16BE.
- */
- *msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL) {
- *charset = AIM_CHARSET_UNICODE;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_error("oscar", "Error converting a Unicode message: %s\n", err->message);
- g_error_free(err);
- err = NULL;
-
- purple_debug_error("oscar", "This should NEVER happen! Sending UTF-8 text flagged as ASCII.\n");
- *msg = g_strdup(from);
- *msglen_int = strlen(*msg);
- *charset = AIM_CHARSET_ASCII;
- *charsubset = 0x0000;
- return;
-}
-
-/**
- * Looks for %n, %d, or %t in a string, and replaces them with the
- * specified name, date, and time, respectively.
- *
- * @param str The string that may contain the special variables.
- * @param name The sender name.
- *
- * @return A newly allocated string where the special variables are
- * expanded. This should be g_free'd by the caller.
- */
-static gchar *
-purple_str_sub_away_formatters(const char *str, const char *name)
-{
- char *c;
- GString *cpy;
- time_t t;
- struct tm *tme;
-
- g_return_val_if_fail(str != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- /* Create an empty GString that is hopefully big enough for most messages */
- cpy = g_string_sized_new(1024);
-
- t = time(NULL);
- tme = localtime(&t);
-
- c = (char *)str;
- while (*c) {
- switch (*c) {
- case '%':
- if (*(c + 1)) {
- switch (*(c + 1)) {
- case 'n':
- /* append name */
- g_string_append(cpy, name);
- c++;
- break;
- case 'd':
- /* append date */
- g_string_append(cpy, purple_date_format_short(tme));
- c++;
- break;
- case 't':
- /* append time */
- g_string_append(cpy, purple_time_format(tme));
- c++;
- break;
- default:
- g_string_append_c(cpy, *c);
- }
- } else {
- g_string_append_c(cpy, *c);
- }
- break;
- default:
- g_string_append_c(cpy, *c);
- }
- c++;
- }
-
- return g_string_free(cpy, FALSE);
-}
-
-static gchar *oscar_caps_to_string(guint64 caps)
-{
- GString *str;
- const gchar *tmp;
- guint64 bit = 1;
-
- str = g_string_new("");
-
- if (!caps) {
- return NULL;
- } else while (bit <= OSCAR_CAPABILITY_LAST) {
- if (bit & caps) {
- switch (bit) {
- case OSCAR_CAPABILITY_BUDDYICON:
- tmp = _("Buddy Icon");
- break;
- case OSCAR_CAPABILITY_TALK:
- tmp = _("Voice");
- break;
- case OSCAR_CAPABILITY_DIRECTIM:
- tmp = _("AIM Direct IM");
- break;
- case OSCAR_CAPABILITY_CHAT:
- tmp = _("Chat");
- break;
- case OSCAR_CAPABILITY_GETFILE:
- tmp = _("Get File");
- break;
- case OSCAR_CAPABILITY_SENDFILE:
- tmp = _("Send File");
- break;
- case OSCAR_CAPABILITY_GAMES:
- case OSCAR_CAPABILITY_GAMES2:
- tmp = _("Games");
- break;
- case OSCAR_CAPABILITY_XTRAZ:
- case OSCAR_CAPABILITY_NEWCAPS:
- tmp = _("ICQ Xtraz");
- break;
- case OSCAR_CAPABILITY_ADDINS:
- tmp = _("Add-Ins");
- break;
- case OSCAR_CAPABILITY_SENDBUDDYLIST:
- tmp = _("Send Buddy List");
- break;
- case OSCAR_CAPABILITY_ICQ_DIRECT:
- tmp = _("ICQ Direct Connect");
- break;
- case OSCAR_CAPABILITY_APINFO:
- tmp = _("AP User");
- break;
- case OSCAR_CAPABILITY_ICQRTF:
- tmp = _("ICQ RTF");
- break;
- case OSCAR_CAPABILITY_EMPTY:
- tmp = _("Nihilist");
- break;
- case OSCAR_CAPABILITY_ICQSERVERRELAY:
- tmp = _("ICQ Server Relay");
- break;
- case OSCAR_CAPABILITY_UNICODEOLD:
- tmp = _("Old ICQ UTF8");
- break;
- case OSCAR_CAPABILITY_TRILLIANCRYPT:
- tmp = _("Trillian Encryption");
- break;
- case OSCAR_CAPABILITY_UNICODE:
- tmp = _("ICQ UTF8");
- break;
- case OSCAR_CAPABILITY_HIPTOP:
- tmp = _("Hiptop");
- break;
- case OSCAR_CAPABILITY_SECUREIM:
- tmp = _("Security Enabled");
- break;
- case OSCAR_CAPABILITY_VIDEO:
- tmp = _("Video Chat");
- break;
- /* Not actually sure about this one... WinAIM doesn't show anything */
- case OSCAR_CAPABILITY_ICHATAV:
- tmp = _("iChat AV");
- break;
- case OSCAR_CAPABILITY_LIVEVIDEO:
- tmp = _("Live Video");
- break;
- case OSCAR_CAPABILITY_CAMERA:
- tmp = _("Camera");
- break;
- case OSCAR_CAPABILITY_ICHAT_SCREENSHARE:
- tmp = _("Screen Sharing");
- break;
- default:
- tmp = NULL;
- break;
- }
- if (tmp)
- g_string_append_printf(str, "%s%s", (*(str->str) == '\0' ? "" : ", "), tmp);
- }
- bit <<= 1;
- }
-
- return g_string_free(str, FALSE);
-}
-
static char *oscar_icqstatus(int state) {
/* Make a cute little string that shows the status of the dude or dudet */
if (state & AIM_ICQ_STATE_CHAT)
@@ -764,255 +182,6 @@ static char *oscar_icqstatus(int state) {
return g_strdup(_("Online"));
}
-static void
-oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value)
-{
- if (value && value[0]) {
- purple_notify_user_info_add_pair(user_info, name, value);
- }
-}
-
-static void
-oscar_user_info_convert_and_add_pair(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
- const char *name, const char *value)
-{
- gchar *utf8;
-
- if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
- purple_notify_user_info_add_pair(user_info, name, utf8);
- g_free(utf8);
- }
-}
-
-static void
-oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
- const char *name, const char *value)
-{
- gchar *utf8;
-
- if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
- purple_notify_user_info_add_pair(user_info, name, utf8);
- g_free(utf8);
- }
-}
-
-/**
- * @brief Append the status information to a user_info struct
- *
- * The returned information is HTML-ready, appropriately escaped, as all information in a user_info struct should be HTML.
- *
- * @param gc The PurpleConnection
- * @param user_info A PurpleNotifyUserInfo object to which status information will be added
- * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status().
- * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status().
- * @param strip_html_tags If strip_html_tags is TRUE, tags embedded in the status message will be stripped, returning a non-formatted string. The string will still be HTML escaped.
- */
-static void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags)
-{
- PurpleAccount *account = purple_connection_get_account(gc);
- OscarData *od;
- PurplePresence *presence = NULL;
- PurpleStatus *status = NULL;
- gchar *message = NULL, *itmsurl = NULL, *tmp;
- gboolean is_away;
-
- od = purple_connection_get_protocol_data(gc);
-
- if (b == NULL && userinfo == NULL)
- return;
-
- if (b == NULL)
- b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn);
- else
- userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
-
- if (b) {
- presence = purple_buddy_get_presence(b);
- status = purple_presence_get_active_status(presence);
- }
-
- /* If we have both b and userinfo we favor userinfo, because if we're
- viewing someone's profile then we want the HTML away message, and
- the "message" attribute of the status contains only the plaintext
- message. */
- if (userinfo) {
- if ((userinfo->flags & AIM_FLAG_AWAY)
- && userinfo->away_len > 0
- && userinfo->away != NULL
- && userinfo->away_encoding != NULL)
- {
- /* Away message */
- tmp = oscar_encoding_extract(userinfo->away_encoding);
- message = oscar_encoding_to_utf8(account,
- tmp, userinfo->away, userinfo->away_len);
- g_free(tmp);
- } else {
- /*
- * Available message or non-HTML away message (because that's
- * all we have right now.
- */
- if ((userinfo->status != NULL) && userinfo->status[0] != '\0') {
- message = oscar_encoding_to_utf8(account,
- userinfo->status_encoding, userinfo->status,
- userinfo->status_len);
- }
-#if defined (_WIN32) || defined (__APPLE__)
- if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0'))
- itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding,
- userinfo->itmsurl, userinfo->itmsurl_len);
-#endif
- }
- } else {
- message = g_strdup(purple_status_get_attr_string(status, "message"));
- itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
- }
-
- is_away = ((status && !purple_status_is_available(status)) ||
- (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
-
- if (strip_html_tags) {
- /* Away messages are HTML, but available messages were originally plain text.
- * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags.
- */
- /*
- * It seems like the above comment no longer applies. All messages need
- * to be escaped.
- */
- if (message) {
- gchar *tmp2;
- tmp = purple_markup_strip_html(message);
- g_free(message);
- tmp2 = g_markup_escape_text(tmp, -1);
- g_free(tmp);
- message = tmp2;
- }
-
- } else {
- if (itmsurl) {
- tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
- itmsurl, message);
- g_free(message);
- message = tmp;
- }
- }
- g_free(itmsurl);
-
- if (message) {
- tmp = purple_str_sub_away_formatters(message, purple_account_get_username(account));
- g_free(message);
- message = tmp;
- }
-
- if (b) {
- if (purple_presence_is_online(presence)) {
- if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) {
- /* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
- * If the status name and the message are the same, only show one. */
- const char *status_name = purple_status_get_name(status);
- if (status_name && message && !strcmp(status_name, message))
- status_name = NULL;
-
- tmp = g_strdup_printf("%s%s%s",
- status_name ? status_name : "",
- ((status_name && message) && *message) ? ": " : "",
- (message && *message) ? message : "");
- g_free(message);
- message = tmp;
- }
-
- } else if (aim_ssi_waitingforauth(od->ssi.local,
- aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
- purple_buddy_get_name(b)))
- {
- /* Note if an offline buddy is not authorized */
- tmp = g_strdup_printf("%s%s%s",
- _("Not Authorized"),
- (message && *message) ? ": " : "",
- (message && *message) ? message : "");
- g_free(message);
- message = tmp;
- } else {
- g_free(message);
- message = g_strdup(_("Offline"));
- }
- }
-
- if (presence) {
- const char *mood;
- const char *description;
- status = purple_presence_get_status(presence, "mood");
- mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
- description = icq_get_custom_icon_description(mood);
- if (description && *description)
- purple_notify_user_info_add_pair(user_info, _("Mood"), _(description));
- }
-
- purple_notify_user_info_add_pair(user_info, _("Status"), message);
- g_free(message);
-}
-
-static void oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
-{
- OscarData *od;
- PurpleAccount *account;
- PurplePresence *presence = NULL;
- PurpleStatus *status = NULL;
- PurpleGroup *g = NULL;
- struct buddyinfo *bi = NULL;
- char *tmp;
- const char *bname = NULL, *gname = NULL;
-
- od = purple_connection_get_protocol_data(gc);
- account = purple_connection_get_account(gc);
-
- if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL)))
- return;
-
- if (userinfo == NULL)
- userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
-
- if (b == NULL)
- b = purple_find_buddy(account, userinfo->bn);
-
- if (b != NULL) {
- bname = purple_buddy_get_name(b);
- g = purple_buddy_get_group(b);
- gname = purple_group_get_name(g);
- presence = purple_buddy_get_presence(b);
- status = purple_presence_get_active_status(presence);
- }
-
- if (userinfo != NULL)
- bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
-
- if ((bi != NULL) && (bi->ipaddr != 0)) {
- tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
- (bi->ipaddr & 0xff000000) >> 24,
- (bi->ipaddr & 0x00ff0000) >> 16,
- (bi->ipaddr & 0x0000ff00) >> 8,
- (bi->ipaddr & 0x000000ff));
- oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
- g_free(tmp);
- }
-
- if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
- tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
- oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
- g_free(tmp);
- }
-
- if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) {
- tmp = aim_ssi_getcomment(od->ssi.local, gname, bname);
- if (tmp != NULL) {
- char *tmp2 = g_markup_escape_text(tmp, strlen(tmp));
- g_free(tmp);
-
- oscar_user_info_convert_and_add_pair(account, od, user_info, _("Buddy Comment"), tmp2);
- g_free(tmp2);
- }
- }
-}
-
static char *extract_name(const char *name) {
char *tmp, *x;
int i, j;
@@ -1496,22 +665,12 @@ oscar_login(PurpleAccount *account)
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0);
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0);
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0);
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
- oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSG, purple_offlinemsg, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSGCOMPLETE, purple_offlinemsgdone, 0);
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
- oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_ALIAS, purple_icqalias, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_INFO, purple_icqinfo, 0);
oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_RIGHTSINFO, purple_parse_locaterights, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_USERINFO, purple_parse_userinfo, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_ERROR, purple_parse_locerr, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0001, purple_parse_genericerr, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x001f, purple_memrequest, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_REDIRECT, purple_handle_redirect, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_MOTD, purple_parse_motd, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, SNAC_SUBTYPE_OSERVICE_EVIL, purple_parse_evilnotify, 0);
oscar_data_addhandler(od, SNAC_FAMILY_POPUP, 0x0002, purple_popup, 0);
oscar_data_addhandler(od, SNAC_FAMILY_USERLOOKUP, SNAC_SUBTYPE_USERLOOKUP_ERROR, purple_parse_searcherror, 0);
oscar_data_addhandler(od, SNAC_FAMILY_USERLOOKUP, 0x0003, purple_parse_searchreply, 0);
@@ -1771,34 +930,6 @@ static int purple_memrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr,
AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
return 1;
}
- /* uncomment this when you're convinced it's right. remember, it's been wrong before. */
-#if 0
- if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) {
- char *buf;
- int i = 8;
- if (modname)
- i += strlen(modname);
- buf = g_malloc(i);
- i = 0;
- if (modname) {
- memcpy(buf, modname, strlen(modname));
- i += strlen(modname);
- }
- buf[i++] = offset & 0xff;
- buf[i++] = (offset >> 8) & 0xff;
- buf[i++] = (offset >> 16) & 0xff;
- buf[i++] = (offset >> 24) & 0xff;
- buf[i++] = len & 0xff;
- buf[i++] = (len >> 8) & 0xff;
- buf[i++] = (len >> 16) & 0xff;
- buf[i++] = (len >> 24) & 0xff;
- purple_debug_misc("oscar", "len + offset is invalid, "
- "hashing request\n");
- aim_sendmemblock(od, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
- g_free(buf);
- return 1;
- }
-#endif
pos = g_new0(struct pieceofcrap, 1);
pos->gc = od->gc;
@@ -2253,18 +1384,18 @@ static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame
purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE);
}
- if (info->status != NULL && info->status[0] != '\0')
+ if (info->status != NULL && info->status[0] != '\0') {
/* Grab the available message */
- message = oscar_encoding_to_utf8(account, info->status_encoding,
- info->status, info->status_len);
+ message = oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len);
+ }
tmp2 = tmp = (message ? purple_markup_escape_text(message, -1) : NULL);
if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) {
- if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len)
+ if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) {
/* Grab the iTunes Music Store URL */
- itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding,
- info->itmsurl, info->itmsurl_len);
+ itmsurl = oscar_encoding_to_utf8(info->itmsurl_encoding, info->itmsurl, info->itmsurl_len);
+ }
if (tmp2 == NULL && itmsurl != NULL)
/*
@@ -2370,17 +1501,11 @@ static int incomingim_chan1(OscarData *od, FlapConnection *conn, aim_userinfo_t
PurpleMessageFlags flags = 0;
struct buddyinfo *bi;
PurpleStoredImage *img;
- GString *message;
gchar *tmp;
- aim_mpmsg_section_t *curpart;
const char *start, *end;
GData *attribs;
- purple_debug_misc("oscar", "Received IM from %s with %d parts\n",
- userinfo->bn, args->mpmsg.numparts);
-
- if (args->mpmsg.numparts == 0)
- return 1;
+ purple_debug_misc("oscar", "Received IM from %s\n", userinfo->bn);
bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
if (!bi) {
@@ -2420,19 +1545,7 @@ static int incomingim_chan1(OscarData *od, FlapConnection *conn, aim_userinfo_t
}
purple_imgstore_unref(img);
- message = g_string_new("");
- curpart = args->mpmsg.parts;
- while (curpart != NULL) {
- tmp = purple_plugin_oscar_decode_im_part(account, userinfo->bn, curpart->charset,
- curpart->charsubset, curpart->data, curpart->datalen);
- if (tmp != NULL) {
- g_string_append(message, tmp);
- g_free(tmp);
- }
-
- curpart = curpart->next;
- }
- tmp = g_string_free(message, FALSE);
+ tmp = g_strdup(args->msg);
/*
* Convert iChat color tags to normal font tags.
@@ -2516,8 +1629,7 @@ static int incomingim_chan1(OscarData *od, FlapConnection *conn, aim_userinfo_t
tmp = tmp2;
}
- serv_got_im(gc, userinfo->bn, tmp, flags,
- (args->icbmflags & AIM_IMFLAGS_OFFLINE) ? args->timestamp : time(NULL));
+ serv_got_im(gc, userinfo->bn, tmp, flags, (args->icbmflags & AIM_IMFLAGS_OFFLINE) ? args->timestamp : time(NULL));
g_free(tmp);
return 1;
@@ -2545,35 +1657,20 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
G_GUINT64_FORMAT ", user %s, status %hu\n",
args->type, userinfo->bn, args->status);
- if (args->msg != NULL)
- {
- if (args->encoding != NULL)
- {
- char *encoding = NULL;
- encoding = oscar_encoding_extract(args->encoding);
- message = oscar_encoding_to_utf8(account, encoding, args->msg,
- args->msglen);
- g_free(encoding);
- } else {
- if (g_utf8_validate(args->msg, args->msglen, NULL))
- message = g_strdup(args->msg);
- }
+ if (args->msg != NULL) {
+ message = oscar_encoding_to_utf8(args->encoding, args->msg, args->msglen);
}
if (args->type & OSCAR_CAPABILITY_CHAT)
{
- char *encoding, *utf8name, *tmp;
+ char *utf8name, *tmp;
GHashTable *components;
if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange) {
g_free(message);
return 1;
}
- encoding = args->encoding ? oscar_encoding_extract(args->encoding) : NULL;
- utf8name = oscar_encoding_to_utf8(account, encoding,
- args->info.chat.roominfo.name,
- args->info.chat.roominfo.namelen);
- g_free(encoding);
+ utf8name = oscar_encoding_to_utf8(args->encoding, args->info.chat.roominfo.name, args->info.chat.roominfo.namelen);
tmp = extract_name(utf8name);
if (tmp != NULL)
@@ -2594,8 +1691,7 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
components);
}
- else if ((args->type & OSCAR_CAPABILITY_SENDFILE) ||
- (args->type & OSCAR_CAPABILITY_DIRECTIM))
+ else if ((args->type & OSCAR_CAPABILITY_SENDFILE) || (args->type & OSCAR_CAPABILITY_DIRECTIM))
{
if (args->status == AIM_RENDEZVOUS_PROPOSE)
{
@@ -2603,7 +1699,7 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
}
else if (args->status == AIM_RENDEZVOUS_CANCEL)
{
- /* The other user canceled a peer request */
+ /* The other user cancelled a peer request */
PeerConnection *conn;
conn = peer_connection_find_by_cookie(od, userinfo->bn, args->cookie);
@@ -2648,24 +1744,22 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
purple_debug_info("oscar", "Got an ICQ Server Relay message of "
"type %d\n", args->info.rtfmsg.msgtype);
- if (args->info.rtfmsg.msgtype == 1)
- {
- if (args->info.rtfmsg.rtfmsg != NULL)
- {
- char *rtfmsg = NULL;
- if (args->encoding != NULL) {
- char *encoding = oscar_encoding_extract(args->encoding);
- rtfmsg = oscar_encoding_to_utf8(account, encoding,
- args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg));
- g_free(encoding);
- } else {
- if (g_utf8_validate(args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg), NULL))
- rtfmsg = g_strdup(args->info.rtfmsg.rtfmsg);
- }
- if (rtfmsg) {
- serv_got_im(gc, userinfo->bn, rtfmsg, flags, time(NULL));
- g_free(rtfmsg);
- }
+ if (args->info.rtfmsg.msgtype == 1) {
+ if (args->info.rtfmsg.msg != NULL) {
+ char *rtfmsg = oscar_encoding_to_utf8(args->encoding, args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg));
+ char *tmp, *tmp2;
+
+ /* Channel 2 messages are supposed to be plain-text (never mind the name "rtfmsg", even
+ * the official client doesn't parse them as RTF). Therefore, we should escape them before
+ * showing to the user. */
+ tmp = g_markup_escape_text(rtfmsg, -1);
+ g_free(rtfmsg);
+ tmp2 = purple_strreplace(tmp, "\r\n", "<br>");
+ g_free(tmp);
+
+ serv_got_im(gc, userinfo->bn, tmp2, flags, time(NULL));
+ aim_im_send_icq_confirmation(od, userinfo->bn, args->cookie);
+ g_free(tmp2);
}
} else if (args->info.rtfmsg.msgtype == 26) {
purple_debug_info("oscar", "Sending X-Status Reply\n");
@@ -2683,122 +1777,6 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
return 1;
}
-/*
- * Authorization Functions
- * Most of these are callbacks from dialogs. They're used by both
- * methods of authorization (SSI and old-school channel 4 ICBM)
- */
-/* When you ask other people for authorization */
-static void
-purple_auth_request(struct name_data *data, char *msg)
-{
- PurpleConnection *gc;
- OscarData *od;
- PurpleAccount *account;
- PurpleBuddy *buddy;
- PurpleGroup *group;
- const char *bname, *gname;
-
- gc = data->gc;
- od = purple_connection_get_protocol_data(gc);
- account = purple_connection_get_account(gc);
- buddy = purple_find_buddy(account, data->name);
- if (buddy != NULL)
- group = purple_buddy_get_group(buddy);
- else
- group = NULL;
-
- if (group != NULL)
- {
- bname = purple_buddy_get_name(buddy);
- gname = purple_group_get_name(group);
- purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
- bname, gname);
- aim_ssi_sendauthrequest(od, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
- if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
- {
- aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);
-
- /* Mobile users should always be online */
- if (bname[0] == '+') {
- purple_prpl_got_user_status(account,
- purple_buddy_get_name(buddy),
- OSCAR_STATUS_ID_AVAILABLE, NULL);
- purple_prpl_got_user_status(account,
- purple_buddy_get_name(buddy),
- OSCAR_STATUS_ID_MOBILE, NULL);
- }
- }
- }
-
- oscar_free_name_data(data);
-}
-
-static void
-purple_auth_sendrequest(PurpleConnection *gc, const char *name)
-{
- struct name_data *data;
-
- data = g_new0(struct name_data, 1);
- data->gc = gc;
- data->name = g_strdup(name);
-
- purple_request_input(data->gc, NULL, _("Authorization Request Message:"),
- NULL, _("Please authorize me!"), TRUE, FALSE, NULL,
- _("_OK"), G_CALLBACK(purple_auth_request),
- _("_Cancel"), G_CALLBACK(oscar_free_name_data),
- purple_connection_get_account(gc), name, NULL,
- data);
-}
-
-static void
-purple_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = (PurpleBuddy *) node;
- gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- purple_auth_sendrequest(gc, purple_buddy_get_name(buddy));
-}
-
-/* When other people ask you for authorization */
-static void
-purple_auth_grant(gpointer cbdata)
-{
- struct name_data *data = cbdata;
- PurpleConnection *gc = data->gc;
- OscarData *od = purple_connection_get_protocol_data(gc);
-
- aim_ssi_sendauthreply(od, data->name, 0x01, NULL);
-
- oscar_free_name_data(data);
-}
-
-/* When other people ask you for authorization */
-static void
-purple_auth_dontgrant(struct name_data *data, char *msg)
-{
- PurpleConnection *gc = data->gc;
- OscarData *od = purple_connection_get_protocol_data(gc);
-
- aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given."));
-}
-
-static void
-purple_auth_dontgrant_msgprompt(gpointer cbdata)
-{
- struct name_data *data = cbdata;
- purple_request_input(data->gc, NULL, _("Authorization Denied Message:"),
- NULL, _("No reason given."), TRUE, FALSE, NULL,
- _("_OK"), G_CALLBACK(purple_auth_dontgrant),
- _("_Cancel"), G_CALLBACK(oscar_free_name_data),
- purple_connection_get_account(data->gc), data->name, NULL,
- data);
-}
-
/* When someone sends you buddies */
static void
purple_icq_buddyadd(struct name_data *data)
@@ -2842,7 +1820,7 @@ incomingim_chan4(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
purple_str_strip_char(msg1[i], '\r');
/* TODO: Should use an encoding other than ASCII? */
- msg2[i] = purple_plugin_oscar_decode_im_part(account, uin, AIM_CHARSET_ASCII, 0x0000, msg1[i], strlen(msg1[i]));
+ msg2[i] = oscar_decode_im(account, uin, AIM_CHARSET_ASCII, msg1[i], strlen(msg1[i]));
g_free(uin);
}
msg2[i] = NULL;
@@ -2895,24 +1873,17 @@ incomingim_chan4(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
case 0x06: { /* Someone requested authorization */
if (i >= 6) {
- struct name_data *data = g_new(struct name_data, 1);
gchar *bn = g_strdup_printf("%u", args->uin);
gchar *reason = NULL;
if (msg2[5] != NULL)
- reason = purple_plugin_oscar_decode_im_part(account, bn, AIM_CHARSET_LATIN_1, 0x0000, msg2[5], strlen(msg2[5]));
+ reason = oscar_decode_im(account, bn, AIM_CHARSET_LATIN_1, msg2[5], strlen(msg2[5]));
purple_debug_info("oscar",
"Received an authorization request from UIN %u\n",
args->uin);
- data->gc = gc;
- data->name = bn;
- data->nick = NULL;
-
- purple_account_request_authorization(account, bn, NULL, NULL,
- reason, purple_find_buddy(account, bn) != NULL,
- purple_auth_grant,
- purple_auth_dontgrant_msgprompt, data);
+ aim_icq_getalias(od, bn, TRUE, reason);
+ g_free(bn);
g_free(reason);
}
} break;
@@ -3014,7 +1985,8 @@ incomingim_chan4(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo,
case 0x1a: { /* Handle SMS or someone has sent you a greeting card or requested buddies? */
ByteStream qbs;
- int smstype, taglen, smslen;
+ guint16 smstype;
+ guint32 taglen, smslen;
char *tagstr = NULL, *smsmsg = NULL;
xmlnode *xmlroot = NULL, *xmltmp = NULL;
gchar *uin = NULL, *message = NULL;
@@ -3375,105 +2347,6 @@ static int purple_parse_mtn(OscarData *od, FlapConnection *conn, FlapFrame *fr,
return 1;
}
-/*
- * We get this error when there was an error in the locate family. This
- * happens when you request info of someone who is offline.
- */
-static int purple_parse_locerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
- gchar *buf;
- va_list ap;
- guint16 reason;
- char *destn;
- PurpleNotifyUserInfo *user_info;
-
- va_start(ap, fr);
- reason = (guint16) va_arg(ap, unsigned int);
- destn = va_arg(ap, char *);
- va_end(ap);
-
- if (destn == NULL)
- return 1;
-
- user_info = purple_notify_user_info_new();
- buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(reason));
- purple_notify_user_info_add_pair(user_info, NULL, buf);
- purple_notify_userinfo(od->gc, destn, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
- purple_conv_present_error(destn, purple_connection_get_account(od->gc), buf);
- g_free(buf);
-
- return 1;
-}
-
-static int purple_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
- PurpleConnection *gc = od->gc;
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleNotifyUserInfo *user_info;
- gchar *tmp = NULL, *info_utf8 = NULL, *base_profile_url = NULL;
- va_list ap;
- aim_userinfo_t *userinfo;
-
- va_start(ap, fr);
- userinfo = va_arg(ap, aim_userinfo_t *);
- va_end(ap);
-
- user_info = purple_notify_user_info_new();
-
- oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* strip_html_tags */ FALSE);
-
- if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
- tmp = purple_str_seconds_to_string(userinfo->idletime*60);
- oscar_user_info_add_pair(user_info, _("Idle"), tmp);
- g_free(tmp);
- }
-
- oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo);
-
- if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) {
- /* An SMS contact is always online; its Online Since value is not useful */
- time_t t = userinfo->onlinesince;
- oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
- }
-
- if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
- time_t t = userinfo->membersince;
- oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
- }
-
- if (userinfo->capabilities != 0) {
- tmp = oscar_caps_to_string(userinfo->capabilities);
- oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
- g_free(tmp);
- }
-
- /* Info */
- if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) {
- tmp = oscar_encoding_extract(userinfo->info_encoding);
- info_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->info,
- userinfo->info_len);
- g_free(tmp);
- if (info_utf8 != NULL) {
- tmp = purple_str_sub_away_formatters(info_utf8, purple_account_get_username(account));
- purple_notify_user_info_add_section_break(user_info);
- oscar_user_info_add_pair(user_info, _("Profile"), tmp);
- g_free(tmp);
- g_free(info_utf8);
- }
- }
-
- purple_notify_user_info_add_section_break(user_info);
- base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com";
- tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>",
- base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
- g_free(tmp);
-
- purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
-
- return 1;
-}
-
static int purple_parse_motd(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
{
char *msg;
@@ -3616,13 +2489,7 @@ static int purple_conv_chat_leave(OscarData *od, FlapConnection *conn, FlapFrame
static int purple_conv_chat_info_update(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
va_list ap;
- aim_userinfo_t *userinfo;
- struct aim_chat_roominfo *roominfo;
- char *roomname;
- int usercount;
- char *roomdesc;
- guint16 unknown_c9, unknown_d2, unknown_d5, maxmsglen, maxvisiblemsglen;
- guint32 creationtime;
+ guint16 maxmsglen, maxvisiblemsglen;
PurpleConnection *gc = od->gc;
struct chat_connection *ccon = find_oscar_chat_by_conn(gc, conn);
@@ -3630,16 +2497,7 @@ static int purple_conv_chat_info_update(OscarData *od, FlapConnection *conn, Fla
return 1;
va_start(ap, fr);
- roominfo = va_arg(ap, struct aim_chat_roominfo *);
- roomname = va_arg(ap, char *);
- usercount= va_arg(ap, int);
- userinfo = va_arg(ap, aim_userinfo_t *);
- roomdesc = va_arg(ap, char *);
- unknown_c9 = (guint16)va_arg(ap, unsigned int);
- creationtime = va_arg(ap, guint32);
maxmsglen = (guint16)va_arg(ap, unsigned int);
- unknown_d2 = (guint16)va_arg(ap, unsigned int);
- unknown_d5 = (guint16)va_arg(ap, unsigned int);
maxvisiblemsglen = (guint16)va_arg(ap, unsigned int);
va_end(ap);
@@ -3655,7 +2513,6 @@ static int purple_conv_chat_info_update(OscarData *od, FlapConnection *conn, Fla
static int purple_conv_chat_incoming_msg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
PurpleConnection *gc = od->gc;
- PurpleAccount *account = purple_connection_get_account(gc);
struct chat_connection *ccon = find_oscar_chat_by_conn(gc, conn);
gchar *utf8;
va_list ap;
@@ -3674,10 +2531,7 @@ static int purple_conv_chat_incoming_msg(OscarData *od, FlapConnection *conn, Fl
charset = va_arg(ap, char *);
va_end(ap);
- utf8 = oscar_encoding_to_utf8(account, charset, msg, len);
- if (utf8 == NULL)
- /* The conversion failed! */
- utf8 = g_strdup(_("[Unable to display a message from this user because it contained invalid characters.]"));
+ utf8 = oscar_encoding_to_utf8(charset, msg, len);
serv_got_chat_in(gc, ccon->id, info->bn, 0, utf8, time(NULL));
g_free(utf8);
@@ -3795,41 +2649,6 @@ purple_icons_fetch(PurpleConnection *gc)
purple_debug_misc("oscar", "no more icons to request\n");
}
-/*
- * Received in response to an IM sent with the AIM_IMFLAGS_ACK option.
- */
-static int purple_parse_msgack(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
- va_list ap;
- guint16 type;
- char *bn;
-
- va_start(ap, fr);
- type = (guint16) va_arg(ap, unsigned int);
- bn = va_arg(ap, char *);
- va_end(ap);
-
- purple_debug_info("oscar", "Sent message to %s.\n", bn);
-
- return 1;
-}
-
-static int purple_parse_evilnotify(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
-#ifdef CRAZY_WARNING
- va_list ap;
- guint16 newevil;
- aim_userinfo_t *userinfo;
-
- va_start(ap, fr);
- newevil = (guint16) va_arg(ap, unsigned int);
- userinfo = va_arg(ap, aim_userinfo_t *);
- va_end(ap);
-
- purple_prpl_got_account_warning_level(account, (userinfo && userinfo->bn) ? userinfo->bn : NULL, (newevil/10.0) + 0.5);
-#endif
-
- return 1;
-}
-
static int purple_selfinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
int warning_level;
va_list ap;
@@ -3850,10 +2669,6 @@ static int purple_selfinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, .
*/
warning_level = info->warnlevel/10.0 + 0.5;
-#ifdef CRAZY_WARNING
- purple_presence_set_warning_level(presence, warning_level);
-#endif
-
return 1;
}
@@ -3992,16 +2807,14 @@ static int purple_bosrights(OscarData *od, FlapConnection *conn, FlapFrame *fr,
tmp = purple_markup_strip_html(message);
itmsurl = purple_status_get_attr_string(status, "itmsurl");
aim_srv_setextrainfo(od, FALSE, 0, is_available, tmp, itmsurl);
+ aim_srv_set_dc_info(od);
g_free(tmp);
presence = purple_status_get_presence(status);
aim_srv_setidle(od, !purple_presence_is_idle(presence) ? 0 : time(NULL) - purple_presence_get_idle_time(presence));
if (od->icq) {
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
- aim_icq_reqofflinemsgs(od);
-#endif
- oscar_set_extendedstatus(gc);
+ oscar_set_extended_status(gc);
aim_icq_setsecurity(od,
purple_account_get_bool(account, "authorization", OSCAR_DEFAULT_AUTHORIZATION),
purple_account_get_bool(account, "web_aware", OSCAR_DEFAULT_WEB_AWARE));
@@ -4033,206 +2846,6 @@ static int purple_bosrights(OscarData *od, FlapConnection *conn, FlapFrame *fr,
return 1;
}
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
-static int purple_offlinemsg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
- va_list ap;
- struct aim_icq_offlinemsg *msg;
- struct aim_incomingim_ch4_args args;
- time_t t;
-
- va_start(ap, fr);
- msg = va_arg(ap, struct aim_icq_offlinemsg *);
- va_end(ap);
-
- purple_debug_info("oscar",
- "Received offline message. Converting to channel 4 ICBM...\n");
- args.uin = msg->sender;
- args.type = msg->type;
- args.flags = msg->flags;
- args.msglen = msg->msglen;
- args.msg = msg->msg;
- t = purple_time_build(msg->year, msg->month, msg->day, msg->hour, msg->minute, 0);
- incomingim_chan4(od, conn, NULL, &args, t);
-
- return 1;
-}
-
-static int purple_offlinemsgdone(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
-{
- aim_icq_ackofflinemsgs(od);
- return 1;
-}
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
-
-static int purple_icqinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
-{
- PurpleConnection *gc;
- PurpleAccount *account;
- PurpleBuddy *buddy;
- struct buddyinfo *bi;
- gchar who[16];
- PurpleNotifyUserInfo *user_info;
- gchar *utf8;
- gchar *buf;
- const gchar *alias;
- va_list ap;
- struct aim_icq_info *info;
-
- gc = od->gc;
- account = purple_connection_get_account(gc);
-
- va_start(ap, fr);
- info = va_arg(ap, struct aim_icq_info *);
- va_end(ap);
-
- if (!info->uin)
- return 0;
-
- user_info = purple_notify_user_info_new();
-
- g_snprintf(who, sizeof(who), "%u", info->uin);
- buddy = purple_find_buddy(account, who);
- if (buddy != NULL)
- bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy)));
- else
- bi = NULL;
-
- purple_notify_user_info_add_pair(user_info, _("UIN"), who);
- oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick);
- if ((bi != NULL) && (bi->ipaddr != 0)) {
- char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
- (bi->ipaddr & 0xff000000) >> 24,
- (bi->ipaddr & 0x00ff0000) >> 16,
- (bi->ipaddr & 0x0000ff00) >> 8,
- (bi->ipaddr & 0x000000ff));
- purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr);
- g_free(tstr);
- }
- oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first);
- oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last);
- if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(account, od, info->email))) {
- buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8);
- purple_notify_user_info_add_pair(user_info, _("Email Address"), buf);
- g_free(buf);
- g_free(utf8);
- }
- if (info->numaddresses && info->email2) {
- int i;
- for (i = 0; i < info->numaddresses; i++) {
- if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(account, od, info->email2[i]))) {
- buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8);
- purple_notify_user_info_add_pair(user_info, _("Email Address"), buf);
- g_free(buf);
- g_free(utf8);
- }
- }
- }
- oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile);
-
- if (info->gender != 0)
- purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
-
- if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) {
- /* Initialize the struct properly or strftime() will crash
- * under some conditions (e.g. Debian sarge w/ LANG=en_HK). */
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
-
- tm->tm_mday = (int)info->birthday;
- tm->tm_mon = (int)info->birthmonth - 1;
- tm->tm_year = (int)info->birthyear - 1900;
-
- /* To be 100% sure that the fields are re-normalized.
- * If you're sure strftime() ALWAYS does this EVERYWHERE,
- * feel free to remove it. --rlaager */
- mktime(tm);
-
- oscar_user_info_convert_and_add(account, od, user_info, _("Birthday"), purple_date_format_short(tm));
- }
- if ((info->age > 0) && (info->age < 255)) {
- char age[5];
- snprintf(age, sizeof(age), "%hhd", info->age);
- purple_notify_user_info_add_pair(user_info, _("Age"), age);
- }
- if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->personalwebpage))) {
- buf = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8);
- purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf);
- g_free(buf);
- g_free(utf8);
- }
-
- if (buddy != NULL)
- oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* strip_html_tags */ FALSE);
-
- oscar_user_info_convert_and_add(account, od, user_info, _("Additional Information"), info->info);
- purple_notify_user_info_add_section_break(user_info);
-
- if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) {
- purple_notify_user_info_add_section_header(user_info, _("Home Address"));
-
- oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->homeaddr);
- oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->homecity);
- oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->homestate);
- oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->homezip);
- }
- if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) {
- purple_notify_user_info_add_section_header(user_info, _("Work Address"));
-
- oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->workaddr);
- oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->workcity);
- oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->workstate);
- oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->workzip);
- }
- if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) {
- purple_notify_user_info_add_section_header(user_info, _("Work Information"));
-
- oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany);
- oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision);
- oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition);
-
- if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->workwebpage))) {
- char *webpage = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8);
- purple_notify_user_info_add_pair(user_info, _("Web Page"), webpage);
- g_free(webpage);
- g_free(utf8);
- }
- }
-
- if (buddy != NULL)
- alias = purple_buddy_get_alias(buddy);
- else
- alias = who;
- purple_notify_userinfo(gc, who, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
-
- return 1;
-}
-
-static int purple_icqalias(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
-{
- PurpleConnection *gc = od->gc;
- PurpleAccount *account = purple_connection_get_account(gc);
- gchar who[16], *utf8;
- PurpleBuddy *b;
- va_list ap;
- struct aim_icq_info *info;
-
- va_start(ap, fr);
- info = va_arg(ap, struct aim_icq_info *);
- va_end(ap);
-
- if (info->uin && info->nick && info->nick[0] && (utf8 = oscar_utf8_try_convert(account, od, info->nick))) {
- g_snprintf(who, sizeof(who), "%u", info->uin);
- serv_got_alias(gc, who, utf8);
- if ((b = purple_find_buddy(account, who))) {
- purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", utf8);
- }
- g_free(utf8);
- }
-
- return 1;
-}
-
static int purple_popup(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
{
PurpleConnection *gc = od->gc;
@@ -4457,8 +3070,8 @@ purple_odc_send_im(PeerConnection *conn, const char *message, PurpleMessageFlags
GString *msg;
GString *data;
gchar *tmp;
- int tmplen;
- guint16 charset, charsubset;
+ gsize tmplen;
+ guint16 charset;
GData *attribs;
const char *start, *end, *last;
int oscar_id = 0;
@@ -4519,8 +3132,7 @@ purple_odc_send_im(PeerConnection *conn, const char *message, PurpleMessageFlags
g_string_append(msg, "</BODY></HTML>");
/* Convert the message to a good encoding */
- purple_plugin_oscar_convert_to_best_encoding(conn->od->gc,
- conn->bn, msg->str, &tmp, &tmplen, &charset, &charsubset);
+ tmp = oscar_encode_im(msg->str, &tmplen, &charset, NULL);
g_string_free(msg, TRUE);
msg = g_string_new_len(tmp, tmplen);
g_free(tmp);
@@ -4567,7 +3179,7 @@ oscar_send_im(PurpleConnection *gc, const char *name, const char *message, Purpl
}
if (imflags & PURPLE_MESSAGE_AUTO_RESP)
- tmp1 = purple_str_sub_away_formatters(message, name);
+ tmp1 = oscar_util_format_string(message, name);
else
tmp1 = g_strdup(message);
@@ -4600,7 +3212,7 @@ oscar_send_im(PurpleConnection *gc, const char *name, const char *message, Purpl
g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, name)), bi);
}
- args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES;
+ args.flags = 0;
if (!is_sms && (!buddy || !PURPLE_BUDDY_IS_ONLINE(buddy)))
args.flags |= AIM_IMFLAGS_OFFLINE;
@@ -4669,7 +3281,7 @@ oscar_send_im(PurpleConnection *gc, const char *name, const char *message, Purpl
g_free(tmp1);
tmp1 = tmp2;
- purple_plugin_oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
+ args.msg = oscar_encode_im(tmp1, &args.msglen, &args.charset, NULL);
if (is_html && (args.msglen > MAXMSGLEN)) {
/* If the length was too long, try stripping the HTML and then running it back through
* purple_strdup_withhtml() and the encoding process. The result may be shorter. */
@@ -4686,14 +3298,12 @@ oscar_send_im(PurpleConnection *gc, const char *name, const char *message, Purpl
g_free(tmp1);
tmp1 = tmp2;
- purple_plugin_oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
-
+ args.msg = oscar_encode_im(tmp1, &args.msglen, &args.charset, NULL);
purple_debug_info("oscar", "Sending %s as %s because the original was too long.\n",
message, (char *)args.msg);
}
- purple_debug_info("oscar", "Sending IM, charset=0x%04hx, charsubset=0x%04hx, length=%d\n",
- args.charset, args.charsubset, args.msglen);
+ purple_debug_info("oscar", "Sending IM, charset=0x%04hx, length=%" G_GSIZE_FORMAT "\n", args.charset, args.msglen);
ret = aim_im_sendch1_ext(od, &args);
g_free((char *)args.msg);
}
@@ -4720,43 +3330,11 @@ void oscar_get_info(PurpleConnection *gc, const char *name) {
aim_locate_getinfoshort(od, name, 0x00000003);
}
-#if 0
-static void oscar_set_dir(PurpleConnection *gc, const char *first, const char *middle, const char *last,
- const char *maiden, const char *city, const char *state, const char *country, int web) {
- /* XXX - some of these things are wrong, but i'm lazy */
- OscarData *od = purple_connection_get_protocol_data(gc);
- aim_locate_setdirinfo(od, first, middle, last,
- maiden, NULL, NULL, city, state, NULL, 0, web);
-}
-#endif
-
void oscar_set_idle(PurpleConnection *gc, int time) {
OscarData *od = purple_connection_get_protocol_data(gc);
aim_srv_setidle(od, time);
}
-static
-gchar *purple_prpl_oscar_convert_to_infotext(const gchar *str, gsize *ret_len, char **encoding)
-{
- int charset = 0;
- char *encoded = NULL;
-
- charset = oscar_charset_check(str);
- if (charset == AIM_CHARSET_UNICODE) {
- encoded = g_convert(str, -1, "UTF-16BE", "UTF-8", NULL, ret_len, NULL);
- *encoding = "unicode-2-0";
- } else if (charset == AIM_CHARSET_LATIN_1) {
- encoded = g_convert(str, -1, "ISO-8859-1", "UTF-8", NULL, ret_len, NULL);
- *encoding = "iso-8859-1";
- } else {
- encoded = g_strdup(str);
- *ret_len = strlen(str);
- *encoding = "us-ascii";
- }
-
- return encoded;
-}
-
void
oscar_set_info(PurpleConnection *gc, const char *rawinfo)
{
@@ -4768,8 +3346,8 @@ oscar_set_info(PurpleConnection *gc, const char *rawinfo)
oscar_set_info_and_status(account, TRUE, rawinfo, FALSE, status);
}
-static void
-oscar_set_extendedstatus(PurpleConnection *gc)
+static guint32
+oscar_get_extended_status(PurpleConnection *gc)
{
OscarData *od;
PurpleAccount *account;
@@ -4813,7 +3391,13 @@ oscar_set_extendedstatus(PurpleConnection *gc)
else if (!strcmp(status_id, OSCAR_STATUS_ID_CUSTOM))
data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY;
- aim_srv_setextrainfo(od, TRUE, data, FALSE, NULL, NULL);
+ return data;
+}
+
+static void
+oscar_set_extended_status(PurpleConnection *gc)
+{
+ aim_srv_setextrainfo(purple_connection_get_protocol_data(gc), TRUE, oscar_get_extended_status(gc), FALSE, NULL, NULL);
}
static void
@@ -4854,7 +3438,7 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *
else if (rawinfo != NULL)
{
char *htmlinfo = purple_strdup_withhtml(rawinfo);
- info = purple_prpl_oscar_convert_to_infotext(htmlinfo, &infolen, &info_encoding);
+ info = oscar_encode_im(htmlinfo, &infolen, NULL, &info_encoding);
g_free(htmlinfo);
if (infolen > od->rights.maxsiglen)
@@ -4887,7 +3471,7 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *
/* We do this for icq too so that they work for old third party clients */
linkified = purple_markup_linkify(status_html);
- away = purple_prpl_oscar_convert_to_infotext(linkified, &awaylen, &away_encoding);
+ away = oscar_encode_im(linkified, &awaylen, NULL, &away_encoding);
g_free(linkified);
if (awaylen > od->rights.maxawaymsglen)
@@ -4916,8 +3500,6 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *
const char *status_html;
status_html = purple_status_get_attr_string(status, "message");
- if (od->icq && (status_html == NULL || status_html[0] == '\0'))
- status_html = purple_status_type_get_name(status_type);
if (status_html != NULL)
{
status_text = purple_markup_strip_html(status_html);
@@ -4930,28 +3512,27 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *
}
itmsurl = purple_status_get_attr_string(status, "itmsurl");
-
- /* TODO: Combine these two calls! */
- aim_srv_setextrainfo(od, FALSE, 0, TRUE, status_text, itmsurl);
- oscar_set_extendedstatus(gc);
+
+ aim_srv_setextrainfo(od, TRUE, oscar_get_extended_status(gc), TRUE, status_text, itmsurl);
g_free(status_text);
}
}
static void
-oscar_set_status_icq(PurpleAccount *account)
+oscar_set_icq_permdeny(PurpleAccount *account)
{
PurpleConnection *gc = purple_account_get_connection(account);
-
- /* Our permit/deny setting affects our invisibility */
- oscar_set_permit_deny(gc);
+ OscarData *od = purple_connection_get_protocol_data(gc);
+ gboolean invisible = purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE);
/*
- * TODO: I guess we should probably wait and do this after we get
- * confirmation from the above SSI call? Right now other people
- * see our status blip to "invisible" before we appear offline.
+ * For ICQ the permit/deny setting controls who can see you
+ * online. Mimicking the official client's behavior, we use PURPLE_PRIVACY_ALLOW_USERS
+ * when our status is "invisible" and PURPLE_PRIVACY_DENY_USERS otherwise.
+ * In the former case, we are visible only to buddies on our "permanently visible" list.
+ * In the latter, we are invisible only to buddies on our "permanently invisible" list.
*/
- oscar_set_extendedstatus(gc);
+ aim_ssi_setpermdeny(od, invisible ? PURPLE_PRIVACY_ALLOW_USERS : PURPLE_PRIVACY_DENY_USERS);
}
void
@@ -4977,22 +3558,15 @@ oscar_set_status(PurpleAccount *account, PurpleStatus *status)
return;
}
+ if (od->icq) {
+ /* Set visibility */
+ oscar_set_icq_permdeny(account);
+ }
+
/* Set the AIM-style away message for both AIM and ICQ accounts */
oscar_set_info_and_status(account, FALSE, NULL, TRUE, status);
-
- /* Set the ICQ status for ICQ accounts only */
- if (od->icq)
- oscar_set_status_icq(account);
}
-#ifdef CRAZY_WARN
-void
-oscar_warn(PurpleConnection *gc, const char *name, gboolean anonymous) {
- OscarData *od = purple_connection_get_protocol_data(gc);
- aim_im_warn(od, od->conn, name, anonymous ? AIM_WARN_ANON : 0);
-}
-#endif
-
void
oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) {
OscarData *od;
@@ -5034,13 +3608,13 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) {
aim_ssi_itemlist_findparentname(od->ssi.local, bname),
bname)) {
/* Not authorized -- Re-request authorization */
- purple_auth_sendrequest(gc, bname);
+ oscar_auth_sendrequest(gc, bname);
}
}
/* XXX - Should this be done from AIM accounts, as well? */
if (od->icq)
- aim_icq_getalias(od, bname);
+ aim_icq_getalias(od, bname, FALSE, NULL);
}
void oscar_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) {
@@ -5150,8 +3724,6 @@ static int purple_ssi_parseerr(OscarData *od, FlapConnection *conn, FlapFrame *f
return 1;
}
- oscar_set_status_icq(purple_connection_get_account(gc));
-
return 1;
}
@@ -5192,12 +3764,14 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
PurpleAccount *account;
PurpleGroup *g;
PurpleBuddy *b;
+ GSList *cur, *next, *buddies;
struct aim_ssi_item *curitem;
guint32 tmp;
PurpleStoredImage *img;
va_list ap;
guint16 fmtver, numitems;
guint32 timestamp;
+ guint16 deny_entry_type = aim_ssi_getdenyentrytype(od);
gc = od->gc;
od = purple_connection_get_protocol_data(gc);
@@ -5210,110 +3784,109 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
va_end(ap);
/* Don't attempt to re-request our buddy list later */
- if (od->getblisttimer != 0)
+ if (od->getblisttimer != 0) {
purple_timeout_remove(od->getblisttimer);
- od->getblisttimer = 0;
+ od->getblisttimer = 0;
+ }
- purple_debug_info("oscar",
- "ssi: syncing local list and server list\n");
+ purple_debug_info("oscar", "ssi: syncing local list and server list\n");
/* Clean the buddy list */
aim_ssi_cleanlist(od);
- { /* If not in server list then prune from local list */
- GSList *cur, *next;
- GSList *buddies = purple_find_buddies(account, NULL);
-
- /* Buddies */
- cur = NULL;
-
- while(buddies) {
- PurpleGroup *g;
- const char *gname;
- const char *bname;
-
- b = buddies->data;
- g = purple_buddy_get_group(b);
- gname = purple_group_get_name(g);
- bname = purple_buddy_get_name(b);
-
- if (aim_ssi_itemlist_exists(od->ssi.local, bname)) {
- /* If the buddy is an ICQ user then load his nickname */
- const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick");
- char *alias;
- const char *balias;
- if (servernick)
- serv_got_alias(gc, bname, servernick);
-
- /* Store local alias on server */
- alias = aim_ssi_getalias(od->ssi.local, gname, bname);
- balias = purple_buddy_get_local_buddy_alias(b);
- if (!alias && balias && *balias)
- aim_ssi_aliasbuddy(od, gname, bname, balias);
- g_free(alias);
- } else {
- purple_debug_info("oscar",
- "ssi: removing buddy %s from local list\n", bname);
- /* We can't actually remove now because it will screw up our looping */
- cur = g_slist_prepend(cur, b);
- }
- buddies = g_slist_delete_link(buddies, buddies);
- }
+ /*** Begin code for pruning buddies from local list if they're not in server list ***/
- while (cur != NULL) {
- b = cur->data;
- cur = g_slist_remove(cur, b);
- purple_blist_remove_buddy(b);
+ /* Buddies */
+ cur = NULL;
+ for (buddies = purple_find_buddies(account, NULL);
+ buddies;
+ buddies = g_slist_delete_link(buddies, buddies))
+ {
+ PurpleGroup *g;
+ const char *gname;
+ const char *bname;
+
+ b = buddies->data;
+ g = purple_buddy_get_group(b);
+ gname = purple_group_get_name(g);
+ bname = purple_buddy_get_name(b);
+
+ if (aim_ssi_itemlist_exists(od->ssi.local, bname)) {
+ /* If the buddy is an ICQ user then load his nickname */
+ const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick");
+ char *alias;
+ const char *balias;
+ if (servernick)
+ serv_got_alias(gc, bname, servernick);
+
+ /* Store local alias on server */
+ alias = aim_ssi_getalias(od->ssi.local, gname, bname);
+ balias = purple_buddy_get_local_buddy_alias(b);
+ if (!alias && balias && *balias)
+ aim_ssi_aliasbuddy(od, gname, bname, balias);
+ g_free(alias);
+ } else {
+ purple_debug_info("oscar",
+ "ssi: removing buddy %s from local list\n", bname);
+ /* Queue the buddy for removal from the local list */
+ cur = g_slist_prepend(cur, b);
}
+ }
+ while (cur != NULL) {
+ purple_blist_remove_buddy(cur->data);
+ cur = g_slist_delete_link(cur, cur);
+ }
- /* Permit list */
- if (account->permit) {
- next = account->permit;
- while (next != NULL) {
- cur = next;
- next = next->next;
- if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
- purple_debug_info("oscar",
- "ssi: removing permit %s from local list\n", (const char *)cur->data);
- purple_privacy_permit_remove(account, cur->data, TRUE);
- }
+ /* Permit list (ICQ doesn't have one) */
+ if (!od->icq) {
+ next = account->permit;
+ while (next != NULL) {
+ cur = next;
+ next = next->next;
+ if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
+ purple_debug_info("oscar",
+ "ssi: removing permit %s from local list\n", (const char *)cur->data);
+ purple_privacy_permit_remove(account, cur->data, TRUE);
}
}
+ }
- /* Deny list */
- if (account->deny) {
- next = account->deny;
- while (next != NULL) {
- cur = next;
- next = next->next;
- if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
- purple_debug_info("oscar",
- "ssi: removing deny %s from local list\n", (const char *)cur->data);
- purple_privacy_deny_remove(account, cur->data, TRUE);
- }
- }
+ /* Deny list */
+ next = account->deny;
+ while (next != NULL) {
+ cur = next;
+ next = next->next;
+ if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, deny_entry_type)) {
+ purple_debug_info("oscar",
+ "ssi: removing deny %s from local list\n", (const char *)cur->data);
+ purple_privacy_deny_remove(account, cur->data, TRUE);
}
- /* Presence settings (idle time visibility) */
- tmp = aim_ssi_getpresence(od->ssi.local);
- if (tmp != 0xFFFFFFFF) {
- const char *idle_reporting_pref;
- gboolean report_idle;
+ }
- idle_reporting_pref = purple_prefs_get_string("/purple/away/idle_reporting");
- report_idle = strcmp(idle_reporting_pref, "none") != 0;
+ /* Presence settings (idle time visibility) */
+ tmp = aim_ssi_getpresence(od->ssi.local);
+ if (tmp != 0xFFFFFFFF) {
+ const char *idle_reporting_pref;
+ gboolean report_idle;
- if (report_idle)
- aim_ssi_setpresence(od, tmp | AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
- else
- aim_ssi_setpresence(od, tmp & ~AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
- }
+ idle_reporting_pref = purple_prefs_get_string("/purple/away/idle_reporting");
+ report_idle = strcmp(idle_reporting_pref, "none") != 0;
+ if (report_idle)
+ aim_ssi_setpresence(od, tmp | AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
+ else
+ aim_ssi_setpresence(od, tmp & ~AIM_SSI_PRESENCE_FLAG_SHOWIDLE);
+ }
- } /* end pruning buddies from local list */
+ /*** End code for pruning buddies from local list ***/
+
+ /*** Begin code for adding from server list to local list ***/
- /* Add from server list to local list */
for (curitem=od->ssi.local; curitem; curitem=curitem->next) {
- if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL)))
+ if (curitem->name && !g_utf8_validate(curitem->name, -1, NULL))
+ /* Got node with invalid UTF-8 in the name. Skip it. */
+ break;
+
switch (curitem->type) {
case AIM_SSI_TYPE_BUDDY: { /* Buddy */
if (curitem->name) {
@@ -5322,13 +3895,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
groupitem = aim_ssi_itemlist_find(od->ssi.local, curitem->gid, 0x0000);
gname = groupitem ? groupitem->name : NULL;
- if (gname != NULL) {
- if (g_utf8_validate(gname, -1, NULL))
- gname_utf8 = g_strdup(gname);
- else
- gname_utf8 = oscar_utf8_try_convert(account, od, gname);
- } else
- gname_utf8 = NULL;
+ gname_utf8 = oscar_utf8_try_convert(account, od, gname);
g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans"));
if (g == NULL) {
@@ -5337,14 +3904,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
}
alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name);
- if (alias != NULL) {
- if (g_utf8_validate(alias, -1, NULL))
- alias_utf8 = g_strdup(alias);
- else
- alias_utf8 = oscar_utf8_try_convert(account, od, alias);
- g_free(alias);
- } else
- alias_utf8 = NULL;
+ alias_utf8 = oscar_utf8_try_convert(account, od, alias);
b = purple_find_buddy_in_group(account, curitem->name, g);
if (b) {
@@ -5386,13 +3946,7 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
char *gname_utf8;
gname = curitem->name;
- if (gname != NULL) {
- if (g_utf8_validate(gname, -1, NULL))
- gname_utf8 = g_strdup(gname);
- else
- gname_utf8 = oscar_utf8_try_convert(account, od, gname);
- } else
- gname_utf8 = NULL;
+ gname_utf8 = oscar_utf8_try_convert(account, od, gname);
if (gname_utf8 != NULL && purple_find_group(gname_utf8) == NULL) {
g = purple_group_new(gname_utf8);
@@ -5401,12 +3955,10 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
g_free(gname_utf8);
} break;
- case AIM_SSI_TYPE_PERMIT: { /* Permit buddy */
- if (curitem->name) {
- /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */
- GSList *list;
- for (list=account->permit; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next);
- if (!list) {
+ case AIM_SSI_TYPE_PERMIT: { /* Permit buddy (unless we're on ICQ) */
+ if (!od->icq && curitem->name) {
+ for (cur = account->permit; (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
+ if (!cur) {
purple_debug_info("oscar",
"ssi: adding permit buddy %s to local list\n", curitem->name);
purple_privacy_permit_add(account, curitem->name, TRUE);
@@ -5414,11 +3966,11 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
}
} break;
+ case AIM_SSI_TYPE_ICQDENY:
case AIM_SSI_TYPE_DENY: { /* Deny buddy */
- if (curitem->name) {
- GSList *list;
- for (list=account->deny; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next);
- if (!list) {
+ if (curitem->type == deny_entry_type && curitem->name) {
+ for (cur = account->deny; (cur && oscar_util_name_compare(curitem->name, cur->data)); cur = cur->next);
+ if (!cur) {
purple_debug_info("oscar",
"ssi: adding deny buddy %s to local list\n", curitem->name);
purple_privacy_deny_add(account, curitem->name, TRUE);
@@ -5450,7 +4002,13 @@ static int purple_ssi_parselist(OscarData *od, FlapConnection *conn, FlapFrame *
} /* End of switch on curitem->type */
} /* End of for loop */
- oscar_set_status_icq(account);
+ /*** End code for adding from server list to local list ***/
+
+ if (od->icq) {
+ oscar_set_icq_permdeny(account);
+ } else {
+ oscar_set_aim_permdeny(gc);
+ }
/* Activate SSI */
/* Sending the enable causes other people to be able to see you, and you to see them */
@@ -5512,7 +4070,7 @@ static int purple_ssi_parseack(OscarData *od, FlapConnection *conn, FlapFrame *f
case 0x000e: { /* buddy requires authorization */
if ((retval->action == SNAC_SUBTYPE_FEEDBAG_ADD) && (retval->name))
- purple_auth_sendrequest(gc, retval->name);
+ oscar_auth_sendrequest(gc, retval->name);
} break;
default: { /* La la la */
@@ -5561,15 +4119,7 @@ purple_ssi_parseaddmod(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
gname_utf8 = gname ? oscar_utf8_try_convert(account, od, gname) : NULL;
alias = aim_ssi_getalias(od->ssi.local, gname, name);
- if (alias != NULL)
- {
- if (g_utf8_validate(alias, -1, NULL))
- alias_utf8 = g_strdup(alias);
- else
- alias_utf8 = oscar_utf8_try_convert(account, od, alias);
- }
- else
- alias_utf8 = NULL;
+ alias_utf8 = oscar_utf8_try_convert(account, od, alias);
g_free(alias);
b = purple_find_buddy(account, name);
@@ -5664,24 +4214,18 @@ static int purple_ssi_authgiven(OscarData *od, FlapConnection *conn, FlapFrame *
static int purple_ssi_authrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
{
- PurpleConnection *gc = od->gc;
va_list ap;
const char *bn;
- const char *msg;
- PurpleAccount *account = purple_connection_get_account(gc);
- struct name_data *data;
- PurpleBuddy *buddy;
+ char *msg;
va_start(ap, fr);
bn = va_arg(ap, const char *);
- msg = va_arg(ap, const char *);
+ msg = va_arg(ap, char *);
va_end(ap);
purple_debug_info("oscar",
"ssi: received authorization request from %s\n", bn);
- buddy = purple_find_buddy(account, bn);
-
if (!msg) {
purple_debug_warning("oscar", "Received auth request from %s with "
"empty message\n", bn);
@@ -5691,16 +4235,7 @@ static int purple_ssi_authrequest(OscarData *od, FlapConnection *conn, FlapFrame
msg = NULL;
}
- data = g_new(struct name_data, 1);
- data->gc = gc;
- data->name = g_strdup(bn);
- data->nick = (buddy ? g_strdup(purple_buddy_get_alias_only(buddy)) : NULL);
-
- purple_account_request_authorization(account, bn, NULL,
- (buddy ? purple_buddy_get_alias_only(buddy) : NULL),
- msg, buddy != NULL, purple_auth_grant,
- purple_auth_dontgrant_msgprompt, data);
-
+ aim_icq_getalias(od, bn, TRUE, msg);
return 1;
}
@@ -5873,9 +4408,9 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes
PurpleConversation *conv = NULL;
struct chat_connection *c = NULL;
char *buf, *buf2, *buf3;
- guint16 charset, charsubset;
- char *charsetstr = NULL;
- int len;
+ guint16 charset;
+ char *charsetstr;
+ gsize len;
if (!(conv = purple_find_chat(gc, id)))
return -EINVAL;
@@ -5891,7 +4426,7 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes
"You cannot send IM Images in AIM chats."),
PURPLE_MESSAGE_ERROR, time(NULL));
- purple_plugin_oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
+ buf2 = oscar_encode_im(buf, &len, &charset, &charsetstr);
/*
* Evan S. suggested that maxvis really does mean "number of
* visible characters" and not "number of bytes"
@@ -5907,10 +4442,11 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes
buf = purple_strdup_withhtml(buf3);
g_free(buf3);
- purple_plugin_oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
+ buf2 = oscar_encode_im(buf, &len, &charset, &charsetstr);
if ((len > c->maxlen) || (len > c->maxvis)) {
- purple_debug_warning("oscar", "Could not send %s because (%i > maxlen %i) or (%i > maxvis %i)\n",
+ purple_debug_warning("oscar",
+ "Could not send %s because (%" G_GSIZE_FORMAT " > maxlen %i) or (%" G_GSIZE_FORMAT " > maxvis %i)\n",
buf2, len, c->maxlen, len, c->maxvis);
g_free(buf);
g_free(buf2);
@@ -5921,12 +4457,6 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes
message, buf2);
}
- if (charset == AIM_CHARSET_ASCII)
- charsetstr = "us-ascii";
- else if (charset == AIM_CHARSET_UNICODE)
- charsetstr = "unicode-2-0";
- else if (charset == AIM_CHARSET_LATIN_1)
- charsetstr = "iso-8859-1";
aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "en");
g_free(buf2);
g_free(buf);
@@ -6081,7 +4611,7 @@ char *oscar_status_text(PurpleBuddy *b)
tmp1 = purple_markup_strip_html(message);
purple_util_chrreplace(tmp1, '\n', ' ');
tmp2 = g_markup_escape_text(tmp1, -1);
- ret = purple_str_sub_away_formatters(tmp2, purple_account_get_username(account));
+ ret = oscar_util_format_string(tmp2, purple_account_get_username(account));
g_free(tmp1);
g_free(tmp2);
}
@@ -6098,67 +4628,40 @@ char *oscar_status_text(PurpleBuddy *b)
return ret;
}
-void oscar_set_permit_deny(PurpleConnection *gc) {
+void oscar_set_aim_permdeny(PurpleConnection *gc) {
PurpleAccount *account = purple_connection_get_account(gc);
OscarData *od = purple_connection_get_protocol_data(gc);
- PurplePrivacyType perm_deny;
/*
- * For ICQ the permit/deny setting controls who you can see you
- * online when you set your status to "invisible." If we're ICQ
- * and we're invisible then we need to use one of
- * PURPLE_PRIVACY_ALLOW_USERS or PURPLE_PRIVACY_ALLOW_BUDDYLIST or
- * PURPLE_PRIVACY_DENY_USERS if we actually want to be invisible
- * to anyone.
- *
- * These three permit/deny settings correspond to:
- * 1. Invisible to everyone except the people on my "permit" list
- * 2. Invisible to everyone except the people on my buddy list
- * 3. Invisible only to the people on my "deny" list
- *
- * It would be nice to allow cases 2 and 3, but our UI doesn't have
- * a nice way to do it. For now we just force case 1.
+ * Conveniently there is a one-to-one mapping between the
+ * values of libpurple's PurplePrivacyType and the values used
+ * by the oscar protocol.
*/
- if (od->icq && purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE))
- perm_deny = PURPLE_PRIVACY_ALLOW_USERS;
- else
- perm_deny = account->perm_deny;
-
- if (od->ssi.received_data)
- /*
- * Conveniently there is a one-to-one mapping between the
- * values of libpurple's PurplePrivacyType and the values used
- * by the oscar protocol.
- */
- aim_ssi_setpermdeny(od, perm_deny, 0xffffffff);
+ aim_ssi_setpermdeny(od, account->perm_deny);
}
void oscar_add_permit(PurpleConnection *gc, const char *who) {
OscarData *od = purple_connection_get_protocol_data(gc);
purple_debug_info("oscar", "ssi: About to add a permit\n");
- if (od->ssi.received_data)
- aim_ssi_addpermit(od, who);
+ aim_ssi_add_to_private_list(od, who, AIM_SSI_TYPE_PERMIT);
}
void oscar_add_deny(PurpleConnection *gc, const char *who) {
OscarData *od = purple_connection_get_protocol_data(gc);
purple_debug_info("oscar", "ssi: About to add a deny\n");
- if (od->ssi.received_data)
- aim_ssi_adddeny(od, who);
+ aim_ssi_add_to_private_list(od, who, aim_ssi_getdenyentrytype(od));
}
void oscar_rem_permit(PurpleConnection *gc, const char *who) {
OscarData *od = purple_connection_get_protocol_data(gc);
purple_debug_info("oscar", "ssi: About to delete a permit\n");
- if (od->ssi.received_data)
- aim_ssi_delpermit(od, who);
+ aim_ssi_del_from_private_list(od, who, AIM_SSI_TYPE_PERMIT);
}
void oscar_rem_deny(PurpleConnection *gc, const char *who) {
OscarData *od = purple_connection_get_protocol_data(gc);
purple_debug_info("oscar", "ssi: About to delete a deny\n");
- if (od->ssi.received_data)
- aim_ssi_deldeny(od, who);
+ aim_ssi_del_from_private_list(od, who, aim_ssi_getdenyentrytype(od));
}
GList *
@@ -6450,7 +4953,7 @@ oscar_close_directim(gpointer object, gpointer ignored)
peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL);
/* OSCAR_DISCONNECT_LOCAL_CLOSED doesn't write anything to the convo
- * window. Let the user know that we canceled the Direct IM. */
+ * window. Let the user know that we cancelled the Direct IM. */
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
purple_conversation_write(conv, NULL, _("You closed the connection."),
PURPLE_MESSAGE_SYSTEM, time(NULL));
@@ -6490,7 +4993,6 @@ oscar_get_aim_info_cb(PurpleBlistNode *node, gpointer ignore)
static GList *
oscar_buddy_menu(PurpleBuddy *buddy) {
-
PurpleConnection *gc;
OscarData *od;
GList *menu;
@@ -6528,6 +5030,7 @@ oscar_buddy_menu(PurpleBuddy *buddy) {
PURPLE_CALLBACK(oscar_get_icqxstatusmsg),
NULL, NULL);
menu = g_list_prepend(menu, act);
+ menu = g_list_prepend(menu, create_visibility_menu_item(od, bname));
}
if (userinfo &&
@@ -6553,15 +5056,6 @@ oscar_buddy_menu(PurpleBuddy *buddy) {
}
menu = g_list_prepend(menu, act);
}
-#if 0
- /* TODO: This menu item should be added by the core */
- if (userinfo->capabilities & OSCAR_CAPABILITY_GETFILE) {
- act = purple_menu_action_new(_("Get File"),
- PURPLE_CALLBACK(oscar_ask_getfile),
- NULL, NULL);
- menu = g_list_prepend(menu, act);
- }
-#endif
}
if (od->ssi.received_data && purple_buddy_get_group(buddy) != NULL)
@@ -6575,7 +5069,7 @@ oscar_buddy_menu(PurpleBuddy *buddy) {
if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname))
{
act = purple_menu_action_new(_("Re-request Authorization"),
- PURPLE_CALLBACK(purple_auth_sendrequest_menu),
+ PURPLE_CALLBACK(oscar_auth_sendrequest_menu),
NULL, NULL);
menu = g_list_prepend(menu, act);
}
@@ -6612,7 +5106,7 @@ oscar_icq_privacy_opts(PurpleConnection *gc, PurpleRequestFields *fields)
purple_account_set_bool(account, "authorization", auth);
purple_account_set_bool(account, "web_aware", web_aware);
- oscar_set_extendedstatus(gc);
+ oscar_set_extended_status(gc);
aim_icq_setsecurity(od, auth, web_aware);
}
@@ -6727,41 +5221,29 @@ static void oscar_show_awaitingauth(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
OscarData *od = purple_connection_get_protocol_data(gc);
- gchar *text, *tmp;
- GSList *buddies;
- PurpleAccount *account;
- int num=0;
-
- text = g_strdup("");
- account = purple_connection_get_account(gc);
+ PurpleAccount *account = purple_connection_get_account(gc);
+ GSList *buddies, *filtered_buddies, *cur;
+ gchar *text;
buddies = purple_find_buddies(account, NULL);
- while (buddies) {
+ filtered_buddies = NULL;
+ for (cur = buddies; cur != NULL; cur = cur->next) {
PurpleBuddy *buddy;
const gchar *bname, *gname;
- buddy = buddies->data;
+ buddy = cur->data;
bname = purple_buddy_get_name(buddy);
gname = purple_group_get_name(purple_buddy_get_group(buddy));
if (aim_ssi_waitingforauth(od->ssi.local, gname, bname)) {
- const gchar *alias = purple_buddy_get_alias_only(buddy);
- if (alias)
- tmp = g_strdup_printf("%s %s (%s)<br>", text, bname, alias);
- else
- tmp = g_strdup_printf("%s %s<br>", text, bname);
- g_free(text);
- text = tmp;
-
- num++;
+ filtered_buddies = g_slist_prepend(filtered_buddies, buddy);
}
-
- buddies = g_slist_delete_link(buddies, buddies);
}
- if (!num) {
- g_free(text);
- text = g_strdup(_("<i>you are not waiting for authorization</i>"));
- }
+ g_slist_free(buddies);
+
+ filtered_buddies = g_slist_reverse(filtered_buddies);
+ text = oscar_format_buddies(filtered_buddies, _("you are not waiting for authorization"));
+ g_slist_free(filtered_buddies);
purple_notify_formatted(gc, NULL, _("You are awaiting authorization from "
"the following buddies"), _("You can re-request "
@@ -6976,6 +5458,12 @@ oscar_actions(PurplePlugin *plugin, gpointer context)
act = purple_plugin_action_new(_("Set Privacy Options..."),
oscar_show_icq_privacy_opts);
menu = g_list_prepend(menu, act);
+
+ act = purple_plugin_action_new("Show Visible List", oscar_show_visible_list);
+ menu = g_list_prepend(menu, act);
+
+ act = purple_plugin_action_new("Show Invisible List", oscar_show_invisible_list);
+ menu = g_list_prepend(menu, act);
}
else
{
@@ -7005,12 +5493,6 @@ oscar_actions(PurplePlugin *plugin, gpointer context)
oscar_show_find_email);
menu = g_list_prepend(menu, act);
-#if 0
- act = purple_plugin_action_new(_("Search for Buddy by Information"),
- show_find_info);
- menu = g_list_prepend(menu, act);
-#endif
-
menu = g_list_reverse(menu);
return menu;
diff --git a/libpurple/protocols/oscar/oscar.h b/libpurple/protocols/oscar/oscar.h
index a6ae11236b..638536e793 100644
--- a/libpurple/protocols/oscar/oscar.h
+++ b/libpurple/protocols/oscar/oscar.h
@@ -103,16 +103,6 @@ extern "C" {
#define AIM_ICONIDENT "AVT1picture.id"
/*
- * Current Maximum Length for Chat Room Messages
- *
- * This is actually defined by the protocol to be
- * dynamic, but I have yet to see due cause to
- * define it dynamically here. Maybe later.
- *
- */
-#define MAXCHATMSGLEN 512
-
-/*
* Found by trial and error.
*/
#define MAXAVAILMSGLEN 251
@@ -143,167 +133,6 @@ struct _ClientInfo
const char *lang; /* two-letter abbrev */
};
-/* Needs to be checked */
-#define CLIENTINFO_AIM_3_5_1670 { \
- "AOL Instant Messenger (SM), version 3.5.1670/WIN32", \
- 0x0004, \
- 0x0003, 0x0005, \
- 0x0000, 0x0686, \
- 0x0000002a, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-/* Latest winaim without ssi */
-#define CLIENTINFO_AIM_4_1_2010 { \
- "AOL Instant Messenger (SM), version 4.1.2010/WIN32", \
- 0x0004, \
- 0x0004, 0x0001, \
- 0x0000, 0x07da, \
- 0x0000004b, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_4_3_2188 { \
- "AOL Instant Messenger (SM), version 4.3.2188/WIN32", \
- 0x0109, \
- 0x0400, 0x0003, \
- 0x0000, 0x088c, \
- 0x00000086, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_4_8_2540 { \
- "AOL Instant Messenger (SM), version 4.8.2540/WIN32", \
- 0x0109, \
- 0x0004, 0x0008, \
- 0x0000, 0x09ec, \
- 0x000000af, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_5_0_2938 { \
- "AOL Instant Messenger, version 5.0.2938/WIN32", \
- 0x0109, \
- 0x0005, 0x0000, \
- 0x0000, 0x0b7a, \
- 0x00000000, \
- "us", "en", \
-}
-
-#define CLIENTINFO_AIM_5_1_3036 { \
- "AOL Instant Messenger, version 5.1.3036/WIN32", \
- 0x0109, \
- 0x0005, 0x0001, \
- 0x0000, 0x0bdc, \
- 0x000000d2, \
- "us", "en", \
-}
-
-#define CLIENTINFO_AIM_5_5_3415 { \
- "AOL Instant Messenger, version 5.5.3415/WIN32", \
- 0x0109, \
- 0x0005, 0x0005, \
- 0x0000, 0x0057, \
- 0x000000ef, \
- "us", "en", \
-}
-
-#define CLIENTINFO_AIM_5_9_3702 { \
- "AOL Instant Messenger, version 5.9.3702/WIN32", \
- 0x0109, \
- 0x0005, 0x0009, \
- 0x0000, 0x0e76, \
- 0x00000111, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICHAT_1_0 { \
- "Apple iChat", \
- 0x311a, \
- 0x0001, 0x0000, \
- 0x0000, 0x003c, \
- 0x000000c6, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_ICQ_4_65_3281 { \
- "ICQ Inc. - Product of ICQ (TM) 2000b.4.65.1.3281.85", \
- 0x010a, \
- 0x0004, 0x0041, \
- 0x0001, 0x0cd1, \
- 0x00000055, \
- "us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_ICQ_5_34_3728 { \
- "ICQ Inc. - Product of ICQ (TM).2002a.5.34.1.3728.85", \
- 0x010a, \
- 0x0005, 0x0022, \
- 0x0001, 0x0e8f, \
- 0x00000055, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICQ_5_45_3777 { \
- "ICQ Inc. - Product of ICQ (TM).2003a.5.45.1.3777.85", \
- 0x010a, \
- 0x0005, 0x002d, \
- 0x0001, 0x0ec1, \
- 0x00000055, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICQ6_6_0_6059 { \
- "ICQ Client", \
- 0x010a, \
- 0x0006, 0x0000, \
- 0x0000, 0x17ab, \
- 0x00007535, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICQBASIC_14_3_1068 { \
- "ICQBasic", \
- 0x010a, \
- 0x0014, 0x0003, \
- 0x0000, 0x042c, \
- 0x0000043d, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICQBASIC_14_34_3000 { \
- "ICQBasic", \
- 0x010a, \
- 0x0014, 0x0034, \
- 0x0000, 0x0bb8, \
- 0x0000043d, \
- "us", "en", \
-}
-
-#define CLIENTINFO_ICQBASIC_14_34_3096 { \
- "ICQBasic", \
- 0x010a, \
- 0x0014, 0x0034, \
- 0x0000, 0x0c18, \
- 0x0000043d, \
- "us", "en", \
-}
-
-#define CLIENTINFO_NETSCAPE_7_0_1 { \
- "Netscape 2000 an approved user of AOL Instant Messenger (SM)", \
- 0x1d0d, \
- 0x0007, 0x0000, \
- 0x0001, 0x0000, \
- 0x00000058, \
- "us", "en", \
-}
-
/*
* We need to use the major-minor-micro versions from the official
* AIM and ICQ programs here or AOL won't let us use certain features.
@@ -329,9 +158,6 @@ struct _ClientInfo
"us", "en", \
}
-#define CLIENTINFO_AIM_KNOWNGOOD CLIENTINFO_AIM_5_1_3036
-#define CLIENTINFO_ICQ_KNOWNGOOD CLIENTINFO_ICQBASIC_14_34_3096
-
typedef enum
{
OSCAR_DISCONNECT_DONE, /* not considered an error */
@@ -376,7 +202,24 @@ typedef enum
#define OSCAR_CAPABILITY_NEWCAPS 0x0000000020000000LL
#define OSCAR_CAPABILITY_XTRAZ 0x0000000040000000LL
#define OSCAR_CAPABILITY_GENERICUNKNOWN 0x0000000080000000LL
-#define OSCAR_CAPABILITY_LAST 0x0000000100000000LL
+#define OSCAR_CAPABILITY_HTML_MSGS 0x0000000100000000LL
+#define OSCAR_CAPABILITY_LAST 0x0000000200000000LL
+
+#define OSCAR_STATUS_ID_INVISIBLE "invisible"
+#define OSCAR_STATUS_ID_OFFLINE "offline"
+#define OSCAR_STATUS_ID_AVAILABLE "available"
+#define OSCAR_STATUS_ID_AWAY "away"
+#define OSCAR_STATUS_ID_DND "dnd"
+#define OSCAR_STATUS_ID_NA "na"
+#define OSCAR_STATUS_ID_OCCUPIED "occupied"
+#define OSCAR_STATUS_ID_FREE4CHAT "free4chat"
+#define OSCAR_STATUS_ID_CUSTOM "custom"
+#define OSCAR_STATUS_ID_MOBILE "mobile"
+#define OSCAR_STATUS_ID_EVIL "evil"
+#define OSCAR_STATUS_ID_DEPRESSION "depression"
+#define OSCAR_STATUS_ID_ATHOME "athome"
+#define OSCAR_STATUS_ID_ATWORK "atwork"
+#define OSCAR_STATUS_ID_LUNCH "lunch"
/*
* Byte Stream type. Sort of.
@@ -395,8 +238,8 @@ typedef enum
struct _ByteStream
{
guint8 *data;
- guint32 len;
- guint32 offset;
+ size_t len;
+ size_t offset;
};
struct _QueuedSnac
@@ -526,7 +369,7 @@ struct _OscarData
*/
IcbmCookie *msgcookies;
- struct aim_icq_info *icq_info;
+ GSList *icq_info;
/** Only used when connecting with the old-style BUCP login. */
struct aim_authresp_info *authinfo;
@@ -580,10 +423,8 @@ struct _OscarData
#define AIM_ICQ_STATE_WEBAWARE 0x00010000
#define AIM_ICQ_STATE_HIDEIP 0x00020000
#define AIM_ICQ_STATE_BIRTHDAY 0x00080000
-#define AIM_ICQ_STATE_DIRECTDISABLED 0x00100000
#define AIM_ICQ_STATE_ICQHOMEPAGE 0x00200000
#define AIM_ICQ_STATE_DIRECTREQUIREAUTH 0x10000000
-#define AIM_ICQ_STATE_DIRECTCONTACTLIST 0x20000000
/**
* Only used when connecting with the old-style BUCP login.
@@ -669,8 +510,8 @@ void flap_connection_send(FlapConnection *conn, FlapFrame *frame);
void flap_connection_send_version(OscarData *od, FlapConnection *conn);
void flap_connection_send_version_with_cookie(OscarData *od, FlapConnection *conn, guint16 length, const guint8 *chipsahoy);
void flap_connection_send_version_with_cookie_and_clientinfo(OscarData *od, FlapConnection *conn, guint16 length, const guint8 *chipsahoy, ClientInfo *ci, gboolean allow_multiple_login);
-void flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data);
-void flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data, gboolean high_priority);
+void flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, aim_snacid_t snacid, ByteStream *data);
+void flap_connection_send_snac_with_priority(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, aim_snacid_t snacid, ByteStream *data, gboolean high_priority);
void flap_connection_send_keepalive(OscarData *od, FlapConnection *conn);
FlapFrame *flap_frame_new(OscarData *od, guint16 channel, int datalen);
@@ -682,64 +523,26 @@ void oscar_data_destroy(OscarData *);
void oscar_data_addhandler(OscarData *od, guint16 family, guint16 subtype, aim_rxcallback_t newhandler, guint16 flags);
aim_rxcallback_t aim_callhandler(OscarData *od, guint16 family, guint16 subtype);
-/* misc.c */
-#define AIM_VISIBILITYCHANGE_PERMITADD 0x05
-#define AIM_VISIBILITYCHANGE_PERMITREMOVE 0x06
-#define AIM_VISIBILITYCHANGE_DENYADD 0x07
-#define AIM_VISIBILITYCHANGE_DENYREMOVE 0x08
-
-#define AIM_PRIVFLAGS_ALLOWIDLE 0x01
-#define AIM_PRIVFLAGS_ALLOWMEMBERSINCE 0x02
-
-#define AIM_WARN_ANON 0x01
-
-
-
/* 0x0001 - family_oservice.c */
/* 0x0002 */ void aim_srv_clientready(OscarData *od, FlapConnection *conn);
/* 0x0004 */ void aim_srv_requestnew(OscarData *od, guint16 serviceid);
/* 0x0006 */ void aim_srv_reqrates(OscarData *od, FlapConnection *conn);
/* 0x0008 */ void aim_srv_rates_addparam(OscarData *od, FlapConnection *conn);
-/* 0x0009 */ void aim_srv_rates_delparam(OscarData *od, FlapConnection *conn);
-/* 0x000c */ void aim_srv_sendpauseack(OscarData *od, FlapConnection *conn);
/* 0x000e */ void aim_srv_reqpersonalinfo(OscarData *od, FlapConnection *conn);
/* 0x0011 */ void aim_srv_setidle(OscarData *od, guint32 idletime);
-/* 0x0014 */ void aim_srv_setprivacyflags(OscarData *od, FlapConnection *conn, guint32);
-/* 0x0016 */ void aim_srv_nop(OscarData *od, FlapConnection *conn);
/* 0x0017 */ void aim_srv_setversions(OscarData *od, FlapConnection *conn);
/* 0x001e */ int aim_srv_setextrainfo(OscarData *od, gboolean seticqstatus, guint32 icqstatus, gboolean setstatusmsg, const char *statusmsg, const char *itmsurl);
+void aim_srv_set_dc_info(OscarData *od);
void aim_bos_reqrights(OscarData *od, FlapConnection *conn);
-int aim_bos_changevisibility(OscarData *od, FlapConnection *conn, int, const char *);
-void aim_bos_setgroupperm(OscarData *od, FlapConnection *conn, guint32 mask);
-
-
-#define AIM_CLIENTTYPE_UNKNOWN 0x0000
-#define AIM_CLIENTTYPE_MC 0x0001
-#define AIM_CLIENTTYPE_WINAIM 0x0002
-#define AIM_CLIENTTYPE_WINAIM41 0x0003
-#define AIM_CLIENTTYPE_AOL_TOC 0x0004
-guint16 aim_im_fingerprint(const guint8 *msghdr, int len);
-
-#define AIM_RATE_CODE_CHANGE 0x0001
-#define AIM_RATE_CODE_WARNING 0x0002
#define AIM_RATE_CODE_LIMIT 0x0003
-#define AIM_RATE_CODE_CLEARLIMIT 0x0004
-void aim_ads_requestads(OscarData *od, FlapConnection *conn);
-
-
/* family_icbm.c */
-#define AIM_OFT_SUBTYPE_SEND_FILE 0x0001
#define AIM_OFT_SUBTYPE_SEND_DIR 0x0002
-#define AIM_OFT_SUBTYPE_GET_FILE 0x0011
-#define AIM_OFT_SUBTYPE_GET_LIST 0x0012
-#define AIM_TRANSFER_DENY_NOTSUPPORTED 0x0000
#define AIM_TRANSFER_DENY_DECLINE 0x0001
-#define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002
#define AIM_IMPARAM_FLAG_CHANNEL_MSGS_ALLOWED 0x00000001
#define AIM_IMPARAM_FLAG_MISSED_CALLS_ENABLED 0x00000002
@@ -761,26 +564,6 @@ void aim_ads_requestads(OscarData *od, FlapConnection *conn);
*/
#define AIM_IMPARAM_FLAG_USE_HTML_FOR_ICQ 0x00000400
-/* This is what the server will give you if you don't set them yourself. */
-/* This is probably out of date. */
-#define AIM_IMPARAM_DEFAULTS { \
- 0, \
- AIM_IMPARAM_FLAG_CHANNEL_MSGS_ALLOWED | AIM_IMPARAM_FLAG_MISSED_CALLS_ENABLED, \
- 512, /* !! Note how small this is. */ \
- (99.9)*10, (99.9)*10, \
- 1000 /* !! And how large this is. */ \
-}
-
-/* This is what most AIM versions use. */
-/* This is probably out of date. */
-#define AIM_IMPARAM_REASONABLE { \
- 0, \
- AIM_IMPARAM_FLAG_CHANNEL_MSGS_ALLOWED | AIM_IMPARAM_FLAG_MISSED_CALLS_ENABLED, \
- 8000, \
- (99.9)*10, (99.9)*10, \
- 0 \
-}
-
struct aim_icbmparameters
{
guint16 maxchan;
@@ -827,9 +610,6 @@ void oscar_chat_destroy(struct chat_connection *cc);
#define AIM_IMFLAGS_HASICON 0x0020 /* already has icon */
#define AIM_IMFLAGS_SUBENC_MACINTOSH 0x0040 /* damn that Steve Jobs! */
#define AIM_IMFLAGS_CUSTOMFEATURES 0x0080 /* features field present */
-#define AIM_IMFLAGS_EXTDATA 0x0100
-#define AIM_IMFLAGS_X 0x0200
-#define AIM_IMFLAGS_MULTIPART 0x0400 /* ->mpmsg section valid */
#define AIM_IMFLAGS_OFFLINE 0x0800 /* send to offline user */
#define AIM_IMFLAGS_TYPINGNOT 0x1000 /* typing notification */
@@ -838,30 +618,6 @@ void oscar_chat_destroy(struct chat_connection *cc);
#define AIM_CHARSET_LATIN_1 0x0003 /* ISO 8859-1 */
/*
- * Multipart message structures.
- */
-typedef struct aim_mpmsg_section_s
-{
- guint16 charset;
- guint16 charsubset;
- gchar *data;
- guint16 datalen;
- struct aim_mpmsg_section_s *next;
-} aim_mpmsg_section_t;
-
-typedef struct aim_mpmsg_s
-{
- unsigned int numparts;
- aim_mpmsg_section_t *parts;
-} aim_mpmsg_t;
-
-int aim_mpmsg_init(OscarData *od, aim_mpmsg_t *mpm);
-int aim_mpmsg_addraw(OscarData *od, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, const gchar *data, guint16 datalen);
-int aim_mpmsg_addascii(OscarData *od, aim_mpmsg_t *mpm, const char *ascii);
-int aim_mpmsg_addunicode(OscarData *od, aim_mpmsg_t *mpm, const guint16 *unicode, guint16 unicodelen);
-void aim_mpmsg_free(OscarData *od, aim_mpmsg_t *mpm);
-
-/*
* Arguments to aim_send_im_ext().
*
* This is really complicated. But immensely versatile.
@@ -869,84 +625,39 @@ void aim_mpmsg_free(OscarData *od, aim_mpmsg_t *mpm);
*/
struct aim_sendimext_args
{
-
/* These are _required_ */
const char *destbn;
guint32 flags; /* often 0 */
- /* Only required if not using multipart messages */
const char *msg;
- int msglen;
-
- /* Required if ->msg is not provided */
- aim_mpmsg_t *mpmsg;
+ gsize msglen;
/* Only used if AIM_IMFLAGS_HASICON is set */
guint32 iconlen;
time_t iconstamp;
guint32 iconsum;
- /* Only used if AIM_IMFLAGS_CUSTOMFEATURES is set */
guint16 featureslen;
guint8 *features;
- /* Only used if AIM_IMFLAGS_CUSTOMCHARSET is set and mpmsg not used */
guint16 charset;
- guint16 charsubset;
-};
-
-/*
- * Arguments to aim_send_rtfmsg().
- */
-struct aim_sendrtfmsg_args
-{
- const char *destbn;
- guint32 fgcolor;
- guint32 bgcolor;
- const char *rtfmsg; /* must be in RTF */
};
/*
* This information is provided in the Incoming ICBM callback for
* Channel 1 ICBM's.
- *
- * Note that although CUSTOMFEATURES and CUSTOMCHARSET say they
- * are optional, both are always set by the current libfaim code.
- * That may or may not change in the future. It is mainly for
- * consistency with aim_sendimext_args.
- *
- * Multipart messages require some explanation. If you want to use them,
- * I suggest you read all the comments in family_icbm.c.
- *
*/
struct aim_incomingim_ch1_args
{
-
- /* Always provided */
- aim_mpmsg_t mpmsg;
guint32 icbmflags; /* some flags apply only to ->msg, not all mpmsg */
time_t timestamp; /* Only set for offline messages */
- /* Only provided if message has a human-readable section */
gchar *msg;
- int msglen;
/* Only provided if AIM_IMFLAGS_HASICON is set */
time_t iconstamp;
guint32 iconlen;
guint16 iconsum;
-
- /* Only provided if AIM_IMFLAGS_CUSTOMFEATURES is set */
- guint8 *features;
- guint8 featureslen;
-
- /* Only provided if AIM_IMFLAGS_EXTDATA is set */
- guint8 extdatalen;
- guint8 *extdata;
-
- /* Only used if AIM_IMFLAGS_CUSTOMCHARSET is set */
- guint16 charset;
- guint16 charsubset;
};
/* Valid values for channel 2 args->status */
@@ -981,10 +692,8 @@ struct _IcbmArgsCh2
struct aim_chat_roominfo roominfo;
} chat;
struct {
- guint16 msgtype;
- guint32 fgcolor;
- guint32 bgcolor;
- const char *rtfmsg;
+ guint8 msgtype;
+ const char *msg;
} rtfmsg;
struct {
guint16 subtype;
@@ -996,11 +705,6 @@ struct _IcbmArgsCh2
void *destructor; /* used internally only */
};
-/* Valid values for channel 4 args->type */
-#define AIM_ICQMSG_AUTHREQUEST 0x0006
-#define AIM_ICQMSG_AUTHDENIED 0x0007
-#define AIM_ICQMSG_AUTHGRANTED 0x0008
-
struct aim_incomingim_ch4_args
{
guint32 uin; /* Of the sender of the ICBM */
@@ -1017,7 +721,6 @@ struct aim_incomingim_ch4_args
/* 0x0006 */ int aim_im_sendch1(OscarData *, const char *destbn, guint16 flags, const char *msg);
/* 0x0006 */ int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, guint16 exchange, const char *roomname, guint16 instance);
/* 0x0006 */ int aim_im_sendch2_icon(OscarData *od, const char *bn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum);
-/* 0x0006 */ int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args);
/* 0x0006 */ void aim_im_sendch2_cancel(PeerConnection *peer_conn);
/* 0x0006 */ void aim_im_sendch2_connected(PeerConnection *peer_conn);
@@ -1026,38 +729,23 @@ struct aim_incomingim_ch4_args
/* 0x0006 */ void aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles);
/* 0x0006 */ void aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles);
-/* 0x0006 */ int aim_im_sendch2_geticqaway(OscarData *od, const char *bn, int type);
-/* 0x0006 */ int aim_im_sendch4(OscarData *od, const char *bn, guint16 type, const char *message);
-/* 0x0008 */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *destbn, guint32 flags);
/* 0x000b */ int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, guint16 code);
/* 0x0010 */ int aim_im_reqofflinemsgs(OscarData *od);
/* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *bn, guint16 type2);
/* 0x000b */ int icq_relay_xstatus (OscarData *od, const char *sn, const guchar* cookie);
void aim_icbm_makecookie(guchar* cookie);
-gchar *oscar_encoding_extract(const char *encoding);
-gchar *oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen);
-gchar *purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcebn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen);
-
+void aim_im_send_icq_confirmation(OscarData *od, const char *bn, const guchar *cookie);
/* 0x0002 - family_locate.c */
/*
* AIM User Info, Standard Form.
*/
-#define AIM_FLAG_UNCONFIRMED 0x0001 /* "damned transients" */
#define AIM_FLAG_ADMINISTRATOR 0x0002
#define AIM_FLAG_AOL 0x0004
-#define AIM_FLAG_OSCAR_PAY 0x0008
-#define AIM_FLAG_FREE 0x0010
#define AIM_FLAG_AWAY 0x0020
-#define AIM_FLAG_ICQ 0x0040
#define AIM_FLAG_WIRELESS 0x0080
-#define AIM_FLAG_UNKNOWN100 0x0100
-#define AIM_FLAG_IMFORWARDING 0x0200
+#define AIM_FLAG_ICQ 0x0040
#define AIM_FLAG_ACTIVEBUDDY 0x0400
-#define AIM_FLAG_UNKNOWN800 0x0800
-#define AIM_FLAG_ONEWAYWIRELESS 0x1000
-#define AIM_FLAG_NOKNOCKKNOCK 0x00040000
-#define AIM_FLAG_FORWARD_MOBILE 0x00080000
#define AIM_USERINFO_PRESENT_FLAGS 0x00000001
#define AIM_USERINFO_PRESENT_MEMBERSINCE 0x00000002
@@ -1130,22 +818,8 @@ struct aim_invite_priv
guint16 instance;
};
-#define AIM_COOKIETYPE_UNKNOWN 0x00
-#define AIM_COOKIETYPE_ICBM 0x01
-#define AIM_COOKIETYPE_ADS 0x02
-#define AIM_COOKIETYPE_BOS 0x03
-#define AIM_COOKIETYPE_IM 0x04
-#define AIM_COOKIETYPE_CHAT 0x05
-#define AIM_COOKIETYPE_CHATNAV 0x06
-#define AIM_COOKIETYPE_INVITE 0x07
-/* we'll move OFT up a bit to give breathing room. not like it really
- * matters. */
-#define AIM_COOKIETYPE_OFTIM 0x10
-#define AIM_COOKIETYPE_OFTGET 0x11
-#define AIM_COOKIETYPE_OFTSEND 0x12
-#define AIM_COOKIETYPE_OFTVOICE 0x13
-#define AIM_COOKIETYPE_OFTIMAGE 0x14
-#define AIM_COOKIETYPE_OFTICON 0x15
+#define AIM_COOKIETYPE_CHAT 0x01
+#define AIM_COOKIETYPE_INVITE 0x02
aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *bn);
void aim_locate_dorequest(OscarData *od);
@@ -1153,10 +827,6 @@ void aim_locate_dorequest(OscarData *od);
/* 0x0002 */ int aim_locate_reqrights(OscarData *od);
/* 0x0004 */ int aim_locate_setcaps(OscarData *od, guint64 caps);
/* 0x0004 */ int aim_locate_setprofile(OscarData *od, const char *profile_encoding, const gchar *profile, const int profile_len, const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len);
-/* 0x0005 */ int aim_locate_getinfo(OscarData *od, const char *, guint16);
-/* 0x0009 */ 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);
-/* 0x000b */ int aim_locate_000b(OscarData *od, const char *bn);
-/* 0x000f */ int aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy);
/* 0x0015 */ int aim_locate_getinfoshort(OscarData *od, const char *bn, guint32 flags);
guint64 aim_locate_getcaps(OscarData *od, ByteStream *bs, int len);
@@ -1171,25 +841,11 @@ int icq_im_xstatus_request(OscarData *od, const char *sn);
/* 0x0003 - family_buddy.c */
/* 0x0002 */ void aim_buddylist_reqrights(OscarData *, FlapConnection *);
-/* 0x0004 */ int aim_buddylist_set(OscarData *, FlapConnection *, const char *);
-/* 0x0004 */ int aim_buddylist_addbuddy(OscarData *, FlapConnection *, const char *);
-/* 0x0005 */ int aim_buddylist_removebuddy(OscarData *, FlapConnection *, const char *);
-
/* 0x000a - family_userlookup.c */
int aim_search_address(OscarData *, const char *);
-
-
-/* 0x000d - family_chatnav.c */
-/* 0x000e - family_chat.c */
-/* These apply to exchanges as well. */
-#define AIM_CHATROOM_FLAG_EVILABLE 0x0001
-#define AIM_CHATROOM_FLAG_NAV_ONLY 0x0002
-#define AIM_CHATROOM_FLAG_INSTANCING_ALLOWED 0x0004
-#define AIM_CHATROOM_FLAG_OCCUPANT_PEEK_ALLOWED 0x0008
-
struct aim_chat_exchangeinfo
{
guint16 number;
@@ -1205,41 +861,10 @@ struct aim_chat_exchangeinfo
#define AIM_CHATFLAGS_AWAY 0x0002
int aim_chat_send_im(OscarData *od, FlapConnection *conn, guint16 flags, const gchar *msg, int msglen, const char *encoding, const char *language);
int aim_chat_join(OscarData *od, guint16 exchange, const char *roomname, guint16 instance);
-int aim_chat_attachname(FlapConnection *conn, guint16 exchange, const char *roomname, guint16 instance);
-char *aim_chat_getname(FlapConnection *conn);
-FlapConnection *aim_chat_getconn(OscarData *, const char *name);
void aim_chatnav_reqrights(OscarData *od, FlapConnection *conn);
int aim_chatnav_createroom(OscarData *od, FlapConnection *conn, const char *name, guint16 exchange);
-int aim_chat_leaveroom(OscarData *od, const char *name);
-
-
-
-/* 0x000f - family_odir.c */
-struct aim_odir
-{
- char *first;
- char *last;
- char *middle;
- char *maiden;
- char *email;
- char *country;
- char *state;
- char *city;
- char *bn;
- char *interest;
- char *nick;
- char *zip;
- char *region;
- char *address;
- struct aim_odir *next;
-};
-
-int aim_odir_email(OscarData *, const char *, const char *);
-int aim_odir_name(OscarData *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *);
-int aim_odir_interest(OscarData *, const char *, const char *);
-
/* 0x0010 - family_bart.c */
@@ -1255,15 +880,9 @@ int aim_bart_request(OscarData *od, const char *bn, guint8 iconcsumtype, const g
#define AIM_SSI_TYPE_DENY 0x0003
#define AIM_SSI_TYPE_PDINFO 0x0004
#define AIM_SSI_TYPE_PRESENCEPREFS 0x0005
+#define AIM_SSI_TYPE_ICQDENY 0x000e
#define AIM_SSI_TYPE_ICONINFO 0x0014
-#define AIM_SSI_ACK_SUCCESS 0x0000
-#define AIM_SSI_ACK_ITEMNOTFOUND 0x0002
-#define AIM_SSI_ACK_IDNUMINUSE 0x000a
-#define AIM_SSI_ACK_ATMAX 0x000c
-#define AIM_SSI_ACK_INVALIDNAME 0x000d
-#define AIM_SSI_ACK_AUTHREQUIRED 0x000e
-
/* These flags are set in the 0x00c9 TLV of SSI type 0x0005 */
#define AIM_SSI_PRESENCE_FLAG_SHOWIDLE 0x00000400
#define AIM_SSI_PRESENCE_FLAG_NORECENTBUDDIES 0x00020000
@@ -1290,11 +909,9 @@ struct aim_ssi_tmp
/* These build the actual SNACs and queue them to be sent */
/* 0x0002 */ int aim_ssi_reqrights(OscarData *od);
/* 0x0004 */ int aim_ssi_reqdata(OscarData *od);
-/* 0x0005 */ int aim_ssi_reqifchanged(OscarData *od, time_t localstamp, guint16 localrev);
/* 0x0007 */ int aim_ssi_enable(OscarData *od);
/* 0x0011 */ int aim_ssi_modbegin(OscarData *od);
/* 0x0012 */ int aim_ssi_modend(OscarData *od);
-/* 0x0014 */ int aim_ssi_sendauth(OscarData *od, char *bn, char *msg);
/* 0x0018 */ int aim_ssi_sendauthrequest(OscarData *od, char *bn, const char *msg);
/* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, char *bn, guint8 reply, const char *msg);
@@ -1311,49 +928,22 @@ gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const
/* Client functions for changing SSI data */
int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth);
-int aim_ssi_addpermit(OscarData *od, const char *name);
-int aim_ssi_adddeny(OscarData *od, const char *name);
int aim_ssi_delbuddy(OscarData *od, const char *name, const char *group);
int aim_ssi_delgroup(OscarData *od, const char *group);
-int aim_ssi_delpermit(OscarData *od, const char *name);
-int aim_ssi_deldeny(OscarData *od, const char *name);
int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *bn);
int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *bn, const char *alias);
int aim_ssi_editcomment(OscarData *od, const char *gn, const char *bn, const char *alias);
int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn);
int aim_ssi_cleanlist(OscarData *od);
int aim_ssi_deletelist(OscarData *od);
-int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask);
+int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny);
int aim_ssi_setpresence(OscarData *od, guint32 presence);
int aim_ssi_seticon(OscarData *od, const guint8 *iconsum, guint8 iconsumlen);
int aim_ssi_delicon(OscarData *od);
+int aim_ssi_add_to_private_list(OscarData *od, const char* name, guint16 list_type);
+int aim_ssi_del_from_private_list(OscarData* od, const char* name, guint16 list_type);
-
-
-/* 0x0015 - family_icq.c */
-#define AIM_ICQ_INFO_SIMPLE 0x001
-#define AIM_ICQ_INFO_SUMMARY 0x002
-#define AIM_ICQ_INFO_EMAIL 0x004
-#define AIM_ICQ_INFO_PERSONAL 0x008
-#define AIM_ICQ_INFO_ADDITIONAL 0x010
-#define AIM_ICQ_INFO_WORK 0x020
-#define AIM_ICQ_INFO_INTERESTS 0x040
-#define AIM_ICQ_INFO_ORGS 0x080
-#define AIM_ICQ_INFO_UNKNOWN 0x100
-#define AIM_ICQ_INFO_HAVEALL 0x1ff
-
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
-struct aim_icq_offlinemsg
-{
- guint32 sender;
- guint16 year;
- guint8 month, day, hour, minute;
- guint8 type;
- guint8 flags;
- char *msg;
- int msglen;
-};
-#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
+guint16 aim_ssi_getdenyentrytype(OscarData* od);
struct aim_icq_info
{
@@ -1410,22 +1000,17 @@ struct aim_icq_info
guint16 numaddresses;
char **email2;
- /* we keep track of these in a linked list because we're 1337 */
- struct aim_icq_info *next;
-
/* status note info */
guint8 icbm_cookie[8];
char *status_note_title;
+
+ gboolean for_auth_request;
+ char *auth_request_reason;
};
-#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
-int aim_icq_reqofflinemsgs(OscarData *od);
-int aim_icq_ackofflinemsgs(OscarData *od);
-#endif
int aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware);
int aim_icq_changepasswd(OscarData *od, const char *passwd);
-int aim_icq_getsimpleinfo(OscarData *od, const char *uin);
-int aim_icq_getalias(OscarData *od, const char *uin);
+int aim_icq_getalias(OscarData *od, const char *uin, gboolean for_auth_request, char *auth_request_reason);
int aim_icq_getallinfo(OscarData *od, const char *uin);
int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias);
@@ -1565,17 +1150,13 @@ const char *oscar_get_ui_info_string(const char *str, const char *default_value)
gchar *oscar_get_clientstring(void);
guint16 aimutil_iconsum(const guint8 *buf, int buflen);
-int aimutil_tokslen(char *toSearch, int theindex, char dl);
-int aimutil_itemcnt(char *toSearch, char dl);
-char *aimutil_itemindex(char *toSearch, int theindex, char dl);
gboolean oscar_util_valid_name(const char *bn);
gboolean oscar_util_valid_name_icq(const char *bn);
gboolean oscar_util_valid_name_sms(const char *bn);
int oscar_util_name_compare(const char *bn1, const char *bn2);
-
-
-
+gchar *oscar_util_format_string(const char *str, const char *name);
+gchar *oscar_format_buddies(GSList *buddies, const gchar *no_buddies_message);
typedef struct {
guint16 family;
@@ -1617,11 +1198,7 @@ int chatnav_modfirst(OscarData *od, aim_module_t *mod);
int chat_modfirst(OscarData *od, aim_module_t *mod);
int locate_modfirst(OscarData *od, aim_module_t *mod);
int service_modfirst(OscarData *od, aim_module_t *mod);
-int invite_modfirst(OscarData *od, aim_module_t *mod);
-int translate_modfirst(OscarData *od, aim_module_t *mod);
int popups_modfirst(OscarData *od, aim_module_t *mod);
-int adverts_modfirst(OscarData *od, aim_module_t *mod);
-int odir_modfirst(OscarData *od, aim_module_t *mod);
int bart_modfirst(OscarData *od, aim_module_t *mod);
int ssi_modfirst(OscarData *od, aim_module_t *mod);
int icq_modfirst(OscarData *od, aim_module_t *mod);
@@ -1630,15 +1207,14 @@ int email_modfirst(OscarData *od, aim_module_t *mod);
void aim_genericreq_n(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype);
void aim_genericreq_n_snacid(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype);
void aim_genericreq_l(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint32 *);
-void aim_genericreq_s(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint16 *);
/* bstream.c */
-int byte_stream_new(ByteStream *bs, guint32 len);
-int byte_stream_init(ByteStream *bs, guint8 *data, int len);
+int byte_stream_new(ByteStream *bs, size_t len);
+int byte_stream_init(ByteStream *bs, guint8 *data, size_t len);
void byte_stream_destroy(ByteStream *bs);
-int byte_stream_empty(ByteStream *bs);
+int byte_stream_bytes_left(ByteStream *bs);
int byte_stream_curpos(ByteStream *bs);
-int byte_stream_setpos(ByteStream *bs, unsigned int off);
+int byte_stream_setpos(ByteStream *bs, size_t off);
void byte_stream_rewind(ByteStream *bs);
int byte_stream_advance(ByteStream *bs, int n);
guint8 byte_stream_get8(ByteStream *bs);
@@ -1647,18 +1223,18 @@ guint32 byte_stream_get32(ByteStream *bs);
guint8 byte_stream_getle8(ByteStream *bs);
guint16 byte_stream_getle16(ByteStream *bs);
guint32 byte_stream_getle32(ByteStream *bs);
-int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, int len);
-guint8 *byte_stream_getraw(ByteStream *bs, int len);
-char *byte_stream_getstr(ByteStream *bs, int len);
+int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, size_t len);
+guint8 *byte_stream_getraw(ByteStream *bs, size_t len);
+char *byte_stream_getstr(ByteStream *bs, size_t len);
int byte_stream_put8(ByteStream *bs, guint8 v);
int byte_stream_put16(ByteStream *bs, guint16 v);
int byte_stream_put32(ByteStream *bs, guint32 v);
int byte_stream_putle8(ByteStream *bs, guint8 v);
int byte_stream_putle16(ByteStream *bs, guint16 v);
int byte_stream_putle32(ByteStream *bs, guint32 v);
-int byte_stream_putraw(ByteStream *bs, const guint8 *v, int len);
+int byte_stream_putraw(ByteStream *bs, const guint8 *v, size_t len);
int byte_stream_putstr(ByteStream *bs, const char *str);
-int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, int len);
+int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, size_t len);
int byte_stream_putuid(ByteStream *bs, OscarData *od);
int byte_stream_putcaps(ByteStream *bs, guint64 caps);
@@ -1693,7 +1269,7 @@ aim_snacid_t aim_newsnac(OscarData *, aim_snac_t *newsnac);
aim_snacid_t aim_cachesnac(OscarData *od, const guint16 family, const guint16 type, const guint16 flags, const void *data, const int datalen);
aim_snac_t *aim_remsnac(OscarData *, aim_snacid_t id);
void aim_cleansnacs(OscarData *, int maxage);
-int aim_putsnac(ByteStream *, guint16 family, guint16 type, guint16 flags, aim_snacid_t id);
+int aim_putsnac(ByteStream *, guint16 family, guint16 type, aim_snacid_t id);
struct chatsnacinfo {
guint16 exchange;
@@ -1720,13 +1296,53 @@ IcbmCookie *aim_uncachecookie(OscarData *od, guint8 *cookie, int type);
IcbmCookie *aim_mkcookie(guint8 *, int, void *);
IcbmCookie *aim_checkcookie(OscarData *, const unsigned char *, const int);
int aim_freecookie(OscarData *od, IcbmCookie *cookie);
-int aim_msgcookie_gettype(guint64 type);
int aim_cookie_free(OscarData *od, IcbmCookie *cookie);
int aim_chat_readroominfo(ByteStream *bs, struct aim_chat_roominfo *outinfo);
void flap_connection_destroy_chat(OscarData *od, FlapConnection *conn);
+/* userinfo.c - displaying user information */
+
+void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags);
+void oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo);
+void oscar_user_info_display_error(OscarData *od, guint16 error_reason, char *buddy);
+void oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info);
+void oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo);
+
+/* authorization.c - OSCAR authorization requests */
+void oscar_auth_sendrequest(PurpleConnection *gc, const char *name);
+void oscar_auth_sendrequest_menu(PurpleBlistNode *node, gpointer ignored);
+void oscar_auth_recvrequest(PurpleConnection *gc, gchar *name, gchar *nick, gchar *reason);
+
+void oscar_set_aim_permdeny(PurpleConnection *gc);
+
+struct buddyinfo
+{
+ gboolean typingnot;
+ guint32 ipaddr;
+
+ unsigned long ico_me_len;
+ unsigned long ico_me_csum;
+ time_t ico_me_time;
+ gboolean ico_informed;
+
+ unsigned long ico_len;
+ unsigned long ico_csum;
+ time_t ico_time;
+ gboolean ico_need;
+ gboolean ico_sent;
+};
+
+struct name_data
+{
+ PurpleConnection *gc;
+ gchar *name;
+ gchar *nick;
+};
+
+void oscar_free_name_data(struct name_data *data);
+
#ifdef __cplusplus
}
#endif
diff --git a/libpurple/protocols/oscar/oscar_data.c b/libpurple/protocols/oscar/oscar_data.c
index dcc43baa5d..8c0a9e17d9 100644
--- a/libpurple/protocols/oscar/oscar_data.c
+++ b/libpurple/protocols/oscar/oscar_data.c
@@ -53,17 +53,13 @@ oscar_data_new(void)
aim__registermodule(od, locate_modfirst);
aim__registermodule(od, buddylist_modfirst);
aim__registermodule(od, msg_modfirst);
- /* aim__registermodule(od, adverts_modfirst); */
- /* aim__registermodule(od, invite_modfirst); */
aim__registermodule(od, admin_modfirst);
aim__registermodule(od, popups_modfirst);
aim__registermodule(od, bos_modfirst);
aim__registermodule(od, search_modfirst);
aim__registermodule(od, stats_modfirst);
- /* aim__registermodule(od, translate_modfirst); */
aim__registermodule(od, chatnav_modfirst);
aim__registermodule(od, chat_modfirst);
- aim__registermodule(od, odir_modfirst);
aim__registermodule(od, bart_modfirst);
/* missing 0x11 - 0x12 */
aim__registermodule(od, ssi_modfirst);
diff --git a/libpurple/protocols/oscar/oscarcommon.h b/libpurple/protocols/oscar/oscarcommon.h
index a7af4cb62f..52433e5f99 100644
--- a/libpurple/protocols/oscar/oscarcommon.h
+++ b/libpurple/protocols/oscar/oscarcommon.h
@@ -77,7 +77,6 @@ void oscar_add_permit(PurpleConnection *gc, const char *who);
void oscar_add_deny(PurpleConnection *gc, const char *who);
void oscar_rem_permit(PurpleConnection *gc, const char *who);
void oscar_rem_deny(PurpleConnection *gc, const char *who);
-void oscar_set_permit_deny(PurpleConnection *gc);
void oscar_join_chat(PurpleConnection *gc, GHashTable *data);
char *oscar_get_chat_name(GHashTable *data);
void oscar_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name);
diff --git a/libpurple/protocols/oscar/peer_proxy.c b/libpurple/protocols/oscar/peer_proxy.c
index 1ef991b704..6bf5c07c80 100644
--- a/libpurple/protocols/oscar/peer_proxy.c
+++ b/libpurple/protocols/oscar/peer_proxy.c
@@ -32,8 +32,8 @@ peer_proxy_send(PeerConnection *conn, ProxyFrame *frame)
ByteStream bs;
purple_debug_info("oscar", "Outgoing peer proxy frame with "
- "type=0x%04hx, unknown=0x%08x, "
- "flags=0x%04hx, and payload length=%hd\n",
+ "type=0x%04hx, unknown=0x%08x, flags=0x%04hx, and "
+ "payload length=%" G_GSIZE_FORMAT "\n",
frame->type, frame->unknown,
frame->flags, frame->payload.len);
@@ -129,8 +129,8 @@ static void
peer_proxy_recv_frame(PeerConnection *conn, ProxyFrame *frame)
{
purple_debug_info("oscar", "Incoming peer proxy frame with "
- "type=0x%04hx, unknown=0x%08x, "
- "flags=0x%04hx, and payload length=%hd\n", frame->type,
+ "type=0x%04hx, unknown=0x%08x, flags=0x%04hx, and "
+ "payload length=%" G_GSIZE_FORMAT "\n", frame->type,
frame->unknown, frame->flags, frame->payload.len);
if (frame->type == PEER_PROXY_TYPE_CREATED)
@@ -168,7 +168,7 @@ peer_proxy_recv_frame(PeerConnection *conn, ProxyFrame *frame)
}
else if (frame->type == PEER_PROXY_TYPE_ERROR)
{
- if (byte_stream_empty(&frame->payload) >= 2)
+ if (byte_stream_bytes_left(&frame->payload) >= 2)
{
guint16 error;
const char *msg;
diff --git a/libpurple/protocols/oscar/rxhandlers.c b/libpurple/protocols/oscar/rxhandlers.c
index d378624d35..75675a9fbe 100644
--- a/libpurple/protocols/oscar/rxhandlers.c
+++ b/libpurple/protocols/oscar/rxhandlers.c
@@ -95,194 +95,3 @@ void aim__shutdownmodules(OscarData *od)
return;
}
-
-#if 0
-/*
- * Bleck functions get called when there's no non-bleck functions
- * around to cleanup the mess...
- */
-static int bleck(OscarData *od, FlapFrame *frame, ...)
-{
- guint16 family, subtype;
- guint16 maxf, maxs;
-
- static const char *channels[6] = {
- "Invalid (0)",
- "FLAP Version",
- "SNAC",
- "Invalid (3)",
- "Negotiation",
- "FLAP NOP"
- };
- static const int maxchannels = 5;
-
- /* XXX: this is ugly. and big just for debugging. */
- static const char *literals[14][25] = {
- {"Invalid",
- NULL
- },
- {"General",
- "Invalid",
- "Error",
- "Client Ready",
- "Server Ready",
- "Service Request",
- "Redirect",
- "Rate Information Request",
- "Rate Information",
- "Rate Information Ack",
- NULL,
- "Rate Information Change",
- "Server Pause",
- NULL,
- "Server Resume",
- "Request Personal User Information",
- "Personal User Information",
- "Evil Notification",
- NULL,
- "Migration notice",
- "Message of the Day",
- "Set Privacy Flags",
- "Well Known URL",
- "NOP"
- },
- {"Location",
- "Invalid",
- "Error",
- "Request Rights",
- "Rights Information",
- "Set user information",
- "Request User Information",
- "User Information",
- "Watcher Sub Request",
- "Watcher Notification"
- },
- {"Buddy List Management",
- "Invalid",
- "Error",
- "Request Rights",
- "Rights Information",
- "Add Buddy",
- "Remove Buddy",
- "Watcher List Query",
- "Watcher List Response",
- "Watcher SubRequest",
- "Watcher Notification",
- "Reject Notification",
- "Oncoming Buddy",
- "Offgoing Buddy"
- },
- {"Messeging",
- "Invalid",
- "Error",
- "Add ICBM Parameter",
- "Remove ICBM Parameter",
- "Request Parameter Information",
- "Parameter Information",
- "Outgoing Message",
- "Incoming Message",
- "Evil Request",
- "Evil Reply",
- "Missed Calls",
- "Message Error",
- "Host Ack"
- },
- {"Advertisements",
- "Invalid",
- "Error",
- "Request Ad",
- "Ad Data (GIFs)"
- },
- {"Invitation / Client-to-Client",
- "Invalid",
- "Error",
- "Invite a Friend",
- "Invitation Ack"
- },
- {"Administrative",
- "Invalid",
- "Error",
- "Information Request",
- "Information Reply",
- "Information Change Request",
- "Information Chat Reply",
- "Account Confirm Request",
- "Account Confirm Reply",
- "Account Delete Request",
- "Account Delete Reply"
- },
- {"Popups",
- "Invalid",
- "Error",
- "Display Popup"
- },
- {"BOS",
- "Invalid",
- "Error",
- "Request Rights",
- "Rights Response",
- "Set group permission mask",
- "Add permission list entries",
- "Delete permission list entries",
- "Add deny list entries",
- "Delete deny list entries",
- "Server Error"
- },
- {"User Lookup",
- "Invalid",
- "Error",
- "Search Request",
- "Search Response"
- },
- {"Stats",
- "Invalid",
- "Error",
- "Set minimum report interval",
- "Report Events"
- },
- {"Translate",
- "Invalid",
- "Error",
- "Translate Request",
- "Translate Reply",
- },
- {"Chat Navigation",
- "Invalid",
- "Error",
- "Request rights",
- "Request Exchange Information",
- "Request Room Information",
- "Request Occupant List",
- "Search for Room",
- "Outgoing Message",
- "Incoming Message",
- "Evil Request",
- "Evil Reply",
- "Chat Error",
- }
- };
-
- maxf = sizeof(literals) / sizeof(literals[0]);
- maxs = sizeof(literals[0]) / sizeof(literals[0][0]);
-
- if (frame->channel == 0x02) {
-
- family = byte_stream_get16(&frame->data);
- subtype = byte_stream_get16(&frame->data);
-
- if ((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL))
- purple_debug_misc("oscar", "bleck: channel %s: null handler for %04x/%04x (%s)\n", channels[frame->channel], family, subtype, literals[family][subtype+1]);
- else
- purple_debug_misc("oscar", "bleck: channel %s: null handler for %04x/%04x (no literal)\n", channels[frame->channel], family, subtype);
- } else {
-
- if (frame->channel <= maxchannels)
- purple_debug_misc("oscar", "bleck: channel %s (0x%02x)\n", channels[frame->channel], frame->channel);
- else
- purple_debug_misc("oscar", "bleck: unknown channel 0x%02x\n", frame->channel);
-
- }
-
- return 1;
-}
-#endif
diff --git a/libpurple/protocols/oscar/snac.c b/libpurple/protocols/oscar/snac.c
index 8a9179dffc..451dfc6647 100644
--- a/libpurple/protocols/oscar/snac.c
+++ b/libpurple/protocols/oscar/snac.c
@@ -151,12 +151,12 @@ void aim_cleansnacs(OscarData *od, int maxage)
return;
}
-int aim_putsnac(ByteStream *bs, guint16 family, guint16 subtype, guint16 flags, aim_snacid_t snacid)
+int aim_putsnac(ByteStream *bs, guint16 family, guint16 subtype, aim_snacid_t snacid)
{
byte_stream_put16(bs, family);
byte_stream_put16(bs, subtype);
- byte_stream_put16(bs, flags);
+ byte_stream_put16(bs, 0x0000);
byte_stream_put32(bs, snacid);
return 10;
diff --git a/libpurple/protocols/oscar/tlv.c b/libpurple/protocols/oscar/tlv.c
index 8c93f98005..67f18080c3 100644
--- a/libpurple/protocols/oscar/tlv.c
+++ b/libpurple/protocols/oscar/tlv.c
@@ -49,27 +49,7 @@ aim_tlv_read(GSList *list, ByteStream *bs)
type = byte_stream_get16(bs);
length = byte_stream_get16(bs);
-#if 0
- /*
- * This code hasn't been needed in years. It's been commented
- * out since 2003, at the latest. It seems likely that it was
- * just a bug in their server code that has since been fixed.
- * In any case, here's the orignal comment, kept for historical
- * purposes:
- *
- * Okay, so now AOL has decided that any TLV of
- * type 0x0013 can only be two bytes, despite
- * what the actual given length is. So here
- * we dump any invalid TLVs of that sort. Hopefully
- * there's no special cases to this special case.
- * - mid (30jun2000)
- */
- if ((type == 0x0013) && (length != 0x0002)) {
- length = 0x0002;
- return list;
- }
-#endif
- if (length > byte_stream_empty(bs)) {
+ if (length > byte_stream_bytes_left(bs)) {
aim_tlvlist_free(list);
return NULL;
}
@@ -108,7 +88,7 @@ GSList *aim_tlvlist_read(ByteStream *bs)
{
GSList *list = NULL;
- while (byte_stream_empty(bs) > 0) {
+ while (byte_stream_bytes_left(bs) > 0) {
list = aim_tlv_read(list, bs);
if (list == NULL)
return NULL;
@@ -142,7 +122,7 @@ GSList *aim_tlvlist_readnum(ByteStream *bs, guint16 num)
{
GSList *list = NULL;
- while ((byte_stream_empty(bs) > 0) && (num != 0)) {
+ while ((byte_stream_bytes_left(bs) > 0) && (num != 0)) {
list = aim_tlv_read(list, bs);
if (list == NULL)
return NULL;
@@ -177,7 +157,7 @@ GSList *aim_tlvlist_readlen(ByteStream *bs, guint16 len)
{
GSList *list = NULL;
- while ((byte_stream_empty(bs) > 0) && (len > 0)) {
+ while ((byte_stream_bytes_left(bs) > 0) && (len > 0)) {
list = aim_tlv_read(list, bs);
if (list == NULL)
return NULL;
@@ -391,6 +371,17 @@ int aim_tlvlist_add_str(GSList **list, const guint16 type, const char *value)
return aim_tlvlist_add_raw(list, type, strlen(value), (guint8 *)value);
}
+static int
+count_caps(guint64 caps)
+{
+ int set_bits = 0;
+ while (caps) {
+ set_bits += caps & 1;
+ caps >>= 1;
+ }
+ return set_bits;
+}
+
/**
* Adds a block of capability blocks to a TLV chain. The bitfield
* passed in should be a bitwise %OR of any of the %AIM_CAPS constants:
@@ -409,23 +400,24 @@ int aim_tlvlist_add_str(GSList **list, const guint16 type, const char *value)
*/
int aim_tlvlist_add_caps(GSList **list, const guint16 type, const guint64 caps, const char *mood)
{
- guint8 buf[256]; /* TODO: Don't use a fixed length buffer */
ByteStream bs;
+ guint32 bs_size;
guint8 *data;
if (caps == 0)
return 0; /* nothing there anyway */
- byte_stream_init(&bs, buf, sizeof(buf));
+ data = icq_get_custom_icon_data(mood);
+ bs_size = 16*(count_caps(caps) + (data != NULL ? 1 : 0));
+ byte_stream_new(&bs, bs_size);
byte_stream_putcaps(&bs, caps);
-
+
/* adding of custom icon GUID */
- data = icq_get_custom_icon_data(mood);
if (data != NULL)
byte_stream_putraw(&bs, data, 16);
- return aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), buf);
+ return aim_tlvlist_add_raw(list, type, byte_stream_curpos(&bs), bs.data);
}
/**
@@ -668,7 +660,7 @@ int aim_tlvlist_write(ByteStream *bs, GSList **list)
/* do an initial run to test total length */
goodbuflen = aim_tlvlist_size(*list);
- if (goodbuflen > byte_stream_empty(bs))
+ if (goodbuflen > byte_stream_bytes_left(bs))
return 0; /* not enough buffer */
/* do the real write-out */
diff --git a/libpurple/protocols/oscar/userinfo.c b/libpurple/protocols/oscar/userinfo.c
new file mode 100644
index 0000000000..5762977ad6
--- /dev/null
+++ b/libpurple/protocols/oscar/userinfo.c
@@ -0,0 +1,553 @@
+/*
+ * Purple's oscar protocol plugin
+ * This file is the legal property of its developers.
+ * Please see the AUTHORS file distributed alongside this file.
+ *
+ * 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 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
+*/
+
+/*
+ * Displaying various information about buddies.
+ */
+
+#include "encoding.h"
+#include "oscar.h"
+
+static gchar *
+oscar_caps_to_string(guint64 caps)
+{
+ GString *str;
+ const gchar *tmp;
+ guint64 bit = 1;
+
+ str = g_string_new("");
+
+ if (!caps) {
+ return NULL;
+ } else while (bit <= OSCAR_CAPABILITY_LAST) {
+ if (bit & caps) {
+ switch (bit) {
+ case OSCAR_CAPABILITY_BUDDYICON:
+ tmp = _("Buddy Icon");
+ break;
+ case OSCAR_CAPABILITY_TALK:
+ tmp = _("Voice");
+ break;
+ case OSCAR_CAPABILITY_DIRECTIM:
+ tmp = _("AIM Direct IM");
+ break;
+ case OSCAR_CAPABILITY_CHAT:
+ tmp = _("Chat");
+ break;
+ case OSCAR_CAPABILITY_GETFILE:
+ tmp = _("Get File");
+ break;
+ case OSCAR_CAPABILITY_SENDFILE:
+ tmp = _("Send File");
+ break;
+ case OSCAR_CAPABILITY_GAMES:
+ case OSCAR_CAPABILITY_GAMES2:
+ tmp = _("Games");
+ break;
+ case OSCAR_CAPABILITY_XTRAZ:
+ case OSCAR_CAPABILITY_NEWCAPS:
+ tmp = _("ICQ Xtraz");
+ break;
+ case OSCAR_CAPABILITY_ADDINS:
+ tmp = _("Add-Ins");
+ break;
+ case OSCAR_CAPABILITY_SENDBUDDYLIST:
+ tmp = _("Send Buddy List");
+ break;
+ case OSCAR_CAPABILITY_ICQ_DIRECT:
+ tmp = _("ICQ Direct Connect");
+ break;
+ case OSCAR_CAPABILITY_APINFO:
+ tmp = _("AP User");
+ break;
+ case OSCAR_CAPABILITY_ICQRTF:
+ tmp = _("ICQ RTF");
+ break;
+ case OSCAR_CAPABILITY_EMPTY:
+ tmp = _("Nihilist");
+ break;
+ case OSCAR_CAPABILITY_ICQSERVERRELAY:
+ tmp = _("ICQ Server Relay");
+ break;
+ case OSCAR_CAPABILITY_UNICODEOLD:
+ tmp = _("Old ICQ UTF8");
+ break;
+ case OSCAR_CAPABILITY_TRILLIANCRYPT:
+ tmp = _("Trillian Encryption");
+ break;
+ case OSCAR_CAPABILITY_UNICODE:
+ tmp = _("ICQ UTF8");
+ break;
+ case OSCAR_CAPABILITY_HIPTOP:
+ tmp = _("Hiptop");
+ break;
+ case OSCAR_CAPABILITY_SECUREIM:
+ tmp = _("Security Enabled");
+ break;
+ case OSCAR_CAPABILITY_VIDEO:
+ tmp = _("Video Chat");
+ break;
+ /* Not actually sure about this one... WinAIM doesn't show anything */
+ case OSCAR_CAPABILITY_ICHATAV:
+ tmp = _("iChat AV");
+ break;
+ case OSCAR_CAPABILITY_LIVEVIDEO:
+ tmp = _("Live Video");
+ break;
+ case OSCAR_CAPABILITY_CAMERA:
+ tmp = _("Camera");
+ break;
+ case OSCAR_CAPABILITY_ICHAT_SCREENSHARE:
+ tmp = _("Screen Sharing");
+ break;
+ default:
+ tmp = NULL;
+ break;
+ }
+ if (tmp)
+ g_string_append_printf(str, "%s%s", (*(str->str) == '\0' ? "" : ", "), tmp);
+ }
+ bit <<= 1;
+ }
+
+ return g_string_free(str, FALSE);
+}
+
+static void
+oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value)
+{
+ if (value && value[0]) {
+ purple_notify_user_info_add_pair(user_info, name, value);
+ }
+}
+
+static void
+oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
+ const char *name, const char *value)
+{
+ gchar *utf8;
+
+ if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
+ purple_notify_user_info_add_pair(user_info, name, utf8);
+ g_free(utf8);
+ }
+}
+
+static void
+oscar_user_info_convert_and_add_hyperlink(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info,
+ const char *name, const char *value, const char *url_prefix)
+{
+ gchar *utf8;
+
+ if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) {
+ gchar *tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>", url_prefix, utf8, utf8);
+ purple_notify_user_info_add_pair(user_info, name, tmp);
+ g_free(utf8);
+ g_free(tmp);
+ }
+}
+
+/**
+ * @brief Append the status information to a user_info struct
+ *
+ * The returned information is HTML-ready, appropriately escaped, as all information in a user_info struct should be HTML.
+ *
+ * @param gc The PurpleConnection
+ * @param user_info A PurpleNotifyUserInfo object to which status information will be added
+ * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status().
+ * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status().
+ * @param strip_html_tags If strip_html_tags is TRUE, tags embedded in the status message will be stripped, returning a non-formatted string. The string will still be HTML escaped.
+ */
+void
+oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags)
+{
+ PurpleAccount *account = purple_connection_get_account(gc);
+ OscarData *od;
+ PurplePresence *presence = NULL;
+ PurpleStatus *status = NULL;
+ gchar *message = NULL, *itmsurl = NULL, *tmp;
+ gboolean is_away;
+
+ od = purple_connection_get_protocol_data(gc);
+
+ if (b == NULL && userinfo == NULL)
+ return;
+
+ if (b == NULL)
+ b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn);
+ else
+ userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
+
+ if (b) {
+ presence = purple_buddy_get_presence(b);
+ status = purple_presence_get_active_status(presence);
+ }
+
+ /* If we have both b and userinfo we favor userinfo, because if we're
+ viewing someone's profile then we want the HTML away message, and
+ the "message" attribute of the status contains only the plaintext
+ message. */
+ if (userinfo) {
+ if ((userinfo->flags & AIM_FLAG_AWAY) && userinfo->away_len > 0 && userinfo->away != NULL && userinfo->away_encoding != NULL) {
+ /* Away message */
+ message = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len);
+ } else {
+ /*
+ * Available message or non-HTML away message (because that's
+ * all we have right now.
+ */
+ if ((userinfo->status != NULL) && userinfo->status[0] != '\0') {
+ message = oscar_encoding_to_utf8(userinfo->status_encoding, userinfo->status, userinfo->status_len);
+ }
+#if defined (_WIN32) || defined (__APPLE__)
+ if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) {
+ itmsurl = oscar_encoding_to_utf8(userinfo->itmsurl_encoding, userinfo->itmsurl, userinfo->itmsurl_len);
+ }
+#endif
+ }
+ } else {
+ message = g_strdup(purple_status_get_attr_string(status, "message"));
+ itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
+ }
+
+ is_away = ((status && !purple_status_is_available(status)) ||
+ (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
+
+ if (strip_html_tags) {
+ /* Away messages are HTML, but available messages were originally plain text.
+ * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags.
+ */
+ /*
+ * It seems like the above comment no longer applies. All messages need
+ * to be escaped.
+ */
+ if (message) {
+ gchar *tmp2;
+ tmp = purple_markup_strip_html(message);
+ g_free(message);
+ tmp2 = g_markup_escape_text(tmp, -1);
+ g_free(tmp);
+ message = tmp2;
+ }
+
+ } else {
+ if (itmsurl) {
+ tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
+ itmsurl, message);
+ g_free(message);
+ message = tmp;
+ }
+ }
+ g_free(itmsurl);
+
+ if (message) {
+ tmp = oscar_util_format_string(message, purple_account_get_username(account));
+ g_free(message);
+ message = tmp;
+ }
+
+ if (b) {
+ if (purple_presence_is_online(presence)) {
+ if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) {
+ /* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
+ * If the status name and the message are the same, only show one. */
+ const char *status_name = purple_status_get_name(status);
+ if (status_name && message && !strcmp(status_name, message))
+ status_name = NULL;
+
+ tmp = g_strdup_printf("%s%s%s",
+ status_name ? status_name : "",
+ ((status_name && message) && *message) ? ": " : "",
+ (message && *message) ? message : "");
+ g_free(message);
+ message = tmp;
+ }
+
+ } else if (aim_ssi_waitingforauth(od->ssi.local,
+ aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
+ purple_buddy_get_name(b)))
+ {
+ /* Note if an offline buddy is not authorized */
+ tmp = g_strdup_printf("%s%s%s",
+ _("Not Authorized"),
+ (message && *message) ? ": " : "",
+ (message && *message) ? message : "");
+ g_free(message);
+ message = tmp;
+ } else {
+ g_free(message);
+ message = g_strdup(_("Offline"));
+ }
+ }
+
+ if (presence) {
+ const char *mood;
+ const char *description;
+ status = purple_presence_get_status(presence, "mood");
+ mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
+ description = icq_get_custom_icon_description(mood);
+ if (description && *description)
+ purple_notify_user_info_add_pair(user_info, _("Mood"), _(description));
+ }
+
+ purple_notify_user_info_add_pair(user_info, _("Status"), message);
+ g_free(message);
+}
+
+void
+oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
+{
+ OscarData *od;
+ PurpleAccount *account;
+ PurplePresence *presence = NULL;
+ PurpleStatus *status = NULL;
+ PurpleGroup *g = NULL;
+ struct buddyinfo *bi = NULL;
+ char *tmp;
+ const char *bname = NULL, *gname = NULL;
+
+ od = purple_connection_get_protocol_data(gc);
+ account = purple_connection_get_account(gc);
+
+ if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL)))
+ return;
+
+ if (userinfo == NULL)
+ userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
+
+ if (b == NULL)
+ b = purple_find_buddy(account, userinfo->bn);
+
+ if (b != NULL) {
+ bname = purple_buddy_get_name(b);
+ g = purple_buddy_get_group(b);
+ gname = purple_group_get_name(g);
+ presence = purple_buddy_get_presence(b);
+ status = purple_presence_get_active_status(presence);
+ }
+
+ if (userinfo != NULL)
+ bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));
+
+ if ((bi != NULL) && (bi->ipaddr != 0)) {
+ tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
+ (bi->ipaddr & 0xff000000) >> 24,
+ (bi->ipaddr & 0x00ff0000) >> 16,
+ (bi->ipaddr & 0x0000ff00) >> 8,
+ (bi->ipaddr & 0x000000ff));
+ oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
+ g_free(tmp);
+ }
+
+ if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
+ tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
+ oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
+ g_free(tmp);
+ }
+
+ if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) {
+ tmp = aim_ssi_getcomment(od->ssi.local, gname, bname);
+ if (tmp != NULL) {
+ char *tmp2 = g_markup_escape_text(tmp, strlen(tmp));
+ g_free(tmp);
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Buddy Comment"), tmp2);
+ g_free(tmp2);
+ }
+ }
+}
+
+void
+oscar_user_info_display_error(OscarData *od, guint16 error_reason, gchar *buddy)
+{
+ PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
+ gchar *buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(error_reason));
+ purple_notify_user_info_add_pair(user_info, NULL, buf);
+ purple_notify_userinfo(od->gc, buddy, user_info, NULL, NULL);
+ purple_notify_user_info_destroy(user_info);
+ purple_conv_present_error(buddy, purple_connection_get_account(od->gc), buf);
+ g_free(buf);
+}
+
+void
+oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info)
+{
+ PurpleConnection *gc = od->gc;
+ PurpleAccount *account = purple_connection_get_account(gc);
+ PurpleBuddy *buddy;
+ struct buddyinfo *bi;
+ gchar who[16];
+ PurpleNotifyUserInfo *user_info;
+ const gchar *alias;
+
+ if (!info->uin)
+ return;
+
+ user_info = purple_notify_user_info_new();
+
+ g_snprintf(who, sizeof(who), "%u", info->uin);
+ buddy = purple_find_buddy(account, who);
+ if (buddy != NULL)
+ bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy)));
+ else
+ bi = NULL;
+
+ purple_notify_user_info_add_pair(user_info, _("UIN"), who);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick);
+ if ((bi != NULL) && (bi->ipaddr != 0)) {
+ char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
+ (bi->ipaddr & 0xff000000) >> 24,
+ (bi->ipaddr & 0x00ff0000) >> 16,
+ (bi->ipaddr & 0x0000ff00) >> 8,
+ (bi->ipaddr & 0x000000ff));
+ purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr);
+ g_free(tstr);
+ }
+ oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last);
+ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Email Address"), info->email, "mailto:");
+ if (info->numaddresses && info->email2) {
+ int i;
+ for (i = 0; i < info->numaddresses; i++) {
+ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Email Address"), info->email2[i], "mailto:");
+ }
+ }
+ oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile);
+
+ if (info->gender != 0)
+ purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male")));
+
+ if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) {
+ /* Initialize the struct properly or strftime() will crash
+ * under some conditions (e.g. Debian sarge w/ LANG=en_HK). */
+ time_t t = time(NULL);
+ struct tm *tm = localtime(&t);
+
+ tm->tm_mday = (int)info->birthday;
+ tm->tm_mon = (int)info->birthmonth - 1;
+ tm->tm_year = (int)info->birthyear - 1900;
+
+ /* To be 100% sure that the fields are re-normalized.
+ * If you're sure strftime() ALWAYS does this EVERYWHERE,
+ * feel free to remove it. --rlaager */
+ mktime(tm);
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Birthday"), purple_date_format_short(tm));
+ }
+ if ((info->age > 0) && (info->age < 255)) {
+ char age[5];
+ snprintf(age, sizeof(age), "%hhd", info->age);
+ purple_notify_user_info_add_pair(user_info, _("Age"), age);
+ }
+ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Personal Web Page"), info->email, "");
+ if (buddy != NULL)
+ oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* strip_html_tags */ FALSE);
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Additional Information"), info->info);
+ purple_notify_user_info_add_section_break(user_info);
+
+ if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) {
+ purple_notify_user_info_add_section_header(user_info, _("Home Address"));
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->homeaddr);
+ oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->homecity);
+ oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->homestate);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->homezip);
+ }
+ if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) {
+ purple_notify_user_info_add_section_header(user_info, _("Work Address"));
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->workaddr);
+ oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->workcity);
+ oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->workstate);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->workzip);
+ }
+ if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) {
+ purple_notify_user_info_add_section_header(user_info, _("Work Information"));
+
+ oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision);
+ oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition);
+ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Web Page"), info->email, "");
+ }
+
+ if (buddy != NULL)
+ alias = purple_buddy_get_alias(buddy);
+ else
+ alias = who;
+ purple_notify_userinfo(gc, who, user_info, NULL, NULL);
+ purple_notify_user_info_destroy(user_info);
+}
+
+void
+oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo)
+{
+ PurpleConnection *gc = od->gc;
+ PurpleAccount *account = purple_connection_get_account(gc);
+ PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
+ gchar *tmp = NULL, *info_utf8 = NULL, *base_profile_url = NULL;
+
+ oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* strip_html_tags */ FALSE);
+
+ if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
+ tmp = purple_str_seconds_to_string(userinfo->idletime*60);
+ oscar_user_info_add_pair(user_info, _("Idle"), tmp);
+ g_free(tmp);
+ }
+
+ oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo);
+
+ if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) {
+ /* An SMS contact is always online; its Online Since value is not useful */
+ time_t t = userinfo->onlinesince;
+ oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
+ }
+
+ if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
+ time_t t = userinfo->membersince;
+ oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
+ }
+
+ if (userinfo->capabilities != 0) {
+ tmp = oscar_caps_to_string(userinfo->capabilities);
+ oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
+ g_free(tmp);
+ }
+
+ /* Info */
+ if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) {
+ info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len);
+ tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account));
+ purple_notify_user_info_add_section_break(user_info);
+ oscar_user_info_add_pair(user_info, _("Profile"), tmp);
+ g_free(tmp);
+ g_free(info_utf8);
+ }
+
+ purple_notify_user_info_add_section_break(user_info);
+ base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com";
+ tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>",
+ base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile"));
+ purple_notify_user_info_add_pair(user_info, NULL, tmp);
+ g_free(tmp);
+
+ purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL);
+ purple_notify_user_info_destroy(user_info);
+} \ No newline at end of file
diff --git a/libpurple/protocols/oscar/util.c b/libpurple/protocols/oscar/util.c
index 3b87e00dc3..81211824eb 100644
--- a/libpurple/protocols/oscar/util.c
+++ b/libpurple/protocols/oscar/util.c
@@ -107,91 +107,6 @@ gchar *oscar_get_clientstring(void)
return g_strdup_printf("%s/%s", name, version);;
}
-/*
- * Tokenizing functions. Used to portably replace strtok/sep.
- * -- DMP.
- *
- */
-/* TODO: Get rid of this and use glib functions */
-int
-aimutil_tokslen(char *toSearch, int theindex, char dl)
-{
- int curCount = 1;
- char *next;
- char *last;
- int toReturn;
-
- last = toSearch;
- next = strchr(toSearch, dl);
-
- while(curCount < theindex && next != NULL) {
- curCount++;
- last = next + 1;
- next = strchr(last, dl);
- }
-
- if ((curCount < theindex) || (next == NULL))
- toReturn = strlen(toSearch) - (curCount - 1);
- else
- toReturn = next - toSearch - (curCount - 1);
-
- return toReturn;
-}
-
-int
-aimutil_itemcnt(char *toSearch, char dl)
-{
- int curCount;
- char *next;
-
- curCount = 1;
-
- next = strchr(toSearch, dl);
-
- while(next != NULL) {
- curCount++;
- next = strchr(next + 1, dl);
- }
-
- return curCount;
-}
-
-char *
-aimutil_itemindex(char *toSearch, int theindex, char dl)
-{
- int curCount;
- char *next;
- char *last;
- char *toReturn;
-
- curCount = 0;
-
- last = toSearch;
- next = strchr(toSearch, dl);
-
- while (curCount < theindex && next != NULL) {
- curCount++;
- last = next + 1;
- next = strchr(last, dl);
- }
- next = strchr(last, dl);
-
- if (curCount < theindex) {
- toReturn = g_malloc(sizeof(char));
- *toReturn = '\0';
- } else {
- if (next == NULL) {
- toReturn = g_malloc((strlen(last) + 1) * sizeof(char));
- strcpy(toReturn, last);
- } else {
- toReturn = g_malloc((next - last + 1) * sizeof(char));
- memcpy(toReturn, last, (next - last));
- toReturn[next - last] = '\0';
- }
- }
- return toReturn;
-}
-
/**
* Calculate the checksum of a given icon.
*/
@@ -323,3 +238,89 @@ oscar_util_name_compare(const char *name1, const char *name2)
return 0;
}
+
+/**
+ * Looks for %n, %d, or %t in a string, and replaces them with the
+ * specified name, date, and time, respectively.
+ *
+ * @param str The string that may contain the special variables.
+ * @param name The sender name.
+ *
+ * @return A newly allocated string where the special variables are
+ * expanded. This should be g_free'd by the caller.
+ */
+gchar *
+oscar_util_format_string(const char *str, const char *name)
+{
+ char *c;
+ GString *cpy;
+ time_t t;
+ struct tm *tme;
+
+ g_return_val_if_fail(str != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ /* Create an empty GString that is hopefully big enough for most messages */
+ cpy = g_string_sized_new(1024);
+
+ t = time(NULL);
+ tme = localtime(&t);
+
+ c = (char *)str;
+ while (*c) {
+ switch (*c) {
+ case '%':
+ if (*(c + 1)) {
+ switch (*(c + 1)) {
+ case 'n':
+ /* append name */
+ g_string_append(cpy, name);
+ c++;
+ break;
+ case 'd':
+ /* append date */
+ g_string_append(cpy, purple_date_format_short(tme));
+ c++;
+ break;
+ case 't':
+ /* append time */
+ g_string_append(cpy, purple_time_format(tme));
+ c++;
+ break;
+ default:
+ g_string_append_c(cpy, *c);
+ }
+ } else {
+ g_string_append_c(cpy, *c);
+ }
+ break;
+ default:
+ g_string_append_c(cpy, *c);
+ }
+ c++;
+ }
+
+ return g_string_free(cpy, FALSE);
+}
+
+gchar *
+oscar_format_buddies(GSList *buddies, const gchar *no_buddies_message)
+{
+ GSList *cur;
+ GString *result;
+ if (!buddies) {
+ return g_strdup_printf("<i>%s</i>", no_buddies_message);
+ }
+ result = g_string_new("");
+ for (cur = buddies; cur != NULL; cur = cur->next) {
+ PurpleBuddy *buddy = cur->data;
+ const gchar *bname = purple_buddy_get_name(buddy);
+ const gchar *alias = purple_buddy_get_alias_only(buddy);
+ g_string_append(result, bname);
+ if (alias) {
+ g_string_append_printf(result, " (%s)", alias);
+ }
+ g_string_append(result, "<br>");
+ }
+ return g_string_free(result, FALSE);
+}
diff --git a/libpurple/protocols/oscar/visibility.c b/libpurple/protocols/oscar/visibility.c
new file mode 100644
index 0000000000..abec4688f8
--- /dev/null
+++ b/libpurple/protocols/oscar/visibility.c
@@ -0,0 +1,199 @@
+/*
+ * Purple's oscar protocol plugin
+ * This file is the legal property of its developers.
+ * Please see the AUTHORS file distributed alongside this file.
+ *
+ * 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 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
+ */
+
+#include "visibility.h"
+#include "request.h"
+
+/* 4 separate strings are needed in order to ease translators' job */
+#define APPEAR_ONLINE N_("Appear Online")
+#define DONT_APPEAR_ONLINE N_("Don't Appear Online")
+#define APPEAR_OFFLINE N_("Appear Offline")
+#define DONT_APPEAR_OFFLINE N_("Don't Appear Offline")
+
+static guint16
+get_buddy_list_type(OscarData *od)
+{
+ PurpleAccount *account = purple_connection_get_account(od->gc);
+ return purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE) ? AIM_SSI_TYPE_PERMIT : AIM_SSI_TYPE_DENY;
+}
+
+static gboolean
+is_buddy_on_list(OscarData *od, const char *bname)
+{
+ return aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL;
+}
+
+static void
+visibility_cb(PurpleBlistNode *node, gpointer whatever)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(node);
+ const char* bname = purple_buddy_get_name(buddy);
+ OscarData *od = purple_connection_get_protocol_data(purple_account_get_connection(purple_buddy_get_account(buddy)));
+ guint16 list_type = get_buddy_list_type(od);
+
+ if (!is_buddy_on_list(od, bname)) {
+ aim_ssi_add_to_private_list(od, bname, list_type);
+ } else {
+ aim_ssi_del_from_private_list(od, bname, list_type);
+ }
+}
+
+PurpleMenuAction *
+create_visibility_menu_item(OscarData *od, const char *bname)
+{
+ PurpleAccount *account = purple_connection_get_account(od->gc);
+ gboolean invisible = purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE);
+ gboolean on_list = is_buddy_on_list(od, bname);
+ const gchar *label;
+
+ if (invisible) {
+ label = on_list ? _(DONT_APPEAR_ONLINE) : _(APPEAR_ONLINE);
+ } else {
+ label = on_list ? _(DONT_APPEAR_OFFLINE) : _(APPEAR_OFFLINE);
+ }
+ return purple_menu_action_new(label, PURPLE_CALLBACK(visibility_cb), NULL, NULL);
+}
+
+typedef void (*ShowDialog)(PurplePluginAction *);
+
+struct list_remove_data
+{
+ PurplePluginAction *action;
+ ShowDialog show_dialog_again;
+ OscarData *od;
+ guint16 list_type;
+ const gchar *list_name;
+};
+
+static void
+list_remove_cb(struct list_remove_data *data, PurpleRequestFields *fields)
+{
+ ShowDialog show_dialog_again = data->show_dialog_again;
+ PurplePluginAction *action = data->action;
+ PurpleRequestField *field = purple_request_fields_get_field(fields, "list-items");
+ GList *sels = purple_request_field_list_get_selected(field);
+ for (; sels; sels = sels->next) {
+ const gchar *name = sels->data;
+ const gchar *bname = purple_request_field_list_get_data(field, name);
+
+ purple_debug_info("oscar", "Removing %s from %s\n", bname, data->list_name);
+
+ aim_ssi_del_from_private_list(data->od, bname, data->list_type);
+ }
+
+ g_free(data);
+ show_dialog_again(action);
+}
+
+static void
+list_close_cb(struct list_remove_data *data, gpointer ignored)
+{
+ g_free(data);
+}
+
+static void
+show_private_list(PurplePluginAction *action,
+ guint16 list_type,
+ const gchar *list_name,
+ const gchar *list_description,
+ const gchar *menu_action_name,
+ ShowDialog caller)
+{
+ PurpleConnection *gc = (PurpleConnection *) action->context;
+ OscarData *od = purple_connection_get_protocol_data(gc);
+ PurpleAccount *account = purple_connection_get_account(gc);
+ GSList *buddies, *cur;
+ gchar *desc;
+ struct list_remove_data *data;
+
+ PurpleRequestField *field;
+ PurpleRequestFields *fields = purple_request_fields_new();
+ PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
+
+ purple_request_fields_add_group(fields, group);
+
+ desc = g_strdup_printf(_("You can add a buddy to this list "
+ "by right-clicking on them and "
+ "selecting \"%s\""), menu_action_name);
+
+ field = purple_request_field_list_new("list-items", desc);
+ g_free(desc);
+
+ purple_request_field_group_add_field(group, field);
+
+ purple_request_field_list_set_multi_select(field, TRUE);
+ purple_request_field_set_required(field, TRUE);
+
+ buddies = purple_find_buddies(account, NULL);
+ for (cur = buddies; cur != NULL; cur = cur->next) {
+ PurpleBuddy *buddy;
+ const gchar *bname;
+
+ buddy = cur->data;
+ bname = purple_buddy_get_name(buddy);
+ if (aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, list_type)) {
+ const gchar *alias = purple_buddy_get_alias_only(buddy);
+ char *dname = alias ? g_strdup_printf("%s (%s)", bname, alias) : NULL;
+ purple_request_field_list_add(field, dname ? dname : bname, (void *)bname);
+ g_free(dname);
+ }
+ }
+
+ g_slist_free(buddies);
+
+ data = g_new0(struct list_remove_data, 1);
+ data->action = action;
+ data->show_dialog_again = caller;
+ data->od = od;
+ data->list_type = list_type;
+ data->list_name = list_name;
+
+ purple_request_fields(gc, list_name, list_description, NULL,
+ fields,
+ _("Close"), G_CALLBACK(list_close_cb),
+ _("Remove"), G_CALLBACK(list_remove_cb),
+ account, NULL, NULL,
+ data);
+}
+
+void
+oscar_show_visible_list(PurplePluginAction *action)
+{
+ show_private_list(action,
+ AIM_SSI_TYPE_PERMIT,
+ _("Visible List"),
+ _("These buddies will see "
+ "your status when you switch "
+ "to \"Invisible\""),
+ _(APPEAR_ONLINE),
+ oscar_show_visible_list);
+}
+
+void
+oscar_show_invisible_list(PurplePluginAction *action)
+{
+ show_private_list(action,
+ AIM_SSI_TYPE_DENY,
+ _("Invisible List"),
+ _("These buddies will always see you as offline"),
+ _(APPEAR_OFFLINE),
+ oscar_show_invisible_list);
+}
+
diff --git a/libpurple/protocols/oscar/family_translate.c b/libpurple/protocols/oscar/visibility.h
index 005528f116..77ea4c2c30 100644
--- a/libpurple/protocols/oscar/family_translate.c
+++ b/libpurple/protocols/oscar/visibility.h
@@ -18,29 +18,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-/*
- * Family 0x000c - Translation.
- *
- * I have no idea why this group was issued. I have never seen anything
- * that uses it. From what I remember, the last time I tried to poke at
- * the server with this group, it whined about not supporting it.
- *
- * But we advertise it anyway, because its fun.
- *
- */
+#ifndef _VISIBILITY_H_
+#define _VISIBILITY_H_
#include "oscar.h"
+#include "plugin.h"
+#include "util.h"
-int translate_modfirst(OscarData *od, aim_module_t *mod)
-{
-
- mod->family = SNAC_FAMILY_TRANSLATE;
- mod->version = 0x0001;
- mod->toolid = 0x0104;
- mod->toolversion = 0x0001;
- mod->flags = 0;
- strncpy(mod->name, "translate", sizeof(mod->name));
- mod->snachandler = NULL;
+PurpleMenuAction * create_visibility_menu_item(OscarData *od, const char *bname);
+void oscar_show_visible_list(PurplePluginAction *action);
+void oscar_show_invisible_list(PurplePluginAction *action);
- return 0;
-}
+#endif \ No newline at end of file
diff --git a/libpurple/protocols/qq/ChangeLog b/libpurple/protocols/qq/ChangeLog
index cb6d7a1877..b0a7534071 100644
--- a/libpurple/protocols/qq/ChangeLog
+++ b/libpurple/protocols/qq/ChangeLog
@@ -233,7 +233,7 @@
2008.08.06 - ccpaging <ccpaging(at)gmail.com>
* Rename names of variables, Group, to Room
* Functions of group_network merged into qq_network and qq_process
- * Canceled managing glist of group packet, add sub_cmdd and room_id to transaction
+ * Cancelled managing glist of group packet, add sub_cmdd and room_id to transaction
* Fixed error of demo group:
If 'room list' and 'room infor' are not setup, response received from server will emits 'room_id = 0' packet.
diff --git a/libpurple/protocols/qq/buddy_info.c b/libpurple/protocols/qq/buddy_info.c
index 019ac8e41c..489bd1c525 100644
--- a/libpurple/protocols/qq/buddy_info.c
+++ b/libpurple/protocols/qq/buddy_info.c
@@ -224,12 +224,10 @@ static void info_display_only(PurpleConnection *gc, gchar **segments)
void qq_request_buddy_info(PurpleConnection *gc, guint32 uid,
guint32 update_class, int action)
{
- qq_data *qd;
gchar raw_data[16] = {0};
g_return_if_fail(uid != 0);
- qd = (qq_data *) gc->proto_data;
g_snprintf(raw_data, sizeof(raw_data), "%u", uid);
qq_send_cmd_mess(gc, QQ_CMD_GET_BUDDY_INFO, (guint8 *) raw_data, strlen(raw_data),
update_class, action);
@@ -271,7 +269,6 @@ static void info_modify_cancel_cb(modify_info_request *info_request)
static void info_modify_ok_cb(modify_info_request *info_request, PurpleRequestFields *fields)
{
PurpleConnection *gc;
- qq_data *qd;
gchar **segments;
int index;
const char *utf8_str;
@@ -279,8 +276,7 @@ static void info_modify_ok_cb(modify_info_request *info_request, PurpleRequestFi
int choice_num;
gc = info_request->gc;
- g_return_if_fail(gc != NULL && info_request->gc);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(gc != NULL);
segments = info_request->segments;
g_return_if_fail(segments != NULL);
@@ -390,14 +386,12 @@ static void field_request_new(PurpleRequestFieldGroup *group, gint index, gchar
static void info_modify_dialogue(PurpleConnection *gc, gchar **segments, int iclass)
{
- qq_data *qd;
PurpleRequestFieldGroup *group;
PurpleRequestFields *fields;
modify_info_request *info_request;
gchar *utf8_title, *utf8_prim;
int index;
- qd = (qq_data *) gc->proto_data;
/* Keep one dialog once a time */
purple_request_close_with_handle(gc);
@@ -416,9 +410,11 @@ static void info_modify_dialogue(PurpleConnection *gc, gchar **segments, int icl
case QQ_FIELD_CONTACT:
utf8_title = g_strdup(_("Modify Contact"));
utf8_prim = g_strdup_printf("%s for %s", _("Modify Contact"), segments[0]);
+ break;
case QQ_FIELD_ADDR:
utf8_title = g_strdup(_("Modify Address"));
utf8_prim = g_strdup_printf("%s for %s", _("Modify Address"), segments[0]);
+ break;
case QQ_FIELD_EXT:
utf8_title = g_strdup(_("Modify Extended Information"));
utf8_prim = g_strdup_printf("%s for %s", _("Modify Extended Information"), segments[0]);
@@ -427,6 +423,7 @@ static void info_modify_dialogue(PurpleConnection *gc, gchar **segments, int icl
default:
utf8_title = g_strdup(_("Modify Information"));
utf8_prim = g_strdup_printf("%s for %s", _("Modify Information"), segments[0]);
+ break;
}
info_request = g_new0(modify_info_request, 1);
diff --git a/libpurple/protocols/qq/buddy_list.c b/libpurple/protocols/qq/buddy_list.c
index 7498e1a54f..a927a87f3a 100644
--- a/libpurple/protocols/qq/buddy_list.c
+++ b/libpurple/protocols/qq/buddy_list.c
@@ -55,11 +55,9 @@ typedef struct _qq_buddy_online {
/* get a list of online_buddies */
void qq_request_get_buddies_online(PurpleConnection *gc, guint8 position, guint32 update_class)
{
- qq_data *qd;
guint8 *raw_data;
gint bytes = 0;
- qd = (qq_data *) gc->proto_data;
raw_data = g_newa(guint8, 5);
/* 000-000 get online friends cmd
@@ -360,7 +358,6 @@ guint16 qq_process_get_buddies(guint8 *data, gint data_len, PurpleConnection *gc
guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConnection *gc)
{
- qq_data *qd;
gint i, j;
gint bytes;
guint8 sub_cmd, reply_code;
@@ -371,8 +368,6 @@ guint32 qq_process_get_buddies_and_rooms(guint8 *data, gint data_len, PurpleConn
g_return_val_if_fail(data != NULL && data_len != 0, -1);
- qd = (qq_data *) gc->proto_data;
-
bytes = 0;
bytes += qq_get8(&sub_cmd, data + bytes);
g_return_val_if_fail(sub_cmd == 0x01, -1);
@@ -468,11 +463,6 @@ void qq_request_change_status(PurpleConnection *gc, guint32 update_class)
guint8 away_cmd;
guint32 misc_status;
gboolean fake_video;
- PurpleAccount *account;
- PurplePresence *presence;
-
- account = purple_connection_get_account(gc);
- presence = purple_account_get_presence(account);
qd = (qq_data *) gc->proto_data;
if (!qd->is_login)
@@ -596,14 +586,13 @@ void qq_process_buddy_change_status(guint8 *data, gint data_len, PurpleConnectio
void qq_update_buddy_status(PurpleConnection *gc, guint32 uid, guint8 status, guint8 flag)
{
gchar *who;
- gchar *status_id;
+ const gchar *status_id;
g_return_if_fail(uid != 0);
/* purple supports signon and idle time
* but it is not much use for QQ, I do not use them */
/* serv_got_update(gc, name, online, 0, q_bud->signon, q_bud->idle, bud->uc); */
- status_id = "available";
switch(status) {
case QQ_BUDDY_OFFLINE:
status_id = "offline";
@@ -677,13 +666,10 @@ void qq_update_buddyies_status(PurpleConnection *gc)
void qq_buddy_data_free_all(PurpleConnection *gc)
{
- qq_data *qd;
PurpleBuddy *buddy;
GSList *buddies, *it;
gint count = 0;
- qd = (qq_data *)purple_connection_get_protocol_data(gc);
-
buddies = purple_find_buddies(purple_connection_get_account(gc), NULL);
for (it = buddies; it; it = it->next) {
qq_buddy_data *qbd = NULL;
diff --git a/libpurple/protocols/qq/buddy_opt.c b/libpurple/protocols/qq/buddy_opt.c
index f8bb588367..fef9ee3920 100644
--- a/libpurple/protocols/qq/buddy_opt.c
+++ b/libpurple/protocols/qq/buddy_opt.c
@@ -262,7 +262,6 @@ void qq_request_auth_code(PurpleConnection *gc, guint8 cmd, guint16 sub_cmd, gui
void qq_process_auth_code(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid)
{
- qq_data *qd;
gint bytes;
guint8 cmd, reply;
guint16 sub_cmd;
@@ -272,8 +271,6 @@ void qq_process_auth_code(PurpleConnection *gc, guint8 *data, gint data_len, gui
g_return_if_fail(data != NULL && data_len != 0);
g_return_if_fail(uid != 0);
- qd = (qq_data *) gc->proto_data;
-
qq_show_packet("qq_process_auth_code", data, data_len);
bytes = 0;
bytes += qq_get8(&cmd, data + bytes);
@@ -324,7 +321,7 @@ static void add_buddy_question_input(PurpleConnection *gc, guint32 uid, gchar *q
add_req->auth_len = 0;
who = uid_to_purple_name(uid);
- msg = g_strdup_printf(_("%u requires verification"), uid);
+ msg = g_strdup_printf(_("%u requires verification: %s"), uid, question);
purple_request_input(gc, _("Add buddy question"), msg,
_("Enter answer here"),
NULL,
@@ -400,7 +397,6 @@ static void request_add_buddy_by_question(PurpleConnection *gc, guint32 uid,
void qq_process_question(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid)
{
- qq_data *qd;
gint bytes;
guint8 cmd, reply;
gchar *question, *answer;
@@ -409,8 +405,6 @@ void qq_process_question(PurpleConnection *gc, guint8 *data, gint data_len, guin
g_return_if_fail(data != NULL && data_len != 0);
- qd = (qq_data *) gc->proto_data;
-
qq_show_packet("qq_process_question", data, data_len);
bytes = 0;
bytes += qq_get8(&cmd, data + bytes);
@@ -720,13 +714,10 @@ void qq_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
/* process reply to add_buddy_auth request */
void qq_process_add_buddy_auth(guint8 *data, gint data_len, PurpleConnection *gc)
{
- qq_data *qd;
gchar **segments, *msg_utf8;
g_return_if_fail(data != NULL && data_len != 0);
- qd = (qq_data *) gc->proto_data;
-
if (data[0] == '0') {
purple_debug_info("QQ", "Reply OK for sending authorize\n");
return;
@@ -767,11 +758,9 @@ void qq_process_remove_buddy(PurpleConnection *gc, guint8 *data, gint data_len,
/* process the server reply for my request to remove myself from a buddy */
void qq_process_buddy_remove_me(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid)
{
- qq_data *qd;
gchar *msg;
g_return_if_fail(data != NULL && data_len != 0);
- qd = (qq_data *) gc->proto_data;
if (data[0] == 0) {
purple_debug_info("QQ", "Reply OK for removing me from %u's buddy list\n", uid);
@@ -1004,7 +993,6 @@ static void server_buddy_add_request(PurpleConnection *gc, gchar *from, gchar *t
void qq_process_buddy_check_code(PurpleConnection *gc, guint8 *data, gint data_len)
{
- qq_data *qd;
gint bytes;
guint8 cmd;
guint8 reply;
@@ -1013,8 +1001,6 @@ void qq_process_buddy_check_code(PurpleConnection *gc, guint8 *data, gint data_l
g_return_if_fail(data != NULL && data_len >= 5);
- qd = (qq_data *) gc->proto_data;
-
qq_show_packet("buddy_check_code", data, data_len);
bytes = 0;
diff --git a/libpurple/protocols/qq/char_conv.c b/libpurple/protocols/qq/char_conv.c
index 3db2c0caf3..0dfedc1306 100644
--- a/libpurple/protocols/qq/char_conv.c
+++ b/libpurple/protocols/qq/char_conv.c
@@ -37,7 +37,7 @@
/* convert a string from from_charset to to_charset, using g_convert */
/* Warning: do not return NULL */
-static gchar *do_convert(const gchar *str, gssize len, const gchar *to_charset, const gchar *from_charset)
+static gchar *do_convert(const gchar *str, gssize len, guint8 *out_len, const gchar *to_charset, const gchar *from_charset)
{
GError *error = NULL;
gchar *ret;
@@ -48,6 +48,8 @@ static gchar *do_convert(const gchar *str, gssize len, const gchar *to_charset,
ret = g_convert(str, len, to_charset, from_charset, &byte_read, &byte_write, &error);
if (error == NULL) {
+ if (out_len)
+ *out_len = byte_write;
return ret; /* convert is OK */
}
@@ -67,7 +69,8 @@ static gchar *do_convert(const gchar *str, gssize len, const gchar *to_charset,
*/
gint qq_get_vstr(gchar **ret, const gchar *from_charset, guint8 *data)
{
- guint8 len;
+ gssize len;
+ guint8 out_len;
g_return_val_if_fail(data != NULL && from_charset != NULL, -1);
@@ -76,9 +79,9 @@ gint qq_get_vstr(gchar **ret, const gchar *from_charset, guint8 *data)
*ret = g_strdup("");
return 1;
}
- *ret = do_convert((gchar *) (data + 1), (gssize) len, UTF8, from_charset);
+ *ret = do_convert((gchar *) (data + 1), len, &out_len, UTF8, from_charset);
- return len + 1;
+ return out_len + 1;
}
gint qq_put_vstr(guint8 *buf, const gchar *str_utf8, const gchar *to_charset)
@@ -86,12 +89,11 @@ gint qq_put_vstr(guint8 *buf, const gchar *str_utf8, const gchar *to_charset)
gchar *str;
guint8 len;
- if (str_utf8 == NULL || (len = strlen(str_utf8)) == 0) {
+ if (str_utf8 == NULL || str_utf8[0] == '\0') {
buf[0] = 0;
return 1;
}
- str = do_convert(str_utf8, -1, to_charset, UTF8);
- len = strlen(str_utf8);
+ str = do_convert(str_utf8, -1, &len, to_charset, UTF8);
buf[0] = len;
if (len > 0) {
memcpy(buf + 1, str, len);
@@ -102,12 +104,12 @@ gint qq_put_vstr(guint8 *buf, const gchar *str_utf8, const gchar *to_charset)
/* Warning: do not return NULL */
gchar *utf8_to_qq(const gchar *str, const gchar *to_charset)
{
- return do_convert(str, -1, to_charset, UTF8);
+ return do_convert(str, -1, NULL, to_charset, UTF8);
}
/* Warning: do not return NULL */
gchar *qq_to_utf8(const gchar *str, const gchar *from_charset)
{
- return do_convert(str, -1, UTF8, from_charset);
+ return do_convert(str, -1, NULL, UTF8, from_charset);
}
diff --git a/libpurple/protocols/qq/file_trans.c b/libpurple/protocols/qq/file_trans.c
index 1ee9a3172c..a0bb67072a 100644
--- a/libpurple/protocols/qq/file_trans.c
+++ b/libpurple/protocols/qq/file_trans.c
@@ -238,12 +238,9 @@ static gint _qq_send_file(PurpleConnection *gc, guint8 *data, gint len, guint16
gint bytes = 0;
guint32 file_key;
qq_data *qd;
- ft_info *info;
qd = (qq_data *) gc->proto_data;
- info = (ft_info *) qd->xfer->data;
-
raw_data = g_newa(guint8, MAX_PACKET_SIZE);
file_key = _gen_file_key();
@@ -805,9 +802,6 @@ void qq_process_recv_file(PurpleConnection *gc, guint8 *data, gint len)
{
gint bytes;
guint8 tag;
- qq_data *qd;
-
- qd = (qq_data *) gc->proto_data;
bytes = 0;
bytes += qq_get8(&tag, data + bytes);
diff --git a/libpurple/protocols/qq/group.c b/libpurple/protocols/qq/group.c
index fe0fe22bff..268bda23a6 100644
--- a/libpurple/protocols/qq/group.c
+++ b/libpurple/protocols/qq/group.c
@@ -119,13 +119,11 @@ PurpleRoomlist *qq_roomlist_get_list(PurpleConnection *gc)
/* free roomlist space, I have no idea when this one is called... */
void qq_roomlist_cancel(PurpleRoomlist *list)
{
- qq_data *qd;
PurpleConnection *gc;
g_return_if_fail(list != NULL);
gc = purple_account_get_connection(list->account);
- qd = (qq_data *) gc->proto_data;
purple_roomlist_set_in_progress(list, FALSE);
purple_roomlist_unref(list);
}
diff --git a/libpurple/protocols/qq/group_im.c b/libpurple/protocols/qq/group_im.c
index cba79accf5..2816e124c7 100644
--- a/libpurple/protocols/qq/group_im.c
+++ b/libpurple/protocols/qq/group_im.c
@@ -48,12 +48,10 @@
PurpleConversation *qq_room_conv_open(PurpleConnection *gc, qq_room_data *rmd)
{
PurpleConversation *conv;
- qq_data *qd;
gchar *topic_utf8;
g_return_val_if_fail(rmd != NULL, NULL);
g_return_val_if_fail(rmd->title_utf8, NULL);
- qd = (qq_data *) gc->proto_data;
conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
rmd->title_utf8, purple_connection_get_account(gc));
@@ -207,7 +205,6 @@ void qq_room_got_chat_in(PurpleConnection *gc,
/* recv an IM from a group chat */
void qq_process_room_im(guint8 *data, gint data_len, guint32 id, PurpleConnection *gc, guint16 msg_type)
{
- qq_data *qd;
gchar *msg_smiley, *msg_fmt, *msg_utf8;
gint bytes, tail_len;
struct {
@@ -229,7 +226,6 @@ void qq_process_room_im(guint8 *data, gint data_len, guint32 id, PurpleConnectio
/* at least include im_text.msg_len */
g_return_if_fail(data != NULL && data_len > 23);
- qd = (qq_data *) gc->proto_data;
/* qq_show_packet("ROOM_IM", data, data_len); */
memset(&im_text, 0, sizeof(im_text));
@@ -376,7 +372,6 @@ int qq_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFl
gint msg_len;
const gchar *start_invalid;
gboolean is_smiley_none;
- guint8 frag_count, frag_index;
g_return_val_if_fail(NULL != gc && NULL != gc->proto_data, -1);
g_return_val_if_fail(id != 0 && what != NULL, -1);
@@ -386,9 +381,6 @@ int qq_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFl
/* qq_show_packet("chat IM UTF8", (guint8 *)what, strlen(what)); */
- fmt = qq_im_fmt_new_by_purple(what);
- is_smiley_none = qq_im_smiley_none(what);
-
msg_stripped = purple_markup_strip_html(what);
g_return_val_if_fail(msg_stripped != NULL, -1);
/* qq_show_packet("IM Stripped", (guint8 *)what, strlen(what)); */
@@ -417,26 +409,10 @@ int qq_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFl
qd->send_im_id++;
fmt = qq_im_fmt_new_by_purple(what);
- frag_count = g_slist_length(segments);
- frag_index = 0;
-/*
- if (frag_count <= 1) {
-*/
- for (it = segments; it; it = it->next) {
- request_room_send_im(gc, id, fmt, (gchar *)it->data);
- g_free(it->data);
- }
-/*
- } else {
- for (it = segments; it; it = it->next) {
- request_room_send_im_ex(gc, id, fmt, (gchar *)it->data,
- qd->send_im_id, frag_count, frag_index);
- g_free(it->data);
- frag_index++;
- }
+ for (it = segments; it; it = g_slist_delete_link(it, it)) {
+ request_room_send_im(gc, id, fmt, (gchar *)it->data);
+ g_free(it->data);
}
-*/
qq_im_fmt_free(fmt);
- g_slist_free(segments);
return 1;
}
diff --git a/libpurple/protocols/qq/group_join.c b/libpurple/protocols/qq/group_join.c
index 8bf3df090b..6d27a2ff05 100644
--- a/libpurple/protocols/qq/group_join.c
+++ b/libpurple/protocols/qq/group_join.c
@@ -178,12 +178,10 @@ void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd,
/* If comes here, cmd is OK already */
void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc)
{
- qq_data *qd;
gint bytes;
guint32 id;
g_return_if_fail(data != NULL && len > 0);
- qd = (qq_data *) gc->proto_data;
if (len < 4) {
purple_debug_error("QQ", "Invalid exit group reply, expect %d bytes, read %d bytes\n", 4, len);
@@ -201,12 +199,10 @@ void qq_process_group_cmd_join_group_auth(guint8 *data, gint len, PurpleConnecti
{
gint bytes;
guint32 id;
- qq_data *qd;
qq_room_data *rmd;
gchar *msg;
g_return_if_fail(data != NULL && len > 0);
- qd = (qq_data *) gc->proto_data;
if (len < 4) {
purple_debug_error("QQ",
@@ -283,7 +279,6 @@ void qq_process_group_cmd_join_group(guint8 *data, gint len, PurpleConnection *g
/* Attempt to join a group without auth */
void qq_group_join(PurpleConnection *gc, GHashTable *data)
{
- qq_data *qd;
gchar *ext_id_str;
gchar *id_str;
guint32 ext_id;
@@ -291,7 +286,6 @@ void qq_group_join(PurpleConnection *gc, GHashTable *data)
qq_room_data *rmd;
g_return_if_fail(data != NULL);
- qd = (qq_data *) gc->proto_data;
ext_id_str = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID);
id_str = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID);
diff --git a/libpurple/protocols/qq/group_opt.c b/libpurple/protocols/qq/group_opt.c
index b30608c2e0..5391f0fc87 100644
--- a/libpurple/protocols/qq/group_opt.c
+++ b/libpurple/protocols/qq/group_opt.c
@@ -134,12 +134,10 @@ void qq_group_modify_members(PurpleConnection *gc, qq_room_data *rmd, guint32 *n
{
guint32 *old_members, *del_members, *add_members;
qq_buddy_data *bd;
- qq_data *qd;
gint i = 0, old = 0, new = 0, del = 0, add = 0;
GList *list;
g_return_if_fail(rmd != NULL);
- qd = (qq_data *) gc->proto_data;
if (new_members[0] == 0xffffffff)
return;
diff --git a/libpurple/protocols/qq/im.c b/libpurple/protocols/qq/im.c
index c4363bf826..1f36fa8a1b 100644
--- a/libpurple/protocols/qq/im.c
+++ b/libpurple/protocols/qq/im.c
@@ -725,7 +725,6 @@ void qq_got_message(PurpleConnection *gc, const gchar *msg)
/* process received normal text IM */
static void process_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_header *im_header)
{
- qq_data *qd;
guint16 purple_msg_type;
gchar *who;
gchar *msg_smiley, *msg_fmt, *msg_utf8;
@@ -749,10 +748,9 @@ static void process_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_
gchar *msg; /* no fixed length, ends with 0x00 */
} im_text;
- g_return_if_fail (data != NULL && len > 0);
+ g_return_if_fail(data != NULL && len > 0);
g_return_if_fail(im_header != NULL);
- qd = (qq_data *) gc->proto_data;
memset(&im_text, 0, sizeof(im_text));
/* qq_show_packet("IM text", data, len); */
@@ -823,7 +821,6 @@ static void process_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_
/* process received extended (2007) text IM */
static void process_extend_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_header *im_header)
{
- qq_data *qd;
guint16 purple_msg_type;
gchar *who;
gchar *msg_smiley, *msg_fmt, *msg_utf8;
@@ -848,10 +845,9 @@ static void process_extend_im_text(PurpleConnection *gc, guint8 *data, gint len,
guint8 fromMobileQQ;
} im_text;
- g_return_if_fail (data != NULL && len > 0);
+ g_return_if_fail(data != NULL && len > 0);
g_return_if_fail(im_header != NULL);
- qd = (qq_data *) gc->proto_data;
memset(&im_text, 0, sizeof(im_text));
/* qq_show_packet("Extend IM text", data, len); */
@@ -1043,12 +1039,10 @@ static void request_send_im(PurpleConnection *gc, guint32 uid_to, gint type,
{
qq_data *qd;
guint8 raw_data[MAX_PACKET_SIZE - 16];
- guint16 im_type;
gint bytes;
time_t now;
qd = (qq_data *) gc->proto_data;
- im_type = QQ_NORMAL_IM_TEXT;
/* purple_debug_info("QQ", "Send IM %d-%d\n", frag_count, frag_index); */
bytes = 0;
@@ -1118,13 +1112,12 @@ GSList *qq_im_get_segments(gchar *msg_stripped, gboolean is_smiley_none)
GString *new_string;
GString *append_utf8;
gchar *start, *p;
- gint count, len;
+ gint len;
qq_emoticon *emoticon;
g_return_val_if_fail(msg_stripped != NULL, NULL);
start = msg_stripped;
- count = 0;
new_string = g_string_new("");
append_utf8 = g_string_new("");
while (*start) {
diff --git a/libpurple/protocols/qq/qq.c b/libpurple/protocols/qq/qq.c
index 6bf654f135..46cbc8d8ba 100644
--- a/libpurple/protocols/qq/qq.c
+++ b/libpurple/protocols/qq/qq.c
@@ -89,15 +89,12 @@ static void server_list_create(PurpleAccount *account)
{
PurpleConnection *gc;
qq_data *qd;
- PurpleProxyInfo *gpi;
const gchar *custom_server;
gc = purple_account_get_connection(account);
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = gc->proto_data;
- gpi = purple_proxy_get_setup(account);
-
qd->use_tcp = purple_account_get_bool(account, "use_tcp", TRUE);
custom_server = purple_account_get_string(account, "server", NULL);
@@ -381,13 +378,10 @@ static void qq_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gbo
static const char *qq_list_emblem(PurpleBuddy *b)
{
PurpleAccount *account;
- PurpleConnection *gc;
- qq_data *qd;
qq_buddy_data *buddy;
if (!b || !(account = purple_buddy_get_account(b)) ||
- !(gc = purple_account_get_connection(account)) ||
- !(qd = purple_connection_get_protocol_data(gc)))
+ !purple_account_get_connection(account))
return NULL;
buddy = purple_buddy_get_protocol_data(b);
@@ -620,12 +614,10 @@ static void action_show_account_info(PurplePluginAction *action)
static void action_about_openq(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *) action->context;
- qq_data *qd;
GString *info;
gchar *title;
- g_return_if_fail(NULL != gc && NULL != gc->proto_data);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(NULL != gc);
info = g_string_new("<html><body>");
g_string_append(info, _("<p><b>Original Author</b>:<br>\n"));
diff --git a/libpurple/protocols/qq/qq_base.c b/libpurple/protocols/qq/qq_base.c
index 8a4f3fe0e8..281d1b451e 100644
--- a/libpurple/protocols/qq/qq_base.c
+++ b/libpurple/protocols/qq/qq_base.c
@@ -386,7 +386,6 @@ static const guint8 login_53_68[16] = {
/* process the login reply packet */
guint8 qq_process_login( PurpleConnection *gc, guint8 *data, gint data_len)
{
- qq_data *qd;
guint8 ret = data[0];
gchar *msg, *msg_utf8;
gchar *error;
@@ -394,8 +393,6 @@ guint8 qq_process_login( PurpleConnection *gc, guint8 *data, gint data_len)
g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR);
- qd = (qq_data *) gc->proto_data;
-
switch (ret) {
case QQ_LOGIN_REPLY_OK:
purple_debug_info("QQ", "Login OK\n");
diff --git a/libpurple/protocols/qq/qq_network.c b/libpurple/protocols/qq/qq_network.c
index 4c391d475b..09b4868766 100644
--- a/libpurple/protocols/qq/qq_network.c
+++ b/libpurple/protocols/qq/qq_network.c
@@ -482,13 +482,11 @@ static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond)
static void udp_pending(gpointer data, gint source, PurpleInputCondition cond)
{
PurpleConnection *gc = NULL;
- qq_data *qd;
guint8 *buf;
gint buf_len;
gc = (PurpleConnection *) data;
- g_return_if_fail(gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(gc != NULL);
if(cond != PURPLE_INPUT_READ) {
purple_connection_error_reason(gc,
@@ -748,14 +746,12 @@ static void connect_cb(gpointer data, gint source, const gchar *error_message)
{
PurpleConnection *gc;
qq_data *qd;
- PurpleAccount *account ;
qq_connection *conn;
gc = (PurpleConnection *) data;
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- account = purple_connection_get_account(gc);
/* conn_data will be destoryed */
qd->conn_data = NULL;
diff --git a/libpurple/protocols/qq/qq_process.c b/libpurple/protocols/qq/qq_process.c
index 56f00c8116..74d3b395b3 100644
--- a/libpurple/protocols/qq/qq_process.c
+++ b/libpurple/protocols/qq/qq_process.c
@@ -58,15 +58,12 @@ enum {
/* default process, decrypt and dump */
static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq)
{
- qq_data *qd;
gchar *msg;
g_return_if_fail(data != NULL && data_len != 0);
qq_show_packet(title, data, data_len);
- qd = (qq_data *) gc->proto_data;
-
qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
data, data_len,
">>> [%d] %s -> [default] decrypt and dump",
@@ -80,12 +77,8 @@ static void process_unknow_cmd(PurpleConnection *gc,const gchar *title, guint8 *
/* parse the reply to send_im */
static void do_im_ack(guint8 *data, gint data_len, PurpleConnection *gc)
{
- qq_data *qd;
-
g_return_if_fail(data != NULL && data_len != 0);
- qd = gc->proto_data;
-
if (data[0] != 0) {
purple_debug_warning("QQ", "Failed sent IM\n");
purple_notify_error(gc, _("Error"), _("Unable to send message."), NULL);
@@ -380,14 +373,11 @@ static void process_private_msg(guint8 *data, gint data_len, guint16 seq, Purple
/* Send ACK if the sys message needs an ACK */
static void request_server_ack(PurpleConnection *gc, gchar *funct_str, gchar *from, guint16 seq)
{
- qq_data *qd;
guint8 *raw_data;
gint bytes;
guint8 bar;
g_return_if_fail(funct_str != NULL && from != NULL);
- qd = (qq_data *) gc->proto_data;
-
bar = 0x1e;
raw_data = g_newa(guint8, strlen(funct_str) + strlen(from) + 16);
@@ -568,11 +558,9 @@ static void process_room_cmd_notify(PurpleConnection *gc,
void qq_update_room(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
{
- qq_data *qd;
gint ret;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail (gc != NULL);
switch (room_cmd) {
case 0:
@@ -599,12 +587,10 @@ void qq_update_room(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
void qq_update_all_rooms(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
{
- qq_data *qd;
gboolean is_new_turn = FALSE;
guint32 next_id;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(gc != NULL);
next_id = qq_room_get_next(gc, room_id);
purple_debug_info("QQ", "Update rooms, next id %u, prev id %u\n", next_id, room_id);
@@ -689,11 +675,9 @@ void qq_update_all(PurpleConnection *gc, guint16 cmd)
static void update_all_rooms_online(PurpleConnection *gc, guint8 room_cmd, guint32 room_id)
{
- qq_data *qd;
guint32 next_id;
- g_return_if_fail (gc != NULL && gc->proto_data != NULL);
- qd = (qq_data *) gc->proto_data;
+ g_return_if_fail (gc != NULL);
next_id = qq_room_get_next_conv(gc, room_id);
if (next_id <= 0 && room_id <= 0) {
diff --git a/libpurple/protocols/qq/qq_trans.c b/libpurple/protocols/qq/qq_trans.c
index 607fd5dbe1..19361955d1 100644
--- a/libpurple/protocols/qq/qq_trans.c
+++ b/libpurple/protocols/qq/qq_trans.c
@@ -109,11 +109,9 @@ guint32 qq_trans_get_ship(qq_transaction *trans)
static qq_transaction *trans_create(PurpleConnection *gc, gint fd,
guint16 cmd, guint16 seq, guint8 *data, gint data_len, guint32 update_class, guint32 ship32)
{
- qq_data *qd;
qq_transaction *trans;
- g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, NULL);
- qd = (qq_data *) gc->proto_data;
+ g_return_val_if_fail(gc != NULL, NULL);
trans = g_new0(qq_transaction, 1);
@@ -138,10 +136,11 @@ static qq_transaction *trans_create(PurpleConnection *gc, gint fd,
/* Remove a packet with seq from send trans */
static void trans_remove(PurpleConnection *gc, qq_transaction *trans)
{
- qq_data *qd = (qq_data *)gc->proto_data;
+ qq_data *qd;
- g_return_if_fail(gc != NULL && gc->proto_data != NULL);
+ g_return_if_fail(gc != NULL);
qd = (qq_data *) gc->proto_data;
+ g_return_if_fail(qd != NULL);
g_return_if_fail(trans != NULL);
#if 0
diff --git a/libpurple/protocols/qq/send_file.c b/libpurple/protocols/qq/send_file.c
index 7bc427836b..2e48e09582 100644
--- a/libpurple/protocols/qq/send_file.c
+++ b/libpurple/protocols/qq/send_file.c
@@ -637,10 +637,8 @@ static void _qq_xfer_cancel(PurpleXfer *xfer)
{
PurpleConnection *gc;
PurpleAccount *account;
- guint16 *seq;
g_return_if_fail (xfer != NULL);
- seq = (guint16 *) xfer->data;
account = purple_xfer_get_account(xfer);
gc = purple_account_get_connection(account);
@@ -670,10 +668,8 @@ static void _qq_xfer_recv_init(PurpleXfer *xfer)
{
PurpleConnection *gc;
PurpleAccount *account;
- ft_info *info;
- g_return_if_fail (xfer != NULL && xfer->data != NULL);
- info = (ft_info *) xfer->data;
+ g_return_if_fail(xfer != NULL);
account = purple_xfer_get_account(xfer);
gc = purple_account_get_connection(account);
@@ -752,7 +748,7 @@ void qq_process_recv_file_accept(guint8 *data, gint data_len, guint32 sender_uid
g_return_if_fail (data != NULL && data_len != 0);
qd = (qq_data *) gc->proto_data;
xfer = qd->xfer;
- info = (ft_info *) qd->xfer->data;
+ info = (ft_info *) xfer->data;
if (data_len <= 30 + QQ_CONN_INFO_LEN) {
purple_debug_warning("QQ", "Received file reject message is empty\n");
@@ -761,7 +757,7 @@ void qq_process_recv_file_accept(guint8 *data, gint data_len, guint32 sender_uid
bytes = 18 + 12; /* skip 30 bytes */
qq_get_conn_info(info, data + bytes);
- _qq_xfer_init_socket(qd->xfer);
+ _qq_xfer_init_socket(xfer);
_qq_xfer_init_udp_channel(info);
_qq_send_packet_file_notifyip(gc, sender_uid);
diff --git a/libpurple/protocols/sametime/sametime.c b/libpurple/protocols/sametime/sametime.c
index be9382c938..0c1eb33a7d 100644
--- a/libpurple/protocols/sametime/sametime.c
+++ b/libpurple/protocols/sametime/sametime.c
@@ -2133,7 +2133,7 @@ static struct mwServiceConference *mw_srvc_conf_new(struct mwSession *s) {
static void ft_incoming_cancel(PurpleXfer *xfer) {
- /* incoming transfer rejected or canceled in-progress */
+ /* incoming transfer rejected or cancelled in-progress */
struct mwFileTransfer *ft = xfer->data;
if(ft) mwFileTransfer_reject(ft);
}
diff --git a/libpurple/protocols/silc/chat.c b/libpurple/protocols/silc/chat.c
index 6ecbe5c314..729d6cdc13 100644
--- a/libpurple/protocols/silc/chat.c
+++ b/libpurple/protocols/silc/chat.c
@@ -1395,7 +1395,7 @@ PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
if (sg->roomlist)
purple_roomlist_unref(sg->roomlist);
- sg->roomlist_canceled = FALSE;
+ sg->roomlist_cancelled = FALSE;
sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc));
f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE);
@@ -1429,6 +1429,6 @@ void silcpurple_roomlist_cancel(PurpleRoomlist *list)
if (sg->roomlist == list) {
purple_roomlist_unref(sg->roomlist);
sg->roomlist = NULL;
- sg->roomlist_canceled = TRUE;
+ sg->roomlist_cancelled = TRUE;
}
}
diff --git a/libpurple/protocols/silc/ops.c b/libpurple/protocols/silc/ops.c
index df4a338667..fac1fde0e5 100644
--- a/libpurple/protocols/silc/ops.c
+++ b/libpurple/protocols/silc/ops.c
@@ -1455,7 +1455,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
int usercount;
PurpleRoomlistRoom *room;
- if (sg->roomlist_canceled)
+ if (sg->roomlist_cancelled)
break;
if (error != SILC_STATUS_OK) {
diff --git a/libpurple/protocols/silc/silcpurple.h b/libpurple/protocols/silc/silcpurple.h
index 50a451ed19..937e0cc358 100644
--- a/libpurple/protocols/silc/silcpurple.h
+++ b/libpurple/protocols/silc/silcpurple.h
@@ -85,7 +85,7 @@ typedef struct SilcPurpleStruct {
SilcMimeAssembler mimeass;
unsigned int detaching : 1;
unsigned int resuming : 1;
- unsigned int roomlist_canceled : 1;
+ unsigned int roomlist_cancelled : 1;
unsigned int chpk : 1;
} *SilcPurple;
diff --git a/libpurple/protocols/silc10/chat.c b/libpurple/protocols/silc10/chat.c
index b9c903ef51..d87598f327 100644
--- a/libpurple/protocols/silc10/chat.c
+++ b/libpurple/protocols/silc10/chat.c
@@ -1417,7 +1417,7 @@ PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc)
if (sg->roomlist)
purple_roomlist_unref(sg->roomlist);
- sg->roomlist_canceled = FALSE;
+ sg->roomlist_cancelled = FALSE;
sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc));
f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE);
@@ -1451,6 +1451,6 @@ void silcpurple_roomlist_cancel(PurpleRoomlist *list)
if (sg->roomlist == list) {
purple_roomlist_unref(sg->roomlist);
sg->roomlist = NULL;
- sg->roomlist_canceled = TRUE;
+ sg->roomlist_cancelled = TRUE;
}
}
diff --git a/libpurple/protocols/silc10/ops.c b/libpurple/protocols/silc10/ops.c
index f4b42fe3b7..8e3566e486 100644
--- a/libpurple/protocols/silc10/ops.c
+++ b/libpurple/protocols/silc10/ops.c
@@ -1444,7 +1444,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
int usercount;
PurpleRoomlistRoom *room;
- if (sg->roomlist_canceled)
+ if (sg->roomlist_cancelled)
break;
if (!success) {
diff --git a/libpurple/protocols/silc10/silcpurple.h b/libpurple/protocols/silc10/silcpurple.h
index 86ba056614..a24d8a0b9d 100644
--- a/libpurple/protocols/silc10/silcpurple.h
+++ b/libpurple/protocols/silc10/silcpurple.h
@@ -80,7 +80,7 @@ typedef struct SilcPurpleStruct {
#endif
unsigned int detaching : 1;
unsigned int resuming : 1;
- unsigned int roomlist_canceled : 1;
+ unsigned int roomlist_cancelled : 1;
unsigned int chpk : 1;
} *SilcPurple;
diff --git a/libpurple/protocols/yahoo/libymsg.c b/libpurple/protocols/yahoo/libymsg.c
index 3ed7f74bef..a448b5a0cb 100644
--- a/libpurple/protocols/yahoo/libymsg.c
+++ b/libpurple/protocols/yahoo/libymsg.c
@@ -502,8 +502,6 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
char *temp = NULL;
YahooFriend *f = NULL; /* It's your friends. They're going to want you to share your StarBursts. */
/* But what if you had no friends? */
- PurpleBuddy *b;
- PurpleGroup *g;
YahooFederation fed = YAHOO_FEDERATION_NONE;
int stealth = 0;
@@ -549,7 +547,9 @@ static void yahoo_process_list_15(PurpleConnection *gc, struct yahoo_packet *pkt
if (yd->current_list15_grp) {
/* This buddy is in a group */
f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!(b = purple_find_buddy(account, norm_bud))) {
+ if (!purple_find_buddy(account, norm_bud)) {
+ PurpleBuddy *b;
+ PurpleGroup *g;
if (!(g = purple_find_group(yd->current_list15_grp))) {
g = purple_group_new(yd->current_list15_grp);
purple_blist_add_group(g, NULL);
@@ -636,8 +636,6 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
GSList *l = pkt->hash;
gboolean export = FALSE;
gboolean got_serv_list = FALSE;
- PurpleBuddy *b;
- PurpleGroup *g;
YahooFriend *f = NULL;
PurpleAccount *account = purple_connection_get_account(gc);
YahooData *yd = gc->proto_data;
@@ -705,7 +703,9 @@ static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
norm_bud = g_strdup(purple_normalize(account, *bud));
f = yahoo_friend_find_or_new(gc, norm_bud);
- if (!(b = purple_find_buddy(account, norm_bud))) {
+ if (!purple_find_buddy(account, norm_bud)) {
+ PurpleBuddy *b;
+ PurpleGroup *g;
if (!(g = purple_find_group(grp))) {
g = purple_group_new(grp);
purple_blist_add_group(g, NULL);
@@ -2702,6 +2702,7 @@ void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
PurpleAccount *account;
YahooData *yd = gc->proto_data;
struct yahoo_p2p_data *p2p_data;
+ const char *norm_username;
f = yahoo_friend_find(gc, who);
account = purple_connection_get_account(gc);
@@ -2734,10 +2735,11 @@ void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
sprintf(temp_str, "%d", ip);
base64_ip = purple_base64_encode( (guchar *)temp_str, strlen(temp_str) );
+ norm_username = purple_normalize(account, purple_account_get_username(account));
pkt = yahoo_packet_new(YAHOO_SERVICE_PEERTOPEER, YAHOO_STATUS_AVAILABLE, 0);
yahoo_packet_hash(pkt, "sssissis",
- 1, purple_normalize(account, purple_account_get_username(account)),
- 4, purple_normalize(account, purple_account_get_username(account)),
+ 1, norm_username,
+ 4, norm_username,
12, base64_ip, /* base64 encode ip */
61, 0, /* To-do : figure out what is 61 for?? */
2, "",
@@ -3804,13 +3806,12 @@ const char *yahoo_list_emblem(PurpleBuddy *b)
{
PurpleAccount *account;
PurpleConnection *gc;
- YahooData *yd;
YahooFriend *f;
PurplePresence *presence;
if (!b || !(account = purple_buddy_get_account(b)) ||
!(gc = purple_account_get_connection(account)) ||
- !(yd = gc->proto_data))
+ !gc->proto_data)
return NULL;
f = yahoo_friend_find(gc, purple_buddy_get_name(b));
@@ -3905,7 +3906,6 @@ static void yahoo_game(PurpleBlistNode *node, gpointer data) {
PurpleBuddy *buddy;
PurpleConnection *gc;
- YahooData *yd;
const char *game;
char *game2;
char *t;
@@ -3916,7 +3916,6 @@ static void yahoo_game(PurpleBlistNode *node, gpointer data) {
buddy = (PurpleBuddy *) node;
gc = purple_account_get_connection(purple_buddy_get_account(buddy));
- yd = (YahooData *) gc->proto_data;
f = yahoo_friend_find(gc, purple_buddy_get_name(buddy));
if (!f)
@@ -4940,7 +4939,6 @@ void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
struct yahoo_packet *pkt;
const char *group = NULL;
char *group2;
- YahooFriend *f;
const char *bname;
const char *fed_bname;
YahooFederation fed = YAHOO_FEDERATION_NONE;
@@ -4952,7 +4950,6 @@ void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *g)
if (!purple_privacy_check(purple_connection_get_account(gc), bname))
return;
- f = yahoo_friend_find(gc, bname);
fed = yahoo_get_federation_from_name(bname);
if (fed != YAHOO_FEDERATION_NONE)
fed_bname += 4;
@@ -5215,15 +5212,11 @@ yahoopurple_cmd_chat_join(PurpleConversation *conv, const char *cmd,
{
GHashTable *comp;
PurpleConnection *gc;
- YahooData *yd;
- int id;
if (!args || !args[0])
return PURPLE_CMD_RET_FAILED;
gc = purple_conversation_get_gc(conv);
- yd = gc->proto_data;
- id = yd->conf_id;
purple_debug_info("yahoo", "Trying to join %s \n", args[0]);
comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
diff --git a/libpurple/protocols/yahoo/util.c b/libpurple/protocols/yahoo/util.c
index 57bbb84b6b..4d036d9b88 100644
--- a/libpurple/protocols/yahoo/util.c
+++ b/libpurple/protocols/yahoo/util.c
@@ -43,7 +43,7 @@ yahoo_account_use_http_proxy(PurpleConnection *pc)
if(proxy_ssl)
ppi = purple_proxy_get_setup(account);
else
- ppi = purple_global_proxy_get_info();
+ ppi = purple_proxy_get_setup(NULL);
type = purple_proxy_info_get_type(ppi);
diff --git a/libpurple/protocols/yahoo/yahoo_aliases.c b/libpurple/protocols/yahoo/yahoo_aliases.c
index fe5286fc87..3b0fc1f3d7 100644
--- a/libpurple/protocols/yahoo/yahoo_aliases.c
+++ b/libpurple/protocols/yahoo/yahoo_aliases.c
@@ -145,7 +145,7 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, con
if (alias != NULL) {
serv_got_alias(gc, yid, alias);
purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
- } else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) {
+ } else if (buddy_alias && *buddy_alias && !g_str_equal(buddy_alias, yid)) {
/* Or if we have an alias that Yahoo doesn't, send it up */
yahoo_update_alias(gc, yid, buddy_alias);
purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
diff --git a/libpurple/protocols/yahoo/yahoo_doodle.c b/libpurple/protocols/yahoo/yahoo_doodle.c
index 277adb74fa..f3f44a2631 100644
--- a/libpurple/protocols/yahoo/yahoo_doodle.c
+++ b/libpurple/protocols/yahoo/yahoo_doodle.c
@@ -372,7 +372,7 @@ void yahoo_doodle_command_got_shutdown(PurpleConnection *gc, const char *from)
/* TODO Ask if user wants to save picture before the session is closed */
- wb->state = DOODLE_STATE_CANCELED;
+ wb->state = DOODLE_STATE_CANCELLED;
purple_whiteboard_destroy(wb);
}
@@ -460,7 +460,7 @@ void yahoo_doodle_end(PurpleWhiteboard *wb)
/* g_debug_debug("yahoo", "doodle: yahoo_doodle_end()\n"); */
- if (gc && wb->state != DOODLE_STATE_CANCELED)
+ if (gc && wb->state != DOODLE_STATE_CANCELLED)
yahoo_doodle_command_send_shutdown(gc, wb->who);
g_free(ds->imv_key);
diff --git a/libpurple/protocols/yahoo/yahoo_doodle.h b/libpurple/protocols/yahoo/yahoo_doodle.h
index 3fda73b771..91329d4595 100644
--- a/libpurple/protocols/yahoo/yahoo_doodle.h
+++ b/libpurple/protocols/yahoo/yahoo_doodle.h
@@ -56,7 +56,7 @@
#define DOODLE_STATE_REQUESTING 0
#define DOODLE_STATE_REQUESTED 1
#define DOODLE_STATE_ESTABLISHED 2
-#define DOODLE_STATE_CANCELED 3
+#define DOODLE_STATE_CANCELLED 3
/* Doodle canvas dimensions */
#define DOODLE_CANVAS_WIDTH 368
diff --git a/libpurple/protocols/yahoo/yahoo_filexfer.c b/libpurple/protocols/yahoo/yahoo_filexfer.c
index 8f6fe64d5d..71c77d86bc 100644
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c
@@ -1235,14 +1235,14 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
PurpleXfer *xfer;
struct yahoo_xfer_data *xd;
PurpleAccount *account;
- YahooData* yd;
+ PurpleConnection *gc;
if (!(xfer = data))
return;
if (!(xd = xfer->data))
return;
- yd = xd->gc->proto_data;
- account = purple_connection_get_account(xd->gc);
+ gc = xd->gc;
+ account = purple_connection_get_account(gc);
if ((source < 0) || (xd->path == NULL) || (xd->host == NULL)) {
purple_xfer_error(PURPLE_XFER_RECEIVE, purple_xfer_get_account(xfer),
xfer->who, _("Unable to connect."));
@@ -1253,7 +1253,14 @@ static void yahoo_xfer_connected_15(gpointer data, gint source, const gchar *err
if (xd->txbuflen == 0)
{
gchar* cookies;
- cookies = yahoo_get_cookies(xd->gc);
+ YahooData *yd = gc->proto_data;
+
+ /* cookies = yahoo_get_cookies(gc);
+ * This doesn't seem to be working. The function is returning NULL, which yahoo servers don't like
+ * For now let us not use this function */
+
+ cookies = g_strdup_printf("Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
+
if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && xd->status_15 == ACCEPTED)
{
if(xd->info_val_249 == 2)
diff --git a/libpurple/protocols/yahoo/yahoochat.c b/libpurple/protocols/yahoo/yahoochat.c
index 7453990ea5..0f8a042598 100644
--- a/libpurple/protocols/yahoo/yahoochat.c
+++ b/libpurple/protocols/yahoo/yahoochat.c
@@ -121,7 +121,6 @@ void yahoo_process_conference_invite(PurpleConnection *gc, struct yahoo_packet *
char *msg = NULL;
GString *members = NULL;
GHashTable *components;
- PurpleConversation *c = NULL;
if ( (pkt->status == 2) || (pkt->status == 11) )
return; /* Status is 11 when we are being notified about invitation being sent to someone else */
@@ -133,7 +132,7 @@ void yahoo_process_conference_invite(PurpleConnection *gc, struct yahoo_packet *
if (pair->key == 57)
{
room = yahoo_string_decode(gc, pair->value, FALSE);
- if((c = yahoo_find_conference(gc, room)))
+ if (yahoo_find_conference(gc, room) != NULL)
{
/* Looks like we got invited to an already open conference. */
/* Laters: Should we accept this conference rather than ignoring the invitation ? */
@@ -618,9 +617,6 @@ void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt)
char *who = NULL;
char *room = NULL;
GSList *l;
- YahooData *yd;
-
- yd = gc->proto_data;
for (l = pkt->hash; l; l = l->next) {
struct yahoo_pair *pair = l->data;
@@ -639,8 +635,7 @@ void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt)
purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
}
- if (room)
- g_free(room);
+ g_free(room);
}
void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt)
@@ -880,7 +875,6 @@ static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char
{
YahooData *yd = gc->proto_data;
struct yahoo_packet *pkt;
- PurpleConversation *c;
char *eroom;
gboolean utf8 = 1;
@@ -905,7 +899,7 @@ static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char
yd->chat_name = NULL;
}
- if ((c = purple_find_chat(gc, YAHOO_CHAT_ID)))
+ if (purple_find_chat(gc, YAHOO_CHAT_ID) != NULL)
serv_got_chat_left(gc, YAHOO_CHAT_ID);
if (!logout)
diff --git a/libpurple/protocols/zephyr/ZVariables.c b/libpurple/protocols/zephyr/ZVariables.c
index f11ba9d91c..028a8bdda8 100644
--- a/libpurple/protocols/zephyr/ZVariables.c
+++ b/libpurple/protocols/zephyr/ZVariables.c
@@ -30,10 +30,10 @@ char *ZGetVariable(var)
if ((varfile = get_localvarfile()) == NULL)
return ((char *)0);
- if ((ret = get_varval(varfile, var)) != ZERR_NONE) {
- g_free(varfile);
+ ret = get_varval(varfile, var);
+ g_free(varfile);
+ if (ret != ZERR_NONE)
return ret;
- }
#ifdef WIN32
varfile = g_strdup("C:\\zephyr\\zephyr.var");
diff --git a/libpurple/proxy.c b/libpurple/proxy.c
index 15e943711b..63b0cc8688 100644
--- a/libpurple/proxy.c
+++ b/libpurple/proxy.c
@@ -1023,7 +1023,7 @@ http_canread(gpointer data, gint source, PurpleInputCondition cond)
g_free(response);
- } else if((header = g_strrstr((const char *)connect_data->read_buffer, "Proxy-Authenticate: Basic"))) {
+ } else if (g_strrstr((const char *)connect_data->read_buffer, "Proxy-Authenticate: Basic") != NULL) {
gchar *t1, *t2;
const char *username, *password;
diff --git a/libpurple/request.c b/libpurple/request.c
index 1dd4028170..391e993d8d 100644
--- a/libpurple/request.c
+++ b/libpurple/request.c
@@ -1399,6 +1399,11 @@ purple_request_action_with_icon_varg(void *handle, const char *title,
handles = g_list_append(handles, info);
return info->ui_handle;
+ } else {
+ /* Fall back on the non-icon request if the UI doesn't support icon
+ requests */
+ return purple_request_action_varg(handle, title, primary, secondary,
+ default_action, account, who, conv, user_data, action_count, actions);
}
return NULL;
diff --git a/libpurple/stun.c b/libpurple/stun.c
index c6f71da0b4..a6f516155d 100644
--- a/libpurple/stun.c
+++ b/libpurple/stun.c
@@ -105,11 +105,11 @@ static void close_stun_conn(struct stun_conn *sc) {
}
static void do_callbacks(void) {
- while(callbacks) {
+ while (callbacks) {
StunCallback cb = callbacks->data;
- if(cb)
+ if (cb)
cb(&nattype);
- callbacks = g_slist_remove(callbacks, cb);
+ callbacks = g_slist_delete_link(callbacks, callbacks);
}
}
@@ -280,7 +280,6 @@ static void hbn_listen_cb(int fd, gpointer data) {
GSList *hosts = data;
struct stun_conn *sc;
static struct stun_header hdr_data;
- int ret;
if(fd < 0) {
nattype.status = PURPLE_STUN_STATUS_UNKNOWN;
@@ -298,15 +297,14 @@ static void hbn_listen_cb(int fd, gpointer data) {
sc->incb = purple_input_add(fd, PURPLE_INPUT_READ, reply_cb, sc);
- ret = GPOINTER_TO_INT(hosts->data);
- hosts = g_slist_remove(hosts, hosts->data);
+ hosts = g_slist_delete_link(hosts, hosts);
memcpy(&(sc->addr), hosts->data, sizeof(struct sockaddr_in));
g_free(hosts->data);
- hosts = g_slist_remove(hosts, hosts->data);
- while(hosts) {
- hosts = g_slist_remove(hosts, hosts->data);
+ hosts = g_slist_delete_link(hosts, hosts);
+ while (hosts) {
+ hosts = g_slist_delete_link(hosts, hosts);
g_free(hosts->data);
- hosts = g_slist_remove(hosts, hosts->data);
+ hosts = g_slist_delete_link(hosts, hosts);
}
hdr_data.type = htons(MSGTYPE_BINDINGREQUEST);
@@ -341,10 +339,10 @@ static void hbn_cb(GSList *hosts, gpointer data, const char *error_message) {
}
if (!purple_network_listen_range(12108, 12208, SOCK_DGRAM, hbn_listen_cb, hosts)) {
- while(hosts) {
- hosts = g_slist_remove(hosts, hosts->data);
+ while (hosts) {
+ hosts = g_slist_delete_link(hosts, hosts);
g_free(hosts->data);
- hosts = g_slist_remove(hosts, hosts->data);
+ hosts = g_slist_delete_link(hosts, hosts);
}
nattype.status = PURPLE_STUN_STATUS_UNKNOWN;
diff --git a/libpurple/util.c b/libpurple/util.c
index fe2d9f28ec..60320c9ffe 100644
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -3115,7 +3115,7 @@ purple_str_strip_char(char *text, char thechar)
if (text[i] != thechar)
text[j++] = text[i];
- text[j++] = '\0';
+ text[j] = '\0';
}
void
diff --git a/libpurple/win32/global.mak b/libpurple/win32/global.mak
index edda84a9e0..4351f3d989 100644
--- a/libpurple/win32/global.mak
+++ b/libpurple/win32/global.mak
@@ -37,7 +37,6 @@ PURPLE_TOP := $(PIDGIN_TREE_TOP)/libpurple
PURPLE_PLUGINS_TOP := $(PURPLE_TOP)/plugins
PURPLE_PERL_TOP := $(PURPLE_PLUGINS_TOP)/perl
PIDGIN_TOP := $(PIDGIN_TREE_TOP)/pidgin
-PIDGIN_IDLETRACK_TOP := $(PIDGIN_TOP)/win32/IdleTracker
PIDGIN_PIXMAPS_TOP := $(PIDGIN_TOP)/pixmaps
PIDGIN_PLUGINS_TOP := $(PIDGIN_TOP)/plugins
PURPLE_PO_TOP := $(PIDGIN_TREE_TOP)/po
@@ -48,7 +47,6 @@ PIDGIN_CONFIG_H := $(PIDGIN_TREE_TOP)/config.h
PURPLE_CONFIG_H := $(PIDGIN_TREE_TOP)/config.h
PIDGIN_REVISION_H := $(PIDGIN_TREE_TOP)/package_revision.h
PIDGIN_REVISION_RAW_TXT := $(PIDGIN_TREE_TOP)/package_revision_raw.txt
-PIDGIN_IDLETRACK_DLL := $(PIDGIN_IDLETRACK_TOP)/idletrack.dll
PURPLE_PURPLE_H := $(PURPLE_TOP)/purple.h
PURPLE_VERSION_H := $(PURPLE_TOP)/version.h
PURPLE_DLL := $(PURPLE_TOP)/libpurple.dll
diff --git a/libpurple/win32/targets.mak b/libpurple/win32/targets.mak
index 89b912d5f6..e31c2f424a 100644
--- a/libpurple/win32/targets.mak
+++ b/libpurple/win32/targets.mak
@@ -36,9 +36,6 @@ $(PURPLE_PERL_DLL) $(PURPLE_PERL_DLL).a:
$(PIDGIN_DLL) $(PIDGIN_DLL).a:
$(MAKE) -C $(PIDGIN_TOP) -f $(MINGW_MAKEFILE) pidgin.dll
-$(PIDGIN_IDLETRACK_DLL) $(PIDGIN_IDLETRACK_DLL).a:
- $(MAKE) -C $(PIDGIN_IDLETRACK_TOP) -f $(MINGW_MAKEFILE) idletrack.dll
-
$(PIDGIN_EXE):
$(MAKE) -C $(PIDGIN_TOP) -f $(MINGW_MAKEFILE) pidgin.exe
diff --git a/libpurple/win32/win32dep.c b/libpurple/win32/win32dep.c
index d2740dc15f..2c2824f744 100644
--- a/libpurple/win32/win32dep.c
+++ b/libpurple/win32/win32dep.c
@@ -35,7 +35,7 @@
static char *app_data_dir = NULL, *install_dir = NULL,
*lib_dir = NULL, *locale_dir = NULL;
-static HINSTANCE libpurpledll_hInstance = 0;
+static HINSTANCE libpurpledll_hInstance = NULL;
/*
* PUBLIC CODE
@@ -77,16 +77,23 @@ FARPROC wpurple_find_and_loadproc(const char *dllname, const char *procedure) {
BOOL did_load = FALSE;
FARPROC proc = 0;
- if(!(hmod = GetModuleHandle(dllname))) {
+ wchar_t *wc_dllname = g_utf8_to_utf16(dllname, -1, NULL, NULL, NULL);
+
+ if(!(hmod = GetModuleHandleW(wc_dllname))) {
purple_debug_warning("wpurple", "%s not already loaded; loading it...\n", dllname);
- if(!(hmod = LoadLibrary(dllname))) {
- purple_debug_error("wpurple", "Could not load: %s\n", dllname);
+ if(!(hmod = LoadLibraryW(wc_dllname))) {
+ purple_debug_error("wpurple", "Could not load: %s (%s)\n", dllname,
+ g_win32_error_message(GetLastError()));
+ g_free(wc_dllname);
return NULL;
}
else
did_load = TRUE;
}
+ g_free(wc_dllname);
+ wc_dllname = NULL;
+
if((proc = GetProcAddress(hmod, procedure))) {
purple_debug_info("wpurple", "This version of %s contains %s\n",
dllname, procedure);
@@ -124,7 +131,7 @@ const char *wpurple_install_dir(void) {
if (!initialized) {
char *tmp = NULL;
wchar_t winstall_dir[MAXPATHLEN];
- if (GetModuleFileNameW(NULL, winstall_dir,
+ if (GetModuleFileNameW(libpurpledll_hInstance, winstall_dir,
MAXPATHLEN) > 0) {
tmp = g_utf16_to_utf8(winstall_dir, -1,
NULL, NULL, NULL);
diff --git a/pidgin.spec.in b/pidgin.spec.in
index faddee0d69..5aa7be6772 100644
--- a/pidgin.spec.in
+++ b/pidgin.spec.in
@@ -46,12 +46,14 @@ BuildRequires: gtk2-devel, libidn-devel
%if "%{_vendor}" == "suse"
# For SuSE:
BuildRequires: gnutls-devel
+%define sslopts "--enable-gnutls=yes --enable-nss=no"
%{?_with_dbus:BuildRequires: dbus-1-devel >= 0.35}
%{!?_without_gstreamer:BuildRequires: gstreamer010-devel >= 0.10}
Requires(pre): gconf2
Requires(post): gconf2
Requires(preun): gconf2
%else
+%define sslopts "--enable-gnutls=no --enable-nss=yes"
%{?_with_dbus:BuildRequires: dbus-devel >= 0.35}
%{!?_without_gstreamer:BuildRequires: gstreamer-devel >= 0.10}
Requires(pre): GConf2
@@ -230,6 +232,7 @@ CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix} \
--mandir=%{_mandir} \
--sysconfdir=%{_sysconfdir} \
--disable-schemas-install \
+ %{sslopts} \
%{!?_with_vv:--disable-vv} \
%{!?_with_dbus:--disable-dbus} \
%{!?_with_avahi:--disable-avahi} \
@@ -471,6 +474,9 @@ fi
%endif
%changelog
+* Wed Sep 01 2010 Stu Tomlinson <stu@nosnilmot.com>
+- Ensure predictable use of SSL libs
+
* Wed Jun 02 2010 Stu Tomlinson <stu@nosnilmot.com>
- add an option to build RPMs using --enable-trayicon-compat
(--with trayiconcompat)
diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
index 56731e0cc7..2cabab439b 100644
--- a/pidgin/Makefile.am
+++ b/pidgin/Makefile.am
@@ -5,9 +5,6 @@ EXTRA_DIST = \
Makefile.mingw \
pidgin.pc.in \
pidgin-uninstalled.pc.in \
- win32/IdleTracker/Makefile.mingw \
- win32/IdleTracker/idletrack.c \
- win32/IdleTracker/idletrack.h \
win32/MinimizeToTray.h \
win32/MinimizeToTray.c \
win32/pidgin_dll_rc.rc.in \
diff --git a/pidgin/Makefile.mingw b/pidgin/Makefile.mingw
index f245022c53..dd4f13285f 100644
--- a/pidgin/Makefile.mingw
+++ b/pidgin/Makefile.mingw
@@ -33,7 +33,6 @@ PURPLE_INCLUDE_PATHS = \
INCLUDE_PATHS += \
$(PURPLE_INCLUDE_PATHS) \
- -I$(PIDGIN_IDLETRACK_TOP) \
-I$(PIDGIN_TOP) \
-I$(PIDGIN_TOP)/win32 \
-I$(GTK_TOP)/include/gtk-2.0 \
@@ -45,8 +44,7 @@ INCLUDE_PATHS += \
LIB_PATHS += -L$(GTK_TOP)/lib \
-L$(PURPLE_TOP) \
- -L$(PIDGIN_TOP) \
- -L$(PIDGIN_IDLETRACK_TOP)
+ -L$(PIDGIN_TOP)
##
## SOURCES, OBJECTS
@@ -121,7 +119,6 @@ PIDGIN_LIBS = \
-lgthread-2.0 \
-lpurple \
-lz \
- -lidletrack \
-lgtk-win32-2.0 \
-latk-1.0 \
-lpango-1.0 \
@@ -151,7 +148,6 @@ install_shallow: $(PIDGIN_INSTALL_DIR) $(EXE_TARGET).exe $(PIDGIN_TARGET).dll
install: install_shallow all
$(MAKE) -C $(PIDGIN_PLUGINS_TOP) -f $(MINGW_MAKEFILE) install
$(MAKE) -C $(PIDGIN_PIXMAPS_TOP) -f $(MINGW_MAKEFILE) install
- $(MAKE) -C $(PIDGIN_IDLETRACK_TOP) -f $(MINGW_MAKEFILE) install
win32/pidgin_dll_rc.rc: win32/pidgin_dll_rc.rc.in $(PIDGIN_TREE_TOP)/VERSION
sed -e 's/@PIDGIN_VERSION@/$(PIDGIN_VERSION)/g' \
@@ -159,7 +155,7 @@ win32/pidgin_dll_rc.rc: win32/pidgin_dll_rc.rc.in $(PIDGIN_TREE_TOP)/VERSION
$(EXE_OBJECTS) $(PIDGIN_OBJECTS): $(PIDGIN_CONFIG_H)
-$(PIDGIN_TARGET).dll $(PIDGIN_TARGET).dll.a: $(PURPLE_DLL).a $(PIDGIN_IDLETRACK_DLL).a $(PIDGIN_OBJECTS)
+$(PIDGIN_TARGET).dll $(PIDGIN_TARGET).dll.a: $(PURPLE_DLL).a $(PIDGIN_OBJECTS)
$(CC) -shared $(PIDGIN_OBJECTS) $(LIB_PATHS) $(PIDGIN_LIBS) $(DLL_LD_FLAGS) -Wl,--output-def,$(PIDGIN_TARGET).def,--out-implib,$(PIDGIN_TARGET).dll.a -o $(PIDGIN_TARGET).dll
$(EXE_TARGET).exe: $(PIDGIN_CONFIG_H) $(PIDGIN_DLL).a $(EXE_OBJECTS) $(PIDGIN_TARGET).dll
@@ -169,7 +165,6 @@ $(EXE_TARGET).exe: $(PIDGIN_CONFIG_H) $(PIDGIN_DLL).a $(EXE_OBJECTS) $(PIDGIN_TA
## CLEAN RULES
##
clean:
- $(MAKE) -C $(PIDGIN_IDLETRACK_TOP) -f $(MINGW_MAKEFILE) clean
$(MAKE) -C $(PIDGIN_PLUGINS_TOP) -f $(MINGW_MAKEFILE) clean
$(MAKE) -C $(PIDGIN_PIXMAPS_TOP) -f $(MINGW_MAKEFILE) clean
rm -f $(PIDGIN_OBJECTS) $(PIDGIN_RC_SRC) $(EXE_OBJECTS) $(EXE_RC_SRC)
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
index 03f05a49a8..d18f11bbf5 100644
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -2418,35 +2418,38 @@ pidgin_accounts_request_add(PurpleAccount *account, const char *remote_user,
g_free(buffer);
}
-struct auth_and_add {
+struct auth_request
+{
PurpleAccountRequestAuthorizationCb auth_cb;
PurpleAccountRequestAuthorizationCb deny_cb;
void *data;
char *username;
char *alias;
PurpleAccount *account;
+ gboolean add_buddy_after_auth;
};
static void
-free_auth_and_add(struct auth_and_add *aa)
+free_auth_request(struct auth_request *ar)
{
- g_free(aa->username);
- g_free(aa->alias);
- g_free(aa);
+ g_free(ar->username);
+ g_free(ar->alias);
+ g_free(ar);
}
static void
-authorize_and_add_cb(struct auth_and_add *aa)
+authorize_and_add_cb(struct auth_request *ar)
{
- aa->auth_cb(aa->data);
- purple_blist_request_add_buddy(aa->account, aa->username,
- NULL, aa->alias);
+ ar->auth_cb(ar->data);
+ if (ar->add_buddy_after_auth) {
+ purple_blist_request_add_buddy(ar->account, ar->username, NULL, ar->alias);
+ }
}
static void
-deny_no_add_cb(struct auth_and_add *aa)
+deny_no_add_cb(struct auth_request *ar)
{
- aa->deny_cb(aa->data);
+ ar->deny_cb(ar->data);
}
static void *
@@ -2463,49 +2466,48 @@ pidgin_accounts_request_authorization(PurpleAccount *account,
char *buffer;
PurpleConnection *gc;
GtkWidget *alert;
+ GdkPixbuf *prpl_icon;
+ struct auth_request *aa;
gc = purple_account_get_connection(account);
if (message != NULL && *message == '\0')
message = NULL;
- buffer = g_strdup_printf(_("%s%s%s%s wants to add %s to his or her buddy list%s%s"),
+ buffer = g_strdup_printf(_("%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"),
remote_user,
- (alias != NULL ? " (" : ""),
- (alias != NULL ? alias : ""),
- (alias != NULL ? ")" : ""),
- (id != NULL
- ? id
- : (purple_connection_get_display_name(gc) != NULL
- ? purple_connection_get_display_name(gc)
- : purple_account_get_username(account))),
- (message != NULL ? ": " : "."),
- (message != NULL ? message : ""));
-
-
- if (!on_list) {
- struct auth_and_add *aa = g_new0(struct auth_and_add, 1);
- aa->auth_cb = auth_cb;
- aa->deny_cb = deny_cb;
- aa->data = user_data;
- aa->username = g_strdup(remote_user);
- aa->alias = g_strdup(alias);
- aa->account = account;
- alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION,
- _("Authorize buddy?"), buffer, aa,
- _("Authorize"), authorize_and_add_cb,
- _("Deny"), deny_no_add_cb,
- NULL);
- g_signal_connect_swapped(G_OBJECT(alert), "destroy", G_CALLBACK(free_auth_and_add), aa);
- } else {
- alert = pidgin_make_mini_dialog(gc, PIDGIN_STOCK_DIALOG_QUESTION,
- _("Authorize buddy?"), buffer, user_data,
- _("Authorize"), auth_cb,
- _("Deny"), deny_cb,
- NULL);
- }
+ (alias != NULL ? " (" : ""),
+ (alias != NULL ? alias : ""),
+ (alias != NULL ? ")" : ""),
+ (id != NULL
+ ? id
+ : (purple_connection_get_display_name(gc) != NULL
+ ? purple_connection_get_display_name(gc)
+ : purple_account_get_username(account))),
+ (message != NULL ? ": " : "."),
+ (message != NULL ? message : ""));
+
+
+ prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
+
+ aa = g_new0(struct auth_request, 1);
+ aa->auth_cb = auth_cb;
+ aa->deny_cb = deny_cb;
+ aa->data = user_data;
+ aa->username = g_strdup(remote_user);
+ aa->alias = g_strdup(alias);
+ aa->account = account;
+ aa->add_buddy_after_auth = !on_list;
+
+ alert = pidgin_make_mini_dialog_with_custom_icon(
+ gc, prpl_icon,
+ _("Authorize buddy?"), buffer, aa,
+ _("Authorize"), authorize_and_add_cb,
+ _("Deny"), deny_no_add_cb,
+ NULL);
+
+ g_signal_connect_swapped(G_OBJECT(alert), "destroy", G_CALLBACK(free_auth_request), aa);
+ g_signal_connect(G_OBJECT(alert), "destroy", G_CALLBACK(purple_account_request_close), NULL);
pidgin_blist_add_alert(alert);
- g_signal_connect(G_OBJECT(alert), "destroy",
- G_CALLBACK(purple_account_request_close), NULL);
g_free(buffer);
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
index 17a4032f2b..75e0c58ebe 100644
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -3168,7 +3168,6 @@ pidgin_blist_create_tooltip_for_node(GtkWidget *widget, gpointer data, int *w, i
} else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
PurpleBlistNode *child;
PurpleBuddy *b = purple_contact_get_priority_buddy((PurpleContact *)node);
- width = height = 0;
for(child = node->child; child; child = child->next)
{
@@ -3654,6 +3653,9 @@ set_mood_show(void)
***************************************************/
static GtkItemFactoryEntry blist_menu[] =
{
+/* NOTE: Do not set any accelerator to Control+O. It is mapped by
+ gtk_blist_key_press_cb to "Get User Info" on the selected buddy. */
+
/* Buddies menu */
{ N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL },
{ N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
@@ -3687,7 +3689,7 @@ static GtkItemFactoryEntry blist_menu[] =
{ N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
{ N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
{ N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
- { N_("/Tools/Set _Mood"), "<CTL>O", set_mood_show, 0, "<Item>", NULL },
+ { N_("/Tools/Set _Mood"), "<CTL>D", set_mood_show, 0, "<Item>", NULL },
{ "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
{ N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
{ N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
@@ -3966,7 +3968,6 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
tmp);
g_free(tmp);
}
- count = 0;
count = purple_blist_get_group_size(group, FALSE);
if (count != 0) {
@@ -3977,7 +3978,6 @@ static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full)
tmp);
g_free(tmp);
}
- count = 0;
tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n");
g_string_append(str, tmp);
@@ -4024,7 +4024,6 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
{
PurpleBuddy *buddy = NULL;
struct _pidgin_blist_node *gtknode = node->ui_data;
- struct _pidgin_blist_node *gtkbuddynode = NULL;
PurplePlugin *prpl;
PurplePluginProtocolInfo *prpl_info;
const char *name = NULL;
@@ -4035,11 +4034,9 @@ pidgin_blist_get_emblem(PurpleBlistNode *node)
if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
if(!gtknode->contact_expanded) {
buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
- gtkbuddynode = ((PurpleBlistNode*)buddy)->ui_data;
}
} else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
buddy = (PurpleBuddy*)node;
- gtkbuddynode = node->ui_data;
p = purple_buddy_get_presence(buddy);
if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
/* This emblem comes from the small emoticon set now,
@@ -4132,7 +4129,6 @@ GdkPixbuf *
pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
{
GdkPixbuf *ret;
- const char *protoname = NULL;
const char *icon = NULL;
struct _pidgin_blist_node *gtknode = node->ui_data;
struct _pidgin_blist_node *gtkbuddynode = NULL;
@@ -4159,7 +4155,6 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
if(buddy || chat) {
PurpleAccount *account;
PurplePlugin *prpl;
- PurplePluginProtocolInfo *prpl_info;
if(buddy)
account = buddy->account;
@@ -4169,12 +4164,6 @@ pidgin_blist_get_status_icon(PurpleBlistNode *node, PidginStatusIconSize size)
prpl = purple_find_prpl(purple_account_get_protocol_id(account));
if(!prpl)
return NULL;
-
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
- if(prpl_info && prpl_info->list_icon) {
- protoname = prpl_info->list_icon(account, buddy);
- }
}
if(buddy) {
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index c766d58b79..c4da5883a3 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -750,9 +750,9 @@ static void
do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
{
const char *buddy, *message;
- PidginConversation *gtkconv;
+ PurpleConversation *conv;
- gtkconv = PIDGIN_CONVERSATION(info->conv);
+ conv = info->conv;
if (resp == GTK_RESPONSE_OK) {
buddy = gtk_entry_get_text(GTK_ENTRY(info->entry));
@@ -761,8 +761,8 @@ do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
if (!g_ascii_strcasecmp(buddy, ""))
return;
- serv_chat_invite(purple_conversation_get_gc(info->conv),
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(info->conv)),
+ serv_chat_invite(purple_conversation_get_gc(conv),
+ purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
message, buddy);
}
@@ -856,7 +856,6 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
InviteBuddyInfo *info = NULL;
if (invite_dialog == NULL) {
- PurpleConnection *gc;
PidginWindow *gtkwin;
GtkWidget *label;
GtkWidget *vbox, *hbox;
@@ -869,7 +868,6 @@ invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
info = g_new0(InviteBuddyInfo, 1);
info->conv = conv;
- gc = purple_conversation_get_gc(conv);
gtkwin = pidgin_conv_get_window(gtkconv);
/* Create the new dialog. */
@@ -1200,12 +1198,10 @@ static void
menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
{
PidginWindow *win = data;
- PurpleConversation *conv;
PidginConversation *gtkconv;
GtkIMHtmlToolbar *toolbar;
gtkconv = pidgin_conv_window_get_active_gtkconv(win);
- conv = gtkconv->active_conv;
toolbar = GTK_IMHTMLTOOLBAR(gtkconv->toolbar);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->image),
@@ -1911,10 +1907,8 @@ static gboolean
conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
{
PidginWindow *win;
- PurpleConversation *conv;
int curconv;
- conv = gtkconv->active_conv;
win = gtkconv->win;
curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook));
@@ -2009,13 +2003,11 @@ conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
static gboolean
entry_key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer data)
{
- PidginWindow *win;
PurpleConversation *conv;
PidginConversation *gtkconv;
gtkconv = (PidginConversation *)data;
conv = gtkconv->active_conv;
- win = gtkconv->win;
if (conv_keypress_common(gtkconv, event))
return TRUE;
@@ -2350,12 +2342,9 @@ insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *position,
gchar *new_text, gint new_text_length, gpointer user_data)
{
PidginConversation *gtkconv = (PidginConversation *)user_data;
- PurpleConversation *conv;
g_return_if_fail(gtkconv != NULL);
- conv = gtkconv->active_conv;
-
if (!purple_prefs_get_bool("/purple/conversations/im/send_typing"))
return;
@@ -2617,7 +2606,6 @@ redraw_icon(gpointer data)
PidginConversation *gtkconv = (PidginConversation *)data;
PurpleConversation *conv = gtkconv->active_conv;
PurpleAccount *account;
- PurplePluginProtocolInfo *prpl_info = NULL;
GdkPixbuf *buf;
GdkPixbuf *scale;
@@ -2628,9 +2616,7 @@ redraw_icon(gpointer data)
gtkconv = PIDGIN_CONVERSATION(conv);
account = purple_conversation_get_account(conv);
- if(account && account->gc) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
- } else {
+ if (!(account && account->gc)) {
gtkconv->u.im->icon_timer = 0;
return FALSE;
}
@@ -2702,7 +2688,6 @@ remove_icon(GtkWidget *widget, PidginConversation *gtkconv)
GList *children;
GtkWidget *event;
PurpleConversation *conv = gtkconv->active_conv;
- PidginWindow *gtkwin;
g_return_if_fail(conv != NULL);
@@ -2730,8 +2715,6 @@ remove_icon(GtkWidget *widget, PidginConversation *gtkconv)
gtkconv->u.im->anim = NULL;
gtkconv->u.im->iter = NULL;
gtkconv->u.im->show_icon = FALSE;
-
- gtkwin = gtkconv->win;
}
static void
@@ -3684,13 +3667,10 @@ update_typing_message(PidginConversation *gtkconv, const char *message)
static void
update_typing_icon(PidginConversation *gtkconv)
{
- PidginWindow *gtkwin;
PurpleConvIm *im = NULL;
PurpleConversation *conv = gtkconv->active_conv;
char *message = NULL;
- gtkwin = gtkconv->win;
-
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
im = PURPLE_CONV_IM(conv);
@@ -5740,10 +5720,8 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
time_t mtime)
{
PidginConversation *gtkconv;
- PidginWindow *win;
PurpleConnection *gc;
PurpleAccount *account;
- PurplePluginProtocolInfo *prpl_info;
int gtk_font_options = 0;
int gtk_font_options_all = 0;
int max_scrollback_lines;
@@ -5830,9 +5808,6 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
g_free(tmp);
}
- win = gtkconv->win;
- prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
-
line_count = gtk_text_buffer_get_line_count(
gtk_text_view_get_buffer(GTK_TEXT_VIEW(
gtkconv->imhtml)));
@@ -6263,7 +6238,6 @@ static void
pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user)
{
PurpleConvChat *chat;
- PurpleConvChatBuddyFlags flags;
PurpleConvChatBuddy *cbuddy;
PidginConversation *gtkconv;
PidginChatPane *gtkchat;
@@ -6306,8 +6280,6 @@ pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user)
g_return_if_fail(alias != NULL);
- flags = purple_conv_chat_user_get_flags(chat, user);
-
cbuddy = purple_conv_chat_cb_find(chat, user);
if (cbuddy)
add_chat_buddy_common(conv, cbuddy, NULL);
@@ -6729,7 +6701,6 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
PurpleConvIm *im = NULL;
PurpleAccount *account = purple_conversation_get_account(conv);
PurpleBuddy *buddy = NULL;
- PurplePresence *p = NULL;
char *markup = NULL;
AtkObject *accessibility_obj;
/* I think this is a little longer than it needs to be but I'm lazy. */
@@ -6749,7 +6720,6 @@ pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields)
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
buddy = purple_find_buddy(account, conv->name);
if (buddy) {
- p = purple_buddy_get_presence(buddy);
markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
} else {
markup = title;
@@ -6964,7 +6934,6 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
int size = 0;
PurpleAccount *account;
- PurplePluginProtocolInfo *prpl_info = NULL;
PurpleBuddyIcon *icon;
@@ -6981,8 +6950,6 @@ pidgin_conv_update_buddy_icon(PurpleConversation *conv)
return;
account = purple_conversation_get_account(conv);
- if(account && account->gc)
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
/* Remove the current icon stuff */
children = gtk_container_get_children(GTK_CONTAINER(gtkconv->u.im->icon_container));
@@ -8627,7 +8594,7 @@ infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkc
static gboolean
notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
{
- gint nb_x, nb_y, x_rel, y_rel;
+ gint nb_x, nb_y;
int tab_clicked;
GtkWidget *page;
GtkWidget *tab;
@@ -8670,9 +8637,6 @@ notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
*/
gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y);
- x_rel = e->x_root - nb_x;
- y_rel = e->y_root - nb_y;
-
/* Reset the min/max x/y */
win->drag_min_x = 0;
win->drag_min_y = 0;
@@ -9239,6 +9203,7 @@ pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
if (win && win->window &&
!GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) {
+#ifdef _WIN32 /* only override window manager placement on Windows */
/* ...check position is on screen... */
if (conv_x >= gdk_screen_width())
conv_x = gdk_screen_width() - 100;
@@ -9251,7 +9216,6 @@ pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
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);
@@ -9503,7 +9467,7 @@ pidgin_conv_window_add_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
gtk_widget_show(gtkconv->menu_tabby);
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+ if (conv_type == PURPLE_CONV_TYPE_IM)
pidgin_conv_update_buddy_icon(conv);
/* Build and set conversations tab */
@@ -9630,9 +9594,7 @@ void
pidgin_conv_window_remove_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
{
unsigned int index;
- PurpleConversationType conv_type;
- conv_type = purple_conversation_get_type(gtkconv->active_conv);
index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
g_object_ref(gtkconv->tab_cont);
@@ -9965,12 +9927,9 @@ conv_get_group(PidginConversation *conv)
static void
conv_placement_by_group(PidginConversation *conv)
{
- PurpleConversationType type;
PurpleGroup *group = NULL;
GList *wl, *cl;
- type = purple_conversation_get_type(conv->active_conv);
-
group = conv_get_group(conv);
/* Go through the list of IMs and find one with this group. */
@@ -10004,12 +9963,10 @@ conv_placement_by_group(PidginConversation *conv)
static void
conv_placement_by_account(PidginConversation *conv)
{
- PurpleConversationType type;
GList *wins, *convs;
PurpleAccount *account;
account = purple_conversation_get_account(conv->active_conv);
- type = purple_conversation_get_type(conv->active_conv);
/* Go through the list of IMs and find one with this group. */
for (wins = pidgin_conv_windows_get_list(); wins != NULL; wins = wins->next) {
diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c
index a14fffd9b9..d29008639b 100644
--- a/pidgin/gtkdialogs.c
+++ b/pidgin/gtkdialogs.c
@@ -1288,7 +1288,7 @@ pidgin_dialogs_remove_buddy_cb(PurpleBuddy *buddy)
purple_debug_info("blist", "Removing '%s' from buddy list.\n", buddy->name);
/* TODO - Should remove from blist first... then call purple_account_remove_buddy()? */
- purple_account_remove_buddy(buddy->account, buddy, group);
+ purple_account_remove_buddy(account, buddy, group);
purple_blist_remove_buddy(buddy);
g_free(name);
diff --git a/pidgin/gtkft.c b/pidgin/gtkft.c
index e52f6a86b6..dfc91a51a4 100644
--- a/pidgin/gtkft.c
+++ b/pidgin/gtkft.c
@@ -112,13 +112,10 @@ static void
get_xfer_info_strings(PurpleXfer *xfer, char **kbsec, char **time_elapsed,
char **time_remaining)
{
- PidginXferUiData *data;
double kb_sent, kb_rem;
double kbps = 0.0;
time_t elapsed, now;
- data = PIDGINXFER(xfer);
-
if (xfer->end_time != 0)
now = xfer->end_time;
else
@@ -159,7 +156,7 @@ get_xfer_info_strings(PurpleXfer *xfer, char **kbsec, char **time_elapsed,
*time_remaining = g_strdup(_("Finished"));
}
else if (purple_xfer_is_canceled(xfer)) {
- *time_remaining = g_strdup(_("Canceled"));
+ *time_remaining = g_strdup(_("Cancelled"));
}
else if (purple_xfer_get_size(xfer) == 0 || (kb_sent > 0 && kbps == 0)) {
*time_remaining = g_strdup(_("Unknown"));
@@ -995,7 +992,7 @@ pidgin_xfer_dialog_cancel_xfer(PidginXferDialog *dialog,
GTK_ICON_SIZE_MENU, NULL);
if (purple_xfer_is_canceled(xfer))
- status = _("Canceled");
+ status = _("Cancelled");
else
status = _("Failed");
@@ -1015,7 +1012,6 @@ pidgin_xfer_dialog_update_xfer(PidginXferDialog *dialog,
{
PidginXferUiData *data;
char *size_str, *remaining_str;
- GtkTreeSelection *selection;
time_t current_time;
GtkTreeIter iter;
gboolean valid;
@@ -1066,8 +1062,6 @@ pidgin_xfer_dialog_update_xfer(PidginXferDialog *dialog,
g_object_unref(pixbuf);
}
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(xfer_dialog->tree));
-
update_title_progress(dialog);
if (xfer == dialog->selected_xfer)
update_detailed_info(xfer_dialog, xfer);
diff --git a/pidgin/gtkft.h b/pidgin/gtkft.h
index e4703cef55..12f8b380ff 100644
--- a/pidgin/gtkft.h
+++ b/pidgin/gtkft.h
@@ -88,10 +88,10 @@ void pidgin_xfer_dialog_remove_xfer(PidginXferDialog *dialog,
PurpleXfer *xfer);
/**
- * Indicate in a file transfer dialog that a transfer was canceled.
+ * Indicate in a file transfer dialog that a transfer was cancelled.
*
* @param dialog The file transfer dialog.
- * @param xfer The file transfer that was canceled.
+ * @param xfer The file transfer that was cancelled.
*/
void pidgin_xfer_dialog_cancel_xfer(PidginXferDialog *dialog,
PurpleXfer *xfer);
diff --git a/pidgin/gtkidle.c b/pidgin/gtkidle.c
index d95bb4ae9e..f5cf624b97 100644
--- a/pidgin/gtkidle.c
+++ b/pidgin/gtkidle.c
@@ -29,7 +29,7 @@
#else
# ifdef USE_SCREENSAVER
# ifdef _WIN32
-# include "idletrack.h"
+# include "gtkwin32dep.h"
# else
/* We're on X11 and not MacOS X with IOKit. */
# include <X11/Xlib.h>
diff --git a/pidgin/gtkimhtml.c b/pidgin/gtkimhtml.c
index aa0908e5af..1aed5fbbf3 100644
--- a/pidgin/gtkimhtml.c
+++ b/pidgin/gtkimhtml.c
@@ -1476,10 +1476,8 @@ imhtml_url_clicked(GtkIMHtml *imhtml, const char *url)
static void gtk_imhtml_class_init (GtkIMHtmlClass *klass)
{
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
- GtkObjectClass *object_class;
GtkBindingSet *binding_set;
GObjectClass *gobject_class;
- object_class = (GtkObjectClass*) klass;
gobject_class = (GObjectClass*) klass;
parent_class = g_type_class_ref(GTK_TYPE_TEXT_VIEW);
signals[URL_CLICKED] = g_signal_new("url_clicked",
diff --git a/pidgin/gtkimhtmltoolbar.c b/pidgin/gtkimhtmltoolbar.c
index cdebda8416..2b36c9c880 100644
--- a/pidgin/gtkimhtmltoolbar.c
+++ b/pidgin/gtkimhtmltoolbar.c
@@ -1205,9 +1205,7 @@ gtk_imhtmltoolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, GtkIMHtml
/* Boring GTK+ stuff */
static void gtk_imhtmltoolbar_class_init (GtkIMHtmlToolbarClass *class)
{
- GtkObjectClass *object_class;
GObjectClass *gobject_class;
- object_class = (GtkObjectClass*) class;
gobject_class = (GObjectClass*) class;
parent_class = g_type_class_ref(GTK_TYPE_HBOX);
gobject_class->finalize = gtk_imhtmltoolbar_finalize;
diff --git a/pidgin/gtkplugin.c b/pidgin/gtkplugin.c
index 15d70bf317..5d034d78d4 100644
--- a/pidgin/gtkplugin.c
+++ b/pidgin/gtkplugin.c
@@ -800,5 +800,8 @@ void pidgin_plugin_dialog_show()
g_signal_connect (G_OBJECT (sel), "changed", G_CALLBACK (prefs_plugin_sel), NULL);
g_signal_connect(G_OBJECT(plugin_dialog), "response", G_CALLBACK(plugin_dialog_response_cb), sel);
gtk_window_set_default_size(GTK_WINDOW(plugin_dialog), 430, 530);
+
+ pidgin_auto_parent_window(GTK_WINDOW(plugin_dialog));
+
gtk_widget_show_all(plugin_dialog);
}
diff --git a/pidgin/gtkpounce.c b/pidgin/gtkpounce.c
index 1a589d5690..fb468b4f3c 100644
--- a/pidgin/gtkpounce.c
+++ b/pidgin/gtkpounce.c
@@ -194,7 +194,6 @@ add_pounce_to_treeview(GtkListStore *model, PurplePounce *pounce)
{
GtkTreeIter iter;
PurpleAccount *account;
- PurplePounceEvent events;
gboolean recurring;
const char *pouncer;
const char *pouncee;
@@ -202,8 +201,6 @@ add_pounce_to_treeview(GtkListStore *model, PurplePounce *pounce)
account = purple_pounce_get_pouncer(pounce);
- events = purple_pounce_get_events(pounce);
-
pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
pouncer = purple_account_get_username(account);
diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c
index e8da8cf67f..81afcd2cfb 100644
--- a/pidgin/gtkprefs.c
+++ b/pidgin/gtkprefs.c
@@ -1042,11 +1042,40 @@ prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
}
static GtkWidget *
+add_theme_prefs_combo(GtkWidget *vbox,
+ GtkSizeGroup *combo_sg, GtkSizeGroup *label_sg,
+ GtkListStore *theme_store,
+ GCallback combo_box_cb, gpointer combo_box_cb_user_data,
+ const char *label_str, const char *prefs_path,
+ const char *theme_type)
+{
+ GtkWidget *label;
+ GtkWidget *combo_box = NULL;
+ GtkWidget *themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+
+ label = gtk_label_new(label_str);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_size_group_add_widget(label_sg, label);
+ gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
+
+ combo_box = prefs_build_theme_combo_box(theme_store,
+ purple_prefs_get_string(prefs_path),
+ theme_type);
+ g_signal_connect(G_OBJECT(combo_box), "changed",
+ (GCallback)combo_box_cb, combo_box_cb_user_data);
+ gtk_size_group_add_widget(combo_sg, combo_box);
+ gtk_box_pack_start(GTK_BOX(themesel_hbox), combo_box, TRUE, TRUE, 0);
+
+ gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+
+ return combo_box;
+}
+
+static GtkWidget *
theme_page(void)
{
- GtkWidget *ret, *vbox;
GtkWidget *label;
- GtkWidget *themesel_hbox;
+ GtkWidget *ret, *vbox;
GtkSizeGroup *label_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
GtkSizeGroup *combo_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
@@ -1067,76 +1096,28 @@ theme_page(void)
gtk_widget_show(label);
/* Buddy List Themes */
- themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-
- label = gtk_label_new(_("Buddy List Theme:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_size_group_add_widget(label_sg, label);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
-
- prefs_blist_themes_combo_box = prefs_build_theme_combo_box(prefs_blist_themes,
- purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"),
- "blist");
- g_signal_connect(G_OBJECT(prefs_blist_themes_combo_box), "changed",
- (GCallback)prefs_set_blist_theme_cb, NULL);
- gtk_size_group_add_widget(combo_sg, prefs_blist_themes_combo_box);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_blist_themes_combo_box, TRUE, TRUE, 0);
-
- gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+ prefs_blist_themes_combo_box = add_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_blist_themes,
+ (GCallback)prefs_set_blist_theme_cb, NULL,
+ _("Buddy List Theme:"), PIDGIN_PREFS_ROOT "/blist/theme", "blist");
/* Status Icon Themes */
- themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-
- label = gtk_label_new(_("Status Icon Theme:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_size_group_add_widget(label_sg, label);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
-
- prefs_status_themes_combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes,
- purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"),
- "icon");
- g_signal_connect(G_OBJECT(prefs_status_themes_combo_box), "changed",
- (GCallback)prefs_set_status_icon_theme_cb, NULL);
- gtk_size_group_add_widget(combo_sg, prefs_status_themes_combo_box);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_status_themes_combo_box, TRUE, TRUE, 0);
-
- gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+ prefs_status_themes_combo_box = add_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_status_icon_themes,
+ (GCallback)prefs_set_status_icon_theme_cb, NULL,
+ _("Status Icon Theme:"), PIDGIN_PREFS_ROOT "/status/icon-theme", "icon");
/* Sound Themes */
- themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-
- label = gtk_label_new(_("Sound Theme:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_size_group_add_widget(label_sg, label);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
-
- prefs_sound_themes_combo_box = prefs_build_theme_combo_box(prefs_sound_themes,
- purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"),
- "sound");
- g_signal_connect(G_OBJECT(prefs_sound_themes_combo_box), "changed",
- (GCallback)prefs_set_sound_theme_cb, NULL);
- gtk_size_group_add_widget(combo_sg, prefs_sound_themes_combo_box);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_sound_themes_combo_box, TRUE, TRUE, 0);
-
- gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+ prefs_sound_themes_combo_box = add_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_sound_themes,
+ (GCallback)prefs_set_sound_theme_cb, NULL,
+ _("Sound Theme:"), PIDGIN_PREFS_ROOT "/sound/theme", "sound");
/* Smiley Themes */
- themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-
- label = gtk_label_new(_("Smiley Theme:"));
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_size_group_add_widget(label_sg, label);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
-
- prefs_smiley_themes_combo_box = prefs_build_theme_combo_box(prefs_smiley_themes,
- purple_prefs_get_string(PIDGIN_PREFS_ROOT "/smileys/theme"),
- "smiley");
- g_signal_connect(G_OBJECT(prefs_smiley_themes_combo_box), "changed",
- (GCallback)prefs_set_smiley_theme_cb, NULL);
- gtk_size_group_add_widget(combo_sg, prefs_smiley_themes_combo_box);
- gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_smiley_themes_combo_box, TRUE, TRUE, 0);
-
- gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
+ prefs_smiley_themes_combo_box = add_theme_prefs_combo(
+ vbox, combo_sg, label_sg, prefs_smiley_themes,
+ (GCallback)prefs_set_smiley_theme_cb, NULL,
+ _("Smiley Theme:"), PIDGIN_PREFS_ROOT "/smileys/theme", "smiley");
/* Custom sort so "none" theme is at top of list */
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(prefs_smiley_themes),
@@ -1809,9 +1790,10 @@ network_page(void)
hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_TURN server:"),
sg, entry, TRUE, NULL);
-
- pidgin_prefs_labeled_spin_button(hbox, _("_Port:"),
+
+ pidgin_prefs_labeled_spin_button(hbox, _("_UDP Port:"),
"/purple/network/turn_port", 0, 65535, NULL);
+
hbox = pidgin_prefs_labeled_entry(vbox, _("Use_rname:"),
"/purple/network/turn_username", sg);
pidgin_prefs_labeled_password(hbox, _("Pass_word:"),
diff --git a/pidgin/gtkroomlist.c b/pidgin/gtkroomlist.c
index f81dbfa460..4ef648c0d7 100644
--- a/pidgin/gtkroomlist.c
+++ b/pidgin/gtkroomlist.c
@@ -362,8 +362,6 @@ pidgin_roomlist_paint_tooltip(GtkWidget *widget, gpointer user_data)
style = grl->tipwindow->style;
- max_text_width = 0;
-
max_text_width = MAX(grl->tip_width, grl->tip_name_width);
max_width = TOOLTIP_BORDER + SMALL_SPACE + max_text_width + TOOLTIP_BORDER;
diff --git a/pidgin/gtksession.c b/pidgin/gtksession.c
index c9bee6f266..a972865c76 100644
--- a/pidgin/gtksession.c
+++ b/pidgin/gtksession.c
@@ -166,7 +166,7 @@ static gchar **session_make_command(gchar *client_id, gchar *config_dir) {
ret[j++] = g_strdup("--display");
ret[j++] = g_strdup((gchar *)gdk_display_get_name(gdk_display_get_default()));
- ret[j++] = NULL;
+ ret[j] = NULL;
return ret;
}
diff --git a/pidgin/gtksmiley.c b/pidgin/gtksmiley.c
index 06a041d8a1..e59c082fd7 100644
--- a/pidgin/gtksmiley.c
+++ b/pidgin/gtksmiley.c
@@ -520,9 +520,6 @@ static void delete_foreach(GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data)
{
PurpleSmiley *smiley = NULL;
- SmileyManager *dialog;
-
- dialog = (SmileyManager*)data;
gtk_tree_model_get(model, iter,
SMILEY, &smiley,
diff --git a/pidgin/gtksourceundomanager.c b/pidgin/gtksourceundomanager.c
index 9cb177ed80..d2980ce109 100644
--- a/pidgin/gtksourceundomanager.c
+++ b/pidgin/gtksourceundomanager.c
@@ -963,7 +963,7 @@ gtk_source_undo_manager_check_list_size (GtkSourceUndoManager *um)
* the stack with a new undo action. So when we undo for example
* typing, we can undo the whole word and not each letter by itself.
*
- * Return Value: %TRUE is merge was successful, %FALSE otherwise.
+ * Return Value: %TRUE is merge was successful, %FALSE otherwise.
**/
static gboolean
gtk_source_undo_manager_merge_action (GtkSourceUndoManager *um,
diff --git a/pidgin/gtkstatusbox.c b/pidgin/gtkstatusbox.c
index 38b62b926c..c315916cb3 100644
--- a/pidgin/gtkstatusbox.c
+++ b/pidgin/gtkstatusbox.c
@@ -657,7 +657,6 @@ pidgin_status_box_class_init (PidginStatusBoxClass *klass)
static void
pidgin_status_box_refresh(PidginStatusBox *status_box)
{
- GtkIconSize icon_size;
GtkStyle *style;
char aa_color[8];
PurpleSavedStatus *saved_status;
@@ -668,8 +667,6 @@ pidgin_status_box_refresh(PidginStatusBox *status_box)
gboolean account_status = FALSE;
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);
-
style = gtk_widget_get_style(GTK_WIDGET(status_box));
snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x",
style->text_aa[GTK_STATE_NORMAL].red >> 8,
@@ -969,11 +966,7 @@ add_popular_statuses(PidginStatusBox *statusbox)
PurpleSavedStatus *saved = cur->data;
const gchar *message;
gchar *stripped = NULL;
- PurpleStatusPrimitive prim;
- PidginStatusBoxItemType type = PIDGIN_STATUS_BOX_TYPE_POPULAR;
-
- /* Get an appropriate status icon */
- prim = purple_savedstatus_get_type(saved);
+ PidginStatusBoxItemType type;
if (purple_savedstatus_is_transient(saved))
{
@@ -982,16 +975,18 @@ add_popular_statuses(PidginStatusBox *statusbox)
* API returns the message when purple_savedstatus_get_title() is
* called, so we don't need to get the message a second time.
*/
+ type = PIDGIN_STATUS_BOX_TYPE_POPULAR;
}
else
{
+ type = PIDGIN_STATUS_BOX_TYPE_SAVED_POPULAR;
+
message = purple_savedstatus_get_message(saved);
if (message != NULL)
{
stripped = purple_markup_strip_html(message);
purple_util_chrreplace(stripped, '\n', ' ');
}
- type = PIDGIN_STATUS_BOX_TYPE_SAVED_POPULAR;
}
pidgin_status_box_add(statusbox, type,
@@ -1074,17 +1069,13 @@ add_account_statuses(PidginStatusBox *status_box, PurpleAccount *account)
PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, NULL,
purple_status_type_get_name(status_type),
NULL,
- GINT_TO_POINTER(purple_status_type_get_primitive(status_type)));
+ GINT_TO_POINTER(prim));
}
}
static void
pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed)
{
- GtkIconSize icon_size;
-
- icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL);
-
/* Unset the model while clearing it */
gtk_tree_view_set_model(GTK_TREE_VIEW(status_box->tree_view), NULL);
gtk_list_store_clear(status_box->dropdown_store);
diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c
index 5a5e689946..34b3a79d1b 100644
--- a/pidgin/gtkutils.c
+++ b/pidgin/gtkutils.c
@@ -680,7 +680,6 @@ static AopMenu *
create_protocols_menu(const char *default_proto_id)
{
AopMenu *aop_menu = NULL;
- PurplePluginProtocolInfo *prpl_info;
PurplePlugin *plugin;
GdkPixbuf *pixbuf = NULL;
GtkSizeGroup *sg;
@@ -702,7 +701,6 @@ create_protocols_menu(const char *default_proto_id)
p = p->next, i++) {
plugin = (PurplePlugin *)p->data;
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
@@ -784,8 +782,6 @@ create_account_menu(PurpleAccount *default_account,
sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
for (p = list, i = 0; p != NULL; p = p->next, i++) {
- PurplePlugin *plugin;
-
if (show_all)
account = (PurpleAccount *)p->data;
else {
@@ -799,8 +795,6 @@ create_account_menu(PurpleAccount *default_account,
continue;
}
- plugin = purple_find_prpl(purple_account_get_protocol_id(account));
-
pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
if (pixbuf) {
@@ -1036,7 +1030,7 @@ pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
char *username = NULL;
char *alias = NULL;
char *str;
- char *c, *s;
+ char *s;
gboolean valid;
g_return_val_if_fail(msg != NULL, FALSE);
@@ -1078,7 +1072,7 @@ pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
if (*s == '\r') *s++ = '\0';
if (*s == '\n') *s++ = '\0';
- if ((c = strchr(key, ':')) != NULL)
+ if (strchr(key, ':') != NULL)
{
if (!g_ascii_strcasecmp(key, "X-IM-Username:"))
username = g_strdup(value);
@@ -2611,18 +2605,11 @@ old_mini_dialog_destroy_cb(GtkWidget *dialog,
}
}
-GtkWidget *
-pidgin_make_mini_dialog(PurpleConnection *gc,
- const char *icon_name,
- const char *primary,
- const char *secondary,
- void *user_data,
- ...)
+static void
+mini_dialog_init(PidginMiniDialog *mini_dialog, PurpleConnection *gc, void *user_data, va_list args)
{
- PidginMiniDialog *mini_dialog;
const char *button_text;
GList *cb_datas = NULL;
- va_list args;
static gboolean first_call = TRUE;
if (first_call) {
@@ -2632,12 +2619,10 @@ pidgin_make_mini_dialog(PurpleConnection *gc,
PURPLE_CALLBACK(connection_signed_off_cb), NULL);
}
- mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name);
g_object_set_data(G_OBJECT(mini_dialog), "gc" ,gc);
g_signal_connect(G_OBJECT(mini_dialog), "destroy",
G_CALLBACK(alert_killed_cb), NULL);
- va_start(args, user_data);
while ((button_text = va_arg(args, char*))) {
struct _old_button_clicked_cb_data *data = NULL;
PidginMiniDialogCallback wrapper_cb = NULL;
@@ -2654,12 +2639,40 @@ pidgin_make_mini_dialog(PurpleConnection *gc,
wrapper_cb, data);
cb_datas = g_list_append(cb_datas, data);
}
- va_end(args);
g_signal_connect(G_OBJECT(mini_dialog), "destroy",
G_CALLBACK(old_mini_dialog_destroy_cb), cb_datas);
+}
+#define INIT_AND_RETURN_MINI_DIALOG(mini_dialog) \
+ va_list args; \
+ va_start(args, user_data); \
+ mini_dialog_init(mini_dialog, gc, user_data, args); \
+ va_end(args); \
return GTK_WIDGET(mini_dialog);
+
+GtkWidget *
+pidgin_make_mini_dialog(PurpleConnection *gc,
+ const char *icon_name,
+ const char *primary,
+ const char *secondary,
+ void *user_data,
+ ...)
+{
+ PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name);
+ INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
+}
+
+GtkWidget *
+pidgin_make_mini_dialog_with_custom_icon(PurpleConnection *gc,
+ GdkPixbuf *custom_icon,
+ const char *primary,
+ const char *secondary,
+ void *user_data,
+ ...)
+{
+ PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new_with_custom_icon(primary, secondary, custom_icon);
+ INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
}
/*
@@ -2771,79 +2784,78 @@ gboolean pidgin_tree_view_search_equal_func(GtkTreeModel *model, gint column,
gboolean pidgin_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf) {
- int width, height, rowstride, i;
- unsigned char *pixels;
- unsigned char *row;
+ int height, rowstride, i;
+ unsigned char *pixels;
+ unsigned char *row;
- if (!gdk_pixbuf_get_has_alpha(pixbuf))
- return TRUE;
+ if (!gdk_pixbuf_get_has_alpha(pixbuf))
+ return TRUE;
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- pixels = gdk_pixbuf_get_pixels (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
- row = pixels;
- for (i = 3; i < rowstride; i+=4) {
- if (row[i] < 0xfe)
- return FALSE;
- }
+ row = pixels;
+ for (i = 3; i < rowstride; i+=4) {
+ if (row[i] < 0xfe)
+ return FALSE;
+ }
- for (i = 1; i < height - 1; i++) {
- row = pixels + (i*rowstride);
- if (row[3] < 0xfe || row[rowstride-1] < 0xfe) {
- return FALSE;
- }
- }
+ for (i = 1; i < height - 1; i++) {
+ row = pixels + (i * rowstride);
+ if (row[3] < 0xfe || row[rowstride - 1] < 0xfe) {
+ return FALSE;
+ }
+ }
- row = pixels + ((height-1) * rowstride);
- for (i = 3; i < rowstride; i+=4) {
- if (row[i] < 0xfe)
- return FALSE;
- }
+ row = pixels + ((height - 1) * rowstride);
+ for (i = 3; i < rowstride; i += 4) {
+ if (row[i] < 0xfe)
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) {
int width, height, rowstride;
- guchar *pixels;
- if (!gdk_pixbuf_get_has_alpha(pixbuf))
- return;
- width = gdk_pixbuf_get_width(pixbuf);
- height = gdk_pixbuf_get_height(pixbuf);
- rowstride = gdk_pixbuf_get_rowstride(pixbuf);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- if (width < 6 || height < 6)
- return;
- /* Top left */
- pixels[3] = 0;
- pixels[7] = 0x80;
- pixels[11] = 0xC0;
- pixels[rowstride + 3] = 0x80;
- pixels[rowstride * 2 + 3] = 0xC0;
-
- /* Top right */
- pixels[width * 4 - 1] = 0;
- pixels[width * 4 - 5] = 0x80;
- pixels[width * 4 - 9] = 0xC0;
- pixels[rowstride + (width * 4) - 1] = 0x80;
- pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
-
- /* Bottom left */
- pixels[(height - 1) * rowstride + 3] = 0;
- pixels[(height - 1) * rowstride + 7] = 0x80;
- pixels[(height - 1) * rowstride + 11] = 0xC0;
- pixels[(height - 2) * rowstride + 3] = 0x80;
- pixels[(height - 3) * rowstride + 3] = 0xC0;
-
- /* Bottom right */
- pixels[height * rowstride - 1] = 0;
- pixels[(height - 1) * rowstride - 1] = 0x80;
- pixels[(height - 2) * rowstride - 1] = 0xC0;
- pixels[height * rowstride - 5] = 0x80;
- pixels[height * rowstride - 9] = 0xC0;
+ guchar *pixels;
+ if (!gdk_pixbuf_get_has_alpha(pixbuf))
+ return;
+ width = gdk_pixbuf_get_width(pixbuf);
+ height = gdk_pixbuf_get_height(pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+ pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+ if (width < 6 || height < 6)
+ return;
+ /* Top left */
+ pixels[3] = 0;
+ pixels[7] = 0x80;
+ pixels[11] = 0xC0;
+ pixels[rowstride + 3] = 0x80;
+ pixels[rowstride * 2 + 3] = 0xC0;
+
+ /* Top right */
+ pixels[width * 4 - 1] = 0;
+ pixels[width * 4 - 5] = 0x80;
+ pixels[width * 4 - 9] = 0xC0;
+ pixels[rowstride + (width * 4) - 1] = 0x80;
+ pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
+
+ /* Bottom left */
+ pixels[(height - 1) * rowstride + 3] = 0;
+ pixels[(height - 1) * rowstride + 7] = 0x80;
+ pixels[(height - 1) * rowstride + 11] = 0xC0;
+ pixels[(height - 2) * rowstride + 3] = 0x80;
+ pixels[(height - 3) * rowstride + 3] = 0xC0;
+
+ /* Bottom right */
+ pixels[height * rowstride - 1] = 0;
+ pixels[(height - 1) * rowstride - 1] = 0x80;
+ pixels[(height - 2) * rowstride - 1] = 0xC0;
+ pixels[height * rowstride - 5] = 0x80;
+ pixels[height * rowstride - 9] = 0xC0;
}
const char *pidgin_get_dim_grey_string(GtkWidget *widget) {
diff --git a/pidgin/gtkutils.h b/pidgin/gtkutils.h
index 95d05531cc..d7e0e8b211 100644
--- a/pidgin/gtkutils.h
+++ b/pidgin/gtkutils.h
@@ -718,6 +718,17 @@ GtkWidget *pidgin_make_mini_dialog(PurpleConnection *handle,
void *user_data, ...) G_GNUC_NULL_TERMINATED;
/**
+ * Does exactly what pidgin_make_mini_dialog() does, except you can specify
+ * a custom icon for the dialog.
+ */
+GtkWidget *pidgin_make_mini_dialog_with_custom_icon(PurpleConnection *gc,
+ GdkPixbuf *custom_icon,
+ const char *primary,
+ const char *secondary,
+ void *user_data,
+ ...) G_GNUC_NULL_TERMINATED;
+
+/**
* This is a callback function to be used for Ctrl+F searching in treeviews.
* Sample Use:
* gtk_tree_view_set_search_equal_func(treeview,
diff --git a/pidgin/minidialog.c b/pidgin/minidialog.c
index 6599123ee3..75c45d5f31 100644
--- a/pidgin/minidialog.c
+++ b/pidgin/minidialog.c
@@ -75,6 +75,7 @@ enum
PROP_TITLE = 1,
PROP_DESCRIPTION,
PROP_ICON_NAME,
+ PROP_CUSTOM_ICON,
LAST_PROPERTY
} HazeConnectionProperties;
@@ -93,17 +94,32 @@ typedef struct _PidginMiniDialogPrivate
#define PIDGIN_MINI_DIALOG_GET_PRIVATE(dialog) \
((PidginMiniDialogPrivate *) ((dialog)->priv))
+static PidginMiniDialog *
+mini_dialog_new(const gchar *title, const gchar *description)
+{
+ return g_object_new(PIDGIN_TYPE_MINI_DIALOG,
+ "title", title,
+ "description", description,
+ NULL);
+}
+
PidginMiniDialog *
pidgin_mini_dialog_new(const gchar *title,
const gchar *description,
const gchar *icon_name)
{
- PidginMiniDialog *mini_dialog = g_object_new(PIDGIN_TYPE_MINI_DIALOG,
- "title", title,
- "description", description,
- "icon-name", icon_name,
- NULL);
+ PidginMiniDialog *mini_dialog = mini_dialog_new(title, description);
+ pidgin_mini_dialog_set_icon_name(mini_dialog, icon_name);
+ return mini_dialog;
+}
+PidginMiniDialog *
+pidgin_mini_dialog_new_with_custom_icon(const gchar *title,
+ const gchar *description,
+ GdkPixbuf *custom_icon)
+{
+ PidginMiniDialog *mini_dialog = mini_dialog_new(title, description);
+ pidgin_mini_dialog_set_custom_icon(mini_dialog, custom_icon);
return mini_dialog;
}
@@ -125,7 +141,13 @@ void
pidgin_mini_dialog_set_icon_name(PidginMiniDialog *mini_dialog,
const char *icon_name)
{
- g_object_set(G_OBJECT(mini_dialog), "icon_name", icon_name, NULL);
+ g_object_set(G_OBJECT(mini_dialog), "icon-name", icon_name, NULL);
+}
+
+void
+pidgin_mini_dialog_set_custom_icon(PidginMiniDialog *mini_dialog, GdkPixbuf *custom_icon)
+{
+ g_object_set(G_OBJECT(mini_dialog), "custom-icon", custom_icon, NULL);
}
struct _mini_dialog_button_clicked_cb_data
@@ -233,6 +255,9 @@ pidgin_mini_dialog_get_property(GObject *object,
g_value_set_string(value, icon_name);
break;
}
+ case PROP_CUSTOM_ICON:
+ g_value_set_object(value, gtk_image_get_pixbuf(priv->icon));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -305,6 +330,8 @@ pidgin_mini_dialog_set_property(GObject *object,
gtk_image_set_from_stock(priv->icon, g_value_get_string(value),
gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
break;
+ case PROP_CUSTOM_ICON:
+ gtk_image_set_from_pixbuf(priv->icon, g_value_get_object(value));
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -355,6 +382,13 @@ pidgin_mini_dialog_class_init(PidginMiniDialogClass *klass)
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_ICON_NAME, param_spec);
+
+ param_spec = g_param_spec_object("custom-icon", "custom-icon",
+ "Pixbuf to use as the dialog's icon",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_CUSTOM_ICON, param_spec);
}
/* 16 is the width of the icon, due to PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL */
diff --git a/pidgin/minidialog.h b/pidgin/minidialog.h
index 386084c8e8..ddbfc8fd6a 100644
--- a/pidgin/minidialog.h
+++ b/pidgin/minidialog.h
@@ -73,6 +73,8 @@ G_BEGIN_DECLS
* <dd>The Gtk stock id of an icon for the dialog, or @c NULL for no icon.
* @see pidginstock.h
* </dd>
+ * <dt><tt>"custom-icon"</tt> (<tt>GdkPixbuf *</tt>)</dt>
+ * <dd>The custom icon to use instead of a stock one (overrides the "icon-name" property).</dd>
* </dl>
*/
typedef struct {
@@ -108,13 +110,20 @@ typedef void (*PidginMiniDialogCallback)(PidginMiniDialog *mini_dialog,
/** Get the GType of #PidginMiniDialog. */
GType pidgin_mini_dialog_get_type (void);
-/** Creates a new #PidginMiniDialog. This is a shortcut for creating the dialog
+/** Creates a new #PidginMiniDialog with a stock icon. This is a shortcut for creating the dialog
* with @c g_object_new() then setting each property yourself.
* @return a new #PidginMiniDialog.
*/
PidginMiniDialog *pidgin_mini_dialog_new(const gchar *title,
const gchar *description, const gchar *icon_name);
+/** Creates a new #PidginMiniDialog with a custom icon. This is a shortcut for creating the dialog
+ * with @c g_object_new() then setting each property yourself.
+ * @return a new #PidginMiniDialog.
+ */
+PidginMiniDialog *pidgin_mini_dialog_new_with_custom_icon(const gchar *title,
+ const gchar *description, GdkPixbuf *custom_icon);
+
/** Shortcut for setting a mini-dialog's title via GObject properties.
* @param mini_dialog a mini-dialog
* @param title the new title for @a mini_dialog
@@ -137,6 +146,13 @@ void pidgin_mini_dialog_set_description(PidginMiniDialog *mini_dialog,
void pidgin_mini_dialog_set_icon_name(PidginMiniDialog *mini_dialog,
const char *icon_name);
+/** Shortcut for setting a mini-dialog's custom icon via GObject properties.
+ * @param mini_dialog a mini-dialog
+ * @param icon_name the pixbuf to use as a custom icon
+ */
+void pidgin_mini_dialog_set_custom_icon(PidginMiniDialog *mini_dialog,
+ GdkPixbuf *custom_icon);
+
/** Adds a new button to a mini-dialog, and attaches the supplied callback to
* its <tt>clicked</tt> signal. After a button is clicked, the dialog is
* destroyed.
diff --git a/pidgin/pidginstock.h b/pidgin/pidginstock.h
index 63a8714130..83185aee83 100644
--- a/pidgin/pidginstock.h
+++ b/pidgin/pidginstock.h
@@ -44,7 +44,7 @@
#define PIDGIN_STOCK_DOWNLOAD "pidgin-download"
#define PIDGIN_STOCK_EDIT "pidgin-edit"
#define PIDGIN_STOCK_FGCOLOR "pidgin-fgcolor"
-#define PIDGIN_STOCK_FILE_CANCELED "pidgin-file-canceled"
+#define PIDGIN_STOCK_FILE_CANCELED "pidgin-file-cancelled"
#define PIDGIN_STOCK_FILE_DONE "pidgin-file-done"
#define PIDGIN_STOCK_IGNORE "pidgin-ignore"
#define PIDGIN_STOCK_INFO "pidgin-info"
diff --git a/pidgin/pixmaps/emotes/default/24/default.theme.in b/pidgin/pixmaps/emotes/default/24/default.theme.in
index af6de4bd9b..e7c3714783 100644
--- a/pidgin/pixmaps/emotes/default/24/default.theme.in
+++ b/pidgin/pixmaps/emotes/default/24/default.theme.in
@@ -419,6 +419,98 @@ male-fighter2.png o=> O=>
female-fighter.png o-+ O-+
yin-yang.png (%)
+# Following Yahoo! Messenger 8.1
+[Yahoo JAPAN]
+happy.png :) :-)
+question.png :-/ :-\\
+shocked.png :-O :O :-o :o
+devil.png >:)
+angel.png O:-) o:-) 0:-)
+sick.png :-&
+sleepy.png (:|
+hypnotized.png @-)
+on-the-phone.png :)]
+sad.png :( :-(
+amorous.png :x :-x :X :-X
+angry.png X-( x-( X( x(
+crying.png :((
+glasses-nerdy.png :-B :-b
+quiet.png :-$
+drool.png =P~ =p~
+lying.png :^O :^o
+call-me.png :-c
+wink.png ;) ;-)
+embarrassed.png :">
+mean.png :-> :>
+laugh.png :)) :-))
+bye.png =;
+arrogant.png [-(
+thinking.png :-?
+waiting.png :-w :-W
+at-wits-end.png ~x( ~X(
+excited.png :D :-D :d :-d
+tongue.png :-P :P :-p :p
+glasses-cool.png B-) b-)
+neutral.png :| :-|
+sleeping.png I-) i-) |-)
+clown.png :o) :O)
+doh.png #-o #-O
+weep.png :-<
+go-away.png :-h
+lashes.png ;;)
+kiss.png :-* :*
+confused.png :-S :-s
+sarcastic.png /:)
+eyeroll.png 8-|
+silly.png 8-}
+clap.png =D> =d>
+mad-tongue.png >:P >:p
+time-out.png :-t :-T
+hug-left.png >:D< >:d<
+love-over.png =((
+hot.png #:-S #:-s
+rotfl.png =)) :-j :-J
+loser.png L-) l-)
+party.png <:-P <:-p
+nervous.png :-SS :-Ss :-sS :-ss
+cowboy.png <):)
+desire.png 8->
+! skywalker.png C:-) c:-) C:) c:)
+! monkey.png :-(|) :(|)
+
+# Hidden Yahoo emotes
+alien.png =:) >-)
+beat-up.png b-( B-(
+chicken.png ~:>
+coffee.png ~o) ~O)
+cow.png 3:-O 3:-o
+dance.png \\:D/ \\:d/
+rose.png @};-
+dont-know.png :-L :-l
+skeleton.png 8-X 8-x
+lamp.png *-:)
+monkey.png :(|)
+coins.png $-)
+peace.png :)>-
+pig.png :@)
+pray.png [-o< [-O<
+pumpkin.png (~~)
+shame.png [-X [-x
+flag.png **==
+clover.png %%-
+musical-note.png :-"
+giggle.png ;))
+worship.png ^:)^
+star.png (*)
+waving.png >:/
+talktohand.png :-@
+
+# Only available after activating the Yahoo! Fighter IMVironment
+male-fighter1.png o-> O->
+male-fighter2.png o=> O=>
+female-fighter.png o-+ O-+
+yin-yang.png (%)
+
# Following MySpaceIM Beta 1.0.697.0
[MySpaceIM]
@@ -428,7 +520,7 @@ confused.png :Z
glasses-nerdy.png B)
bulgy-eyes.png %)
freaked-out.png :E
-smile.png :) :-)
+happy.png :) :-)
amorous.png :X
laugh.png :))
mohawk.png -:
diff --git a/pidgin/pixmaps/emotes/small/16/Makefile.am b/pidgin/pixmaps/emotes/small/16/Makefile.am
index cfc18e4c30..af06ecce1b 100644
--- a/pidgin/pixmaps/emotes/small/16/Makefile.am
+++ b/pidgin/pixmaps/emotes/small/16/Makefile.am
@@ -34,7 +34,6 @@ SMILEYS = \
confused.png \
console.png \
cold.png \
- cool.png \
cross.png \
crying.png \
devil.png \
@@ -44,7 +43,6 @@ SMILEYS = \
excruciating.png \
eyeroll.png \
girl.png \
- grin.png \
happy.png \
hug-left.png \
hug-right.png \
@@ -77,6 +75,7 @@ SMILEYS = \
star.png \
stressed.png \
thinking.png \
+ thunder.png \
tongue.png \
tv.png \
uhm-yeah.png \
diff --git a/pidgin/pixmaps/emotes/small/16/cool.png b/pidgin/pixmaps/emotes/small/16/cool.png
deleted file mode 100644
index ef1c870b2a..0000000000
--- a/pidgin/pixmaps/emotes/small/16/cool.png
+++ /dev/null
Binary files differ
diff --git a/pidgin/pixmaps/emotes/small/16/glasses-cool.png b/pidgin/pixmaps/emotes/small/16/glasses-cool.png
new file mode 100644
index 0000000000..d6207f3de4
--- /dev/null
+++ b/pidgin/pixmaps/emotes/small/16/glasses-cool.png
Binary files differ
diff --git a/pidgin/pixmaps/emotes/small/16/grin.png b/pidgin/pixmaps/emotes/small/16/grin.png
deleted file mode 100644
index 76251d6c9e..0000000000
--- a/pidgin/pixmaps/emotes/small/16/grin.png
+++ /dev/null
Binary files differ
diff --git a/pidgin/pixmaps/emotes/small/16/small.theme.in b/pidgin/pixmaps/emotes/small/16/small.theme.in
index 9421ebf161..cba32b4378 100644
--- a/pidgin/pixmaps/emotes/small/16/small.theme.in
+++ b/pidgin/pixmaps/emotes/small/16/small.theme.in
@@ -1,5 +1,5 @@
_Name=Small
-_Description=Smaller versions of the default smilies
+_Description=Smaller versions of the default smileys
Icon=wink.png
Author=Hylke Bons
@@ -13,10 +13,12 @@ wink.png ;-) ;)
tongue.png :P :p :-P :-p
shocked.png =-O =-o
kiss.png :-*
+glasses-cool.png 8-)
embarrassed.png :-[
crying.png :'( :'-(
thinking.png :-/ :-\\
angel.png O:-) o:-)
+shut-mouth.png :-X
[XMPP]
@@ -29,18 +31,23 @@ wink.png ;-) ;) ;^)
tongue.png :P :p :-P :-p
shocked.png =-O =-o :-O :-o
kiss.png :kiss: :-*
+glasses-cool.png 8-) B-)
embarrassed.png :-[
crying.png :'-( :'(
thinking.png :-/ :-\\
angel.png O:-) o:-)
+shut-mouth.png :-X
# Following XEP-0038 + GTalk
angry.png >:-( >:( X-( x-(
+rose.png @->-- :rose:
phone.png :telephone:
+lamp.png :jabber:
in_love.png :heart: :love: <3
musical-note.png :music:
beer.png :beer:
coffee.png :coffee:
+star.png :star:
# Others
neutral.png :| :-|
@@ -61,6 +68,8 @@ embarrassed.png :-[
angel.png O:-)
thinking.png :-\\ :-/
crying.png :'(
+shut-mouth.png :-X
+glasses-cool.png 8-)
# Following Windows Live Messenger 8.1
@@ -70,6 +79,7 @@ excited.png :D :d :-D :-d
wink.png ;) ;-)
shocked.png :-O :-o :O :o
tongue.png :-P :P :-p :p
+glasses-cool.png (H) (h)
angry.png :@ :-@
embarrassed.png :$ :-$
confused.png :S :s :-S :-s
@@ -79,21 +89,28 @@ neutral.png :| :-|
devil.png (6)
angel.png (A) (a)
in_love.png (L) (l)
+star.png (*)
musical-note.png (8)
+rose.png (F) (f)
kiss.png (K) (k)
camera.png (P) (p)
+lamp.png (I) (i)
coffee.png (C) (c)
phone.png (T) (t)
hug-left.png ({)
hug-right.png (})
beer.png (B) (b)
+boy.png (Z) (z)
+girl.png (X) (x)
sarcastic.png ^o)
sick.png +o(
plate.png (pl)
mobile.png (mp)
dont-know.png :^)
thinking.png *-)
+thunder.png (li)
party.png <:o)
+eyeroll.png 8-)
sleepy.png |-)
# Hidden MSN emotes
@@ -106,28 +123,37 @@ console.png (xx) (XX)
shocked.png /:O /jy /surprised
party.png /8-) /dy /revel
crying.png /:< /ll /cry
+shut-mouth.png /:X /bz /shut_mouth
sleeping.png /:Z /shui /sleep
embarrassed.png /:-| /gg /embarassed
+pissed-off.png /:@ /fn /pissed_off
excited.png /:D /cy /toothy_smile
happy.png /:) /wx /small_smile
sad.png /:( /ng /sad
+glasses-cool.png /:+ /kuk /cool
sick.png /:T /tu /vomit
sleepy.png /|-) /kun /sleepy
hot.png /:L /sweat
question.png /? /yiw /question
+excruciating.png /:8 /zhem /excrutiating
afraid.png /shake /fad /shake
amorous.png /love /aiq /love
search.png /find /zhao /search
hug-left.png /hug /yb /hug
+lamp.png /! /dp /lightbulb
+thunder.png /li /shd /lightning
musical-note.png /music /yy /music
coffee.png /coffee /kf /coffee
hungry.png /eat /fan /eat
+rose.png /rose /mg /rose
kiss.png /kiss /wen /kiss
in_love.png /heart /xin /heart
meeting.png /meeting /hy /meeting
phone.png /phone /dh /phone
tv.png /TV /ds /TV
angry.png /<O> /oh /angry
+girl.png /<00> /nv /woman
+boy.png /<11> /nan /man
# Following ICQ 6.0
@@ -146,9 +172,12 @@ kiss.png :-{} :-*
embarrassed.png :-[
devil.png ]:->
angel.png O:-)
+rose.png @}->--
+shut-mouth.png :-X :X :-x :x
thinking.png :-\\ :-/
beer.png *DRINK*
excited.png :-D :D
+glasses-cool.png 8-)
amorous.png *IN\ LOVE*
@@ -165,17 +194,21 @@ sad.png :( :-(
amorous.png :x :-x :X :-X
angry.png X-( x-( X( x(
crying.png :((
+drool.png =P~ =p~
+lying.png :^O :^o
wink.png ;) ;-)
embarrassed.png :">
mean.png :-> :>
thinking.png :-?
excited.png :D :-D :d :-d
tongue.png :-P :P :-p :p
+glasses-cool.png B-) b-)
neutral.png :| :-|
sleeping.png I-) i-) |-)
kiss.png :-* :*
confused.png :-S :-s
sarcastic.png /:)
+eyeroll.png 8-|
hug-left.png >:D< >:d<
hot.png #:-S #:-s
party.png <:-P <:-p
@@ -183,38 +216,48 @@ nervous.png :-SS :-Ss :-sS :-ss
# Hidden Yahoo emotes
coffee.png ~o) ~O)
+rose.png @};-
dont-know.png :-L :-l
+lamp.png *-:)
shame.png [-X [-x
musical-note.png :-"
+star.png (*)
# Following Yahoo! Messenger 8.1
[Yahoo JAPAN]
-smile.png :) :-)
+happy.png :) :-)
question.png :-/ :-\\
-shock.png :-O :O :-o :o
+shocked.png :-O :O :-o :o
devil.png >:)
angel.png O:-) o:-) 0:-)
sick.png :-&
-yawn.png (:|
+sleepy.png (:|
sad.png :( :-(
+amorous.png :x :-x :X :-X
angry.png X-( x-( X( x(
crying.png :((
wink.png ;) ;-)
thinking.png :-?
-smile-big.png :D :-D :d :-d
+excited.png :D :-D :d :-d
tongue.png :-P :P :-p :p
+glasses-cool.png B-) b-)
neutral.png :| :-|
-sleepy.png I-) i-) |-)
+sleeping.png I-) i-) |-)
kiss.png :-* :*
confused.png :-S :-s
+sarcastic.png /:)
+eyeroll.png 8-|
hug-left.png >:D< >:d<
party.png <:-P <:-p
# Hidden Yahoo emotes
coffee.png ~o) ~O)
+rose.png @};-
dont-know.png :-L :-l
+lamp.png *-:)
shame.png [-X [-x
musical-note.png :-"
+star.png (*)
# Following MySpaceIM Beta 1.0.697.0
@@ -222,10 +265,13 @@ musical-note.png :-"
excited.png :D :-D
devil.png }:)
confused.png :Z
+happy.png :) :-)
amorous.png :X
+pirate.png P)
shocked.png :O
neutral.png :|
tongue.png :P :p
+pissed-off.png B|
wink.png ;-) ;)
sad.png :[
kiss.png :x
@@ -240,7 +286,7 @@ neutral.png :-| :|
shocked.png :-O :O
tongue.png :-P :P
embarrassed.png :-$ :$
-cool.png 8-)
+glasses-cool.png 8-)
in_love.png (H)
rose.png (F)
### Added in v3.0
@@ -252,7 +298,7 @@ kiss.png (x)
lamp.png (i)
pissed-off.png :e :-e
shut-mouth.png :-x :x
-grumpy.png (z)
+thunder.png (z)
coffee.png (U)
mrgreen.png (G)
### Added in v5.0
@@ -265,7 +311,7 @@ thinking.png :-? :?
drool.png :-~ :~
sleeping.png :-z :z
lying.png :L)
-nerdy.png 8-| 8|
+glasses-nerdy.png 8-| 8|
pirate.png P-)
### Added in v5.9.7
bored.png :-[ :[
diff --git a/pidgin/pixmaps/emotes/small/16/thunder.png b/pidgin/pixmaps/emotes/small/16/thunder.png
new file mode 100644
index 0000000000..51a3b81640
--- /dev/null
+++ b/pidgin/pixmaps/emotes/small/16/thunder.png
Binary files differ
diff --git a/pidgin/pixmaps/pidgin.ico b/pidgin/pixmaps/pidgin.ico
index b215586d1c..f4b3a30501 100644
--- a/pidgin/pixmaps/pidgin.ico
+++ b/pidgin/pixmaps/pidgin.ico
Binary files differ
diff --git a/pidgin/plugins/gevolution/add_buddy_dialog.c b/pidgin/plugins/gevolution/add_buddy_dialog.c
index 6a334b476a..3b7e23645a 100644
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c
+++ b/pidgin/plugins/gevolution/add_buddy_dialog.c
@@ -54,8 +54,7 @@ delete_win_cb(GtkWidget *w, GdkEvent *event, GevoAddBuddyDialog *dialog)
gevo_addrbooks_model_unref(dialog->addrbooks);
- if (dialog->username != NULL)
- g_free(dialog->username);
+ g_free(dialog->username);
g_free(dialog);
@@ -289,7 +288,7 @@ populate_treeview(GevoAddBuddyDialog *dialog, const gchar *uri)
{
EContact *contact = E_CONTACT(c->data);
const char *name;
- GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells;
+ GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells, *ggs;
name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
@@ -299,9 +298,11 @@ populate_treeview(GevoAddBuddyDialog *dialog, const gchar *uri)
msns = e_contact_get(contact, E_CONTACT_IM_MSN);
icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
+ ggs = e_contact_get(contact, E_CONTACT_IM_GADUGADU);
if (aims == NULL && jabbers == NULL && yahoos == NULL &&
- msns == NULL && icqs == NULL && novells == NULL)
+ msns == NULL && icqs == NULL && novells == NULL &&
+ ggs == NULL)
{
GtkTreeIter iter;
@@ -320,6 +321,7 @@ populate_treeview(GevoAddBuddyDialog *dialog, const gchar *uri)
add_ims(dialog, contact, name, msns, "prpl-msn");
add_ims(dialog, contact, name, icqs, "prpl-icq");
add_ims(dialog, contact, name, novells, "prpl-novell");
+ add_ims(dialog, contact, name, ggs, "prpl-gg");
}
}
@@ -365,7 +367,7 @@ search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
{
EContact *contact = E_CONTACT(l->data);
const char *name;
- GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells;
+ GList *aims, *jabbers, *yahoos, *msns, *icqs, *novells, *ggs;
name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
@@ -381,9 +383,11 @@ search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
msns = e_contact_get(contact, E_CONTACT_IM_MSN);
icqs = e_contact_get(contact, E_CONTACT_IM_ICQ);
novells = e_contact_get(contact, E_CONTACT_IM_GROUPWISE);
+ ggs = e_contact_get(contact, E_CONTACT_IM_GADUGADU);
if (aims == NULL && jabbers == NULL && yahoos == NULL &&
- msns == NULL && icqs == NULL && novells == NULL)
+ msns == NULL && icqs == NULL && novells == NULL &&
+ ggs == NULL)
{
GtkTreeIter iter;
@@ -402,6 +406,7 @@ search_changed_cb(GtkEntry *entry, GevoAddBuddyDialog *dialog)
add_ims(dialog, contact, name, msns, "prpl-msn");
add_ims(dialog, contact, name, icqs, "prpl-icq");
add_ims(dialog, contact, name, novells, "prpl-novell");
+ add_ims(dialog, contact, name, ggs, "prpl-gg");
}
}
}
diff --git a/pidgin/plugins/gevolution/gevo-util.c b/pidgin/plugins/gevolution/gevo-util.c
index 9213328cfd..8f97a7df8f 100644
--- a/pidgin/plugins/gevolution/gevo-util.c
+++ b/pidgin/plugins/gevolution/gevo-util.c
@@ -111,6 +111,8 @@ gevo_prpl_get_field(PurpleAccount *account, PurpleBuddy *buddy)
protocol_field = E_CONTACT_IM_JABBER;
else if (!strcmp(protocol_id, "prpl-novell"))
protocol_field = E_CONTACT_IM_GROUPWISE;
+ else if (!strcmp(protocol_id, "prpl-gg"))
+ protocol_field = E_CONTACT_IM_GADUGADU;
return protocol_field;
}
diff --git a/pidgin/plugins/gevolution/gevolution.c b/pidgin/plugins/gevolution/gevolution.c
index 848ad38aff..2317e95b7b 100644
--- a/pidgin/plugins/gevolution/gevolution.c
+++ b/pidgin/plugins/gevolution/gevolution.c
@@ -125,6 +125,7 @@ update_buddies_from_contact(EContact *contact)
update_ims_from_contact(contact, name, "prpl-msn", E_CONTACT_IM_MSN);
update_ims_from_contact(contact, name, "prpl-icq", E_CONTACT_IM_ICQ);
update_ims_from_contact(contact, name, "prpl-novell", E_CONTACT_IM_GROUPWISE);
+ update_ims_from_contact(contact, name, "prpl-gg", E_CONTACT_IM_GADUGADU);
}
static void
diff --git a/pidgin/plugins/gevolution/new_person_dialog.c b/pidgin/plugins/gevolution/new_person_dialog.c
index 08aa7715f1..30682f0ce1 100644
--- a/pidgin/plugins/gevolution/new_person_dialog.c
+++ b/pidgin/plugins/gevolution/new_person_dialog.c
@@ -153,6 +153,8 @@ add_cb(GtkWidget *w, GevoNewPersonDialog *dialog)
field = E_CONTACT_IM_MSN;
else if (!strcmp(im_service, "prpl-novell"))
field = E_CONTACT_IM_GROUPWISE;
+ else if (!strcmp(im_service, "prpl-gg"))
+ field = E_CONTACT_IM_GADUGADU;
if (field > 0)
{
@@ -202,8 +204,7 @@ add_cb(GtkWidget *w, GevoNewPersonDialog *dialog)
if (name != NULL)
e_contact_name_free(name);
- if (full_name != NULL)
- g_free(full_name);
+ g_free(full_name);
delete_win_cb(NULL, NULL, dialog);
}
diff --git a/pidgin/plugins/notify.c b/pidgin/plugins/notify.c
index fc68e56233..1e0a38aa8d 100644
--- a/pidgin/plugins/notify.c
+++ b/pidgin/plugins/notify.c
@@ -303,7 +303,6 @@ static int
attach_signals(PurpleConversation *conv)
{
PidginConversation *gtkconv = NULL;
- PidginWindow *gtkwin = NULL;
GSList *imhtml_ids = NULL, *entry_ids = NULL;
guint id;
@@ -313,8 +312,6 @@ attach_signals(PurpleConversation *conv)
return 0;
}
- gtkwin = gtkconv->win;
-
if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_focus")) {
/* TODO should really find a way to make this work no matter
* where the focus is inside the conv window, without having
@@ -358,13 +355,11 @@ static void
detach_signals(PurpleConversation *conv)
{
PidginConversation *gtkconv = NULL;
- PidginWindow *gtkwin = NULL;
GSList *ids = NULL, *l;
gtkconv = PIDGIN_CONVERSATION(conv);
if (!gtkconv)
return;
- gtkwin = gtkconv->win;
ids = purple_conversation_get_data(conv, "notify-imhtml-signals");
for (l = ids; l != NULL; l = l->next)
@@ -650,7 +645,6 @@ static void
apply_method()
{
GList *convs;
- PidginWindow *purplewin = NULL;
for (convs = purple_get_conversations(); convs != NULL;
convs = convs->next) {
@@ -659,7 +653,6 @@ apply_method()
/* remove notifications */
unnotify(conv, FALSE);
- purplewin = PIDGIN_CONVERSATION(conv)->win;
if (GPOINTER_TO_INT(purple_conversation_get_data(conv, "notify-message-count")) != 0)
/* reattach appropriate notifications */
notify(conv, FALSE);
diff --git a/pidgin/plugins/vvconfig.c b/pidgin/plugins/vvconfig.c
index b5489b747f..d125703c7c 100644
--- a/pidgin/plugins/vvconfig.c
+++ b/pidgin/plugins/vvconfig.c
@@ -28,6 +28,9 @@
#include <gst/interfaces/propertyprobe.h>
+/* container window for showing a stand-alone configurator */
+static GtkWidget *window = NULL;
+
static PurpleMediaElementInfo *old_video_src = NULL, *old_video_sink = NULL,
*old_audio_src = NULL, *old_audio_sink = NULL;
@@ -502,6 +505,59 @@ plugin_load(PurplePlugin *plugin)
return TRUE;
}
+static void
+config_destroy(GtkObject *w, gpointer nul)
+{
+ purple_debug_info("vvconfig", "closing vv configuration window\n");
+ window = NULL;
+}
+
+static void
+config_close(GtkObject *w, gpointer nul)
+{
+ gtk_widget_destroy(GTK_WIDGET(window));
+}
+
+static void
+show_config(PurplePluginAction *action)
+{
+ if (!window) {
+ GtkWidget *vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
+ GtkWidget *hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
+ GtkWidget *config_frame = get_plugin_config_frame(NULL);
+ GtkWidget *close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+
+ gtk_container_add(GTK_CONTAINER(vbox), config_frame);
+ gtk_container_add(GTK_CONTAINER(vbox), hbox);
+ window = pidgin_create_window(_("Voice/Video Settings"),
+ PIDGIN_HIG_BORDER, NULL, TRUE);
+ g_signal_connect(G_OBJECT(window), "destroy",
+ G_CALLBACK(config_destroy), NULL);
+ g_signal_connect(G_OBJECT(close), "clicked",
+ G_CALLBACK(config_close), NULL);
+ gtk_box_pack_end(GTK_BOX(hbox), close, FALSE, FALSE, PIDGIN_HIG_BORDER);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ gtk_widget_show(GTK_WIDGET(close));
+ gtk_widget_show(GTK_WIDGET(vbox));
+ gtk_widget_show(GTK_WIDGET(hbox));
+ }
+ gtk_window_present(GTK_WINDOW(window));
+}
+
+
+static GList *
+actions(PurplePlugin *plugin, gpointer context)
+{
+ GList *l = NULL;
+ PurplePluginAction *act = NULL;
+
+ act = purple_plugin_action_new(_("Voice and Video Settings"),
+ show_config);
+ l = g_list_append(l, act);
+
+ return l;
+}
+
static gboolean
plugin_unload(PurplePlugin *plugin)
{
@@ -525,32 +581,32 @@ static PidginPluginUiInfo ui_info = {
static PurplePluginInfo info =
{
- PURPLE_PLUGIN_MAGIC, /**< 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 */
-
- "gtk-maiku-vvconfig", /**< id */
- N_("Voice/Video Settings"), /**< name */
- DISPLAY_VERSION, /**< version */
- N_("Configure your microphone and webcam."), /**< summary */
+ PURPLE_PLUGIN_MAGIC, /**< 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 */
+
+ "gtk-maiku-vvconfig", /**< id */
+ N_("Voice/Video Settings"), /**< name */
+ DISPLAY_VERSION, /**< version */
+ N_("Configure your microphone and webcam."), /**< summary */
N_("Configure microphone and webcam "
- "settings for voice/video calls."), /**< description */
- "Mike Ruprecht <cmaiku@gmail.com>", /**< author */
- PURPLE_WEBSITE, /**< homepage */
-
- plugin_load, /**< load */
- plugin_unload, /**< unload */
- NULL, /**< destroy */
-
- &ui_info, /**< ui_info */
- NULL, /**< extra_info */
- NULL, /**< prefs_info */
- NULL, /**< actions */
+ "settings for voice/video calls."), /**< description */
+ "Mike Ruprecht <cmaiku@gmail.com>", /**< author */
+ PURPLE_WEBSITE, /**< homepage */
+
+ plugin_load, /**< load */
+ plugin_unload, /**< unload */
+ NULL, /**< destroy */
+
+ &ui_info, /**< ui_info */
+ NULL, /**< extra_info */
+ NULL, /**< prefs_info */
+ actions, /**< actions */
/* padding */
NULL,
diff --git a/pidgin/plugins/xmppconsole.c b/pidgin/plugins/xmppconsole.c
index 7c063d80ac..38c2eb1451 100644
--- a/pidgin/plugins/xmppconsole.c
+++ b/pidgin/plugins/xmppconsole.c
@@ -183,7 +183,7 @@ static void message_send_cb(GtkWidget *widget, gpointer p)
{
GtkTextIter start, end;
PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConnection *gc = console->gc;
+ PurpleConnection *gc;
GtkTextBuffer *buffer;
char *text;
diff --git a/pidgin/win32/IdleTracker/Makefile.mingw b/pidgin/win32/IdleTracker/Makefile.mingw
deleted file mode 100644
index 8395da1411..0000000000
--- a/pidgin/win32/IdleTracker/Makefile.mingw
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Makefile.mingw
-#
-# Description: Makefile for idletrack
-#
-
-PIDGIN_TREE_TOP := ../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-
-TARGET = idletrack
-
-##
-## SOURCES, OBJECTS
-##
-
-C_SRC = idletrack.c
-
-OBJECTS = $(C_SRC:%.c=%.o)
-
-include $(PIDGIN_COMMON_RULES)
-
-##
-## TARGET DEFINITIONS
-##
-
-.PHONY: all install clean
-
-all: $(TARGET).dll
-
-install: $(PIDGIN_INSTALL_DIR)
- cp $(TARGET).dll $(PIDGIN_INSTALL_DIR)
-
-##
-## BUILD DLL
-##
-
-$(TARGET).dll $(TARGET).dll.a: $(OBJECTS)
- $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).dll.a -o $(TARGET).dll
-
-##
-## CLEAN RULES
-##
-
-clean:
- rm -f $(OBJECTS) $(TARGET).dll $(TARGET).dll.a
-
-include $(PIDGIN_COMMON_TARGETS)
diff --git a/pidgin/win32/IdleTracker/idletrack.c b/pidgin/win32/IdleTracker/idletrack.c
deleted file mode 100644
index a273963bcf..0000000000
--- a/pidgin/win32/IdleTracker/idletrack.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * idletrack.c
- *
- * Authors: mrgentry @ http://www.experts-exchange.com
- * Herman Bloggs <hermanator12002@yahoo.com>
- * Date: February, 2003
- * Description: Track user inactivity.
- *
- * Andrew Whewell <awhewell@users.sourceforge.net> - 25th June 2004. Added
- * support for GetLastInputInfo under Windows 2000 and above. This avoids having
- * IDLETRACK.DLL hook itself into every process on the machine, which makes
- * upgrades easier. The hook mechanism is also used by key loggers, so not
- * using hooks doesn't put the willys up programs that keep an eye out for
- * loggers.
- *
- * Windows 9x doesn't have GetLastInputInfo - when Purple runs on these machines
- * the code silently falls back onto the old hooking scheme.
- */
-#define _WIN32_WINNT 0x0500
-#include "idletrack.h"
-
-#define EXPORT __declspec(dllexport)
-
-static HANDLE hMapObject = NULL;
-static DWORD *lastTime = NULL;
-static HHOOK keyHook = NULL;
-static HHOOK mouseHook = NULL;
-static HINSTANCE g_hInstance = NULL;
-static POINT g_point;
-
-/* GetLastInputInfo address and module - if g_GetLastInputInfo == NULL then
- * we fall back on the old "hook the world" method. GetLastInputInfo was brought
- * in with Windows 2000 so Windows 9x will still hook everything.
- */
-typedef BOOL (WINAPI *GETLASTINPUTINFO)(LASTINPUTINFO *);
-static HMODULE g_user32 = NULL;
-static GETLASTINPUTINFO g_GetLastInputInfo = NULL;
-
-static DWORD* setup_shared_mem() {
- BOOL fInit;
-
- /* Set up the shared memory. */
- hMapObject = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* use paging file */
- NULL, /* no security attributes */
- PAGE_READWRITE, /* read/write access */
- 0, /* size: high 32-bits */
- sizeof(DWORD), /* size: low 32-bits */
- "timermem"); /* name of map object */
-
- if(hMapObject == NULL)
- return NULL;
-
- /* The first process to attach initializes memory. */
- fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
-
- /* Get a pointer to the file-mapped shared memory. */
- lastTime = (DWORD*) MapViewOfFile(hMapObject, /* object to map view of */
- FILE_MAP_WRITE, /* read/write access */
- 0, /* high offset: map from */
- 0, /* low offset: beginning */
- 0); /* default: map entire file */
-
- if(lastTime == NULL)
- return NULL;
-
- *lastTime = GetTickCount();
-
- return lastTime;
-}
-
-
-static LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
- if(!(code < 0)) {
- if(lastTime == NULL)
- lastTime = setup_shared_mem();
-
- if(lastTime)
- *lastTime = GetTickCount();
- }
- return CallNextHookEx(keyHook, code, wParam, lParam);
-}
-
-
-static LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {
- /* We need to verify that the Mouse pointer has actually moved. */
- if(!(code < 0) &&
- !((g_point.x == ((MOUSEHOOKSTRUCT*) lParam)->pt.x) &&
- (g_point.y == ((MOUSEHOOKSTRUCT*) lParam)->pt.y))) {
- g_point.x = ((MOUSEHOOKSTRUCT*) lParam)->pt.x;
- g_point.y = ((MOUSEHOOKSTRUCT*) lParam)->pt.y;
-
- if(lastTime == NULL)
- lastTime = setup_shared_mem();
-
- if(lastTime)
- *lastTime = GetTickCount();
- }
- return CallNextHookEx(mouseHook, code, wParam, lParam);
-}
-
-
-EXPORT DWORD winpidgin_get_lastactive() {
- DWORD result = 0;
-
- /* If we have GetLastInputInfo then use it, otherwise use the hooks*/
- if(g_GetLastInputInfo != NULL) {
- LASTINPUTINFO lii;
- memset(&lii, 0, sizeof(lii));
- lii.cbSize = sizeof(lii);
- if(g_GetLastInputInfo(&lii)) {
- result = lii.dwTime;
- }
- } else {
- if(lastTime == NULL)
- lastTime = setup_shared_mem();
-
- if(lastTime)
- result = *lastTime;
- }
-
- return result;
-}
-
-
-EXPORT BOOL winpidgin_set_idlehooks() {
- /* Is GetLastInputInfo available?*/
- g_user32 = LoadLibrary("user32.dll");
- if(g_user32) {
- g_GetLastInputInfo = (GETLASTINPUTINFO) GetProcAddress(g_user32, "GetLastInputInfo");
- }
-
- /* If we couldn't find GetLastInputInfo then fall back onto the hooking scheme*/
- if(g_GetLastInputInfo == NULL) {
- /* Set up the shared memory.*/
- lastTime = setup_shared_mem();
- if(lastTime == NULL)
- return FALSE;
- *lastTime = GetTickCount();
-
- /* Set up the keyboard hook.*/
- keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
- if(keyHook == NULL) {
- UnmapViewOfFile(lastTime);
- CloseHandle(hMapObject);
- return FALSE;
- }
-
- /* Set up the mouse hook.*/
- mouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hInstance, 0);
- if(mouseHook == NULL) {
- UnhookWindowsHookEx(keyHook);
- UnmapViewOfFile(lastTime);
- CloseHandle(hMapObject);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-
-EXPORT void winpidgin_remove_idlehooks() {
- if(g_user32 != NULL)
- FreeLibrary(g_user32);
- if(keyHook)
- UnhookWindowsHookEx(keyHook);
- if(mouseHook)
- UnhookWindowsHookEx(mouseHook);
- if(lastTime)
- UnmapViewOfFile(lastTime);
- if(hMapObject)
- CloseHandle(hMapObject);
-}
-
-/* suppress gcc "no previous prototype" warning */
-BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved);
-BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
- switch(dwReason) {
- case DLL_PROCESS_ATTACH:
- g_hInstance = hInstance;
- g_point.x = 0;
- g_point.y = 0;
- break;
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
-}
diff --git a/pidgin/win32/IdleTracker/idletrack.h b/pidgin/win32/IdleTracker/idletrack.h
deleted file mode 100644
index 718a4427b8..0000000000
--- a/pidgin/win32/IdleTracker/idletrack.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * idletrack.h
- */
-#include <windows.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-DWORD winpidgin_get_lastactive(void);
-BOOL winpidgin_set_idlehooks(void);
-void winpidgin_remove_idlehooks(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
diff --git a/pidgin/win32/gtkwin32dep.c b/pidgin/win32/gtkwin32dep.c
index 5e5b7fc2ca..2e9706f0d7 100644
--- a/pidgin/win32/gtkwin32dep.c
+++ b/pidgin/win32/gtkwin32dep.c
@@ -43,7 +43,6 @@
#include "network.h"
#include "resource.h"
-#include "idletrack.h"
#include "zlib.h"
#include "untar.h"
@@ -377,15 +376,19 @@ winpidgin_conv_im_blink(PurpleAccount *account, const char *who, char **message,
void winpidgin_init(HINSTANCE hint) {
FARPROC proc;
+ gchar *exchndl_dll_path;
purple_debug_info("winpidgin", "winpidgin_init start\n");
exe_hInstance = hint;
- proc = wpurple_find_and_loadproc("exchndl.dll", "SetLogFile");
+ exchndl_dll_path = g_build_filename(wpurple_install_dir(), "exchndl.dll", NULL);
+ proc = wpurple_find_and_loadproc(exchndl_dll_path, "SetLogFile");
+ g_free(exchndl_dll_path);
+ exchndl_dll_path = NULL;
if (proc) {
gchar *debug_dir, *locale_debug_dir;
-
+
debug_dir = g_build_filename(purple_user_dir(), "pidgin.RPT", NULL);
locale_debug_dir = g_locale_from_utf8(debug_dir, -1, NULL, NULL, NULL);
@@ -397,10 +400,6 @@ void winpidgin_init(HINSTANCE hint) {
g_free(locale_debug_dir);
}
- /* IdleTracker Initialization */
- if(!winpidgin_set_idlehooks())
- purple_debug_error("winpidgin", "Failed to initialize idle tracker\n");
-
winpidgin_spell_init();
purple_debug_info("winpidgin", "GTK+ :%u.%u.%u\n",
gtk_major_version, gtk_minor_version, gtk_micro_version);
@@ -429,9 +428,6 @@ void winpidgin_cleanup(void) {
if(messagewin_hwnd)
DestroyWindow(messagewin_hwnd);
- /* Idle tracker cleanup */
- winpidgin_remove_idlehooks();
-
}
/* DLL initializer */
@@ -535,5 +531,18 @@ void winpidgin_ensure_onscreen(GtkWidget *win) {
(winR.right - winR.left),
(winR.bottom - winR.top), TRUE);
}
+
+}
+
+DWORD winpidgin_get_lastactive() {
+ DWORD result = 0;
+
+ LASTINPUTINFO lii;
+ memset(&lii, 0, sizeof(lii));
+ lii.cbSize = sizeof(lii);
+ if (GetLastInputInfo(&lii))
+ result = lii.dwTime;
+
+ return result;
}
diff --git a/pidgin/win32/gtkwin32dep.h b/pidgin/win32/gtkwin32dep.h
index a0f64e0aca..3584334e0c 100644
--- a/pidgin/win32/gtkwin32dep.h
+++ b/pidgin/win32/gtkwin32dep.h
@@ -39,6 +39,7 @@ void winpidgin_shell_execute(const char *target, const char *verb, const char *c
void winpidgin_ensure_onscreen(GtkWidget *win);
void winpidgin_conv_blink(PurpleConversation *conv, PurpleMessageFlags flags);
void winpidgin_window_flash(GtkWindow *window, gboolean flash);
+DWORD winpidgin_get_lastactive(void);
/* init / cleanup */
void winpidgin_init(HINSTANCE);
diff --git a/pidgin/win32/nsis/nsis_translations.desktop.in b/pidgin/win32/nsis/nsis_translations.desktop.in
index c7b7d25fd9..ed0dc8284a 100644
--- a/pidgin/win32/nsis/nsis_translations.desktop.in
+++ b/pidgin/win32/nsis/nsis_translations.desktop.in
@@ -6,7 +6,7 @@ _PIDGINISRUNNING=An instance of Pidgin is currently running. Please exit Pidgin
# "Next >" appears on a button on the License Page of the Installer
_PIDGINLICENSEBUTTON=Next >
-# $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue."
+# $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue." DO NOT translate the CLICK in $_CLICK. It will break the installer.
_PIDGINLICENSEBOTTOMTEXT=$(^Name) is released under the GNU General Public License (GPL). The license is provided here for information purposes only. $_CLICK
#Installer Subsection Text
diff --git a/pidgin/win32/nsis/pidgin-installer.nsi b/pidgin/win32/nsis/pidgin-installer.nsi
index e858eacf35..951643d96a 100644
--- a/pidgin/win32/nsis/pidgin-installer.nsi
+++ b/pidgin/win32/nsis/pidgin-installer.nsi
@@ -268,7 +268,7 @@ Section $(GTKSECTIONTITLE) SecGtk
DetailPrint "Downloading GTK+ Runtime ... ($R2)"
NSISdl::download /TIMEOUT=10000 $R2 $R1
Pop $R0
- StrCmp $R0 "cancel" done
+ ;StrCmp $R0 "cancel" done
StrCmp $R0 "success" +2
MessageBox MB_RETRYCANCEL "$(PIDGINGTKDOWNLOADERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done
@@ -304,6 +304,7 @@ Section $(PIDGINSECTIONTITLE) SecPidgin
WriteRegStr HKLM "${HKLM_APP_PATHS_KEY}" "Path" "$INSTDIR\Gtk\bin"
WriteRegStr HKLM ${PIDGIN_REG_KEY} "" "$INSTDIR"
WriteRegStr HKLM ${PIDGIN_REG_KEY} "Version" "${PIDGIN_VERSION}"
+ WriteRegStr HKLM "${PIDGIN_UNINSTALL_KEY}" "DisplayIcon" "$INSTDIR\pidgin.exe"
WriteRegStr HKLM "${PIDGIN_UNINSTALL_KEY}" "DisplayName" "Pidgin"
WriteRegStr HKLM "${PIDGIN_UNINSTALL_KEY}" "DisplayVersion" "${PIDGIN_VERSION}"
WriteRegStr HKLM "${PIDGIN_UNINSTALL_KEY}" "HelpLink" "http://developer.pidgin.im/wiki/Using Pidgin"
@@ -317,6 +318,7 @@ Section $(PIDGINSECTIONTITLE) SecPidgin
pidgin_hkcu:
WriteRegStr HKCU ${PIDGIN_REG_KEY} "" "$INSTDIR"
WriteRegStr HKCU ${PIDGIN_REG_KEY} "Version" "${PIDGIN_VERSION}"
+ WriteRegStr HKCU "${PIDGIN_UNINSTALL_KEY}" "DisplayIcon" "$INSTDIR\pidgin.exe"
WriteRegStr HKCU "${PIDGIN_UNINSTALL_KEY}" "DisplayName" "Pidgin"
WriteRegStr HKCU "${PIDGIN_UNINSTALL_KEY}" "DisplayVersion" "${PIDGIN_VERSION}"
WriteRegStr HKCU "${PIDGIN_UNINSTALL_KEY}" "HelpLink" "http://developer.pidgin.im/wiki/Using Pidgin"
@@ -541,6 +543,7 @@ Section Uninstall
Delete "$INSTDIR\ca-certs\StartCom_Certification_Authority.pem"
Delete "$INSTDIR\ca-certs\StartCom_Free_SSL_CA.pem"
Delete "$INSTDIR\ca-certs\Thawte_Premium_Server_CA.pem"
+ Delete "$INSTDIR\ca-certs\ValiCert_Class_2_VA.crt"
Delete "$INSTDIR\ca-certs\VeriSign_Class3_Extended_Validation_CA.pem"
Delete "$INSTDIR\ca-certs\Verisign_Class3_Primary_CA.pem"
Delete "$INSTDIR\ca-certs\VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem"
@@ -618,7 +621,6 @@ Section Uninstall
RMDir "$INSTDIR\spellcheck\lib"
RMDir "$INSTDIR\spellcheck"
Delete "$INSTDIR\freebl3.dll"
- Delete "$INSTDIR\idletrack.dll"
Delete "$INSTDIR\libjabber.dll"
Delete "$INSTDIR\libnspr4.dll"
Delete "$INSTDIR\libmeanwhile-1.dll"
diff --git a/pidgin/win32/winpidgin.c b/pidgin/win32/winpidgin.c
index 8135ceeea1..c0186c32cf 100644
--- a/pidgin/win32/winpidgin.c
+++ b/pidgin/win32/winpidgin.c
@@ -605,9 +605,9 @@ WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
char *lpszCmdLine, int nCmdShow) {
wchar_t errbuf[512];
wchar_t pidgin_dir[MAX_PATH];
+ wchar_t *pidgin_dir_start = NULL;
wchar_t exe_name[MAX_PATH];
HMODULE hmod;
- wchar_t *tmp;
wchar_t *wtmp;
int pidgin_argc;
char **pidgin_argv; /* This is in utf-8 */
@@ -672,14 +672,14 @@ WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
if (GetModuleFileNameW(NULL, pidgin_dir, MAX_PATH) != 0) {
/* primitive dirname() */
- tmp = wcsrchr(pidgin_dir, L'\\');
+ pidgin_dir_start = wcsrchr(pidgin_dir, L'\\');
- if (tmp) {
+ if (pidgin_dir_start) {
HMODULE hmod;
- tmp[0] = L'\0';
+ pidgin_dir_start[0] = L'\0';
/* tmp++ will now point to the executable file name */
- wcscpy(exe_name, tmp + 1);
+ wcscpy(exe_name, pidgin_dir_start + 1);
wcscat(pidgin_dir, L"\\exchndl.dll");
if ((hmod = LoadLibraryW(pidgin_dir))) {
@@ -702,7 +702,8 @@ WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
proc = GetProcAddress(hmod, "SetDebugInfoDir");
if (proc) {
char *pidgin_dir_ansi = NULL;
- tmp[0] = L'\0';
+ /* Restore pidgin_dir to point to where the executable is */
+ pidgin_dir_start[0] = L'\0';
i = WideCharToMultiByte(CP_ACP, 0, pidgin_dir,
-1, NULL, 0, NULL, NULL);
if (i != 0) {
@@ -728,7 +729,8 @@ WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
}
- tmp[0] = L'\0';
+ /* Restore pidgin_dir to point to where the executable is */
+ pidgin_dir_start[0] = L'\0';
}
} else {
DWORD dw = GetLastError();
@@ -763,9 +765,14 @@ WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance,
return 0;
/* Now we are ready for Pidgin .. */
- if ((hmod = LoadLibraryW(L"pidgin.dll")))
+ wcscat(pidgin_dir, L"\\pidgin.dll");
+ if ((hmod = LoadLibraryW(pidgin_dir)))
pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main");
+ /* Restore pidgin_dir to point to where the executable is */
+ if (pidgin_dir_start)
+ pidgin_dir_start[0] = L'\0';
+
if (!pidgin_main) {
DWORD dw = GetLastError();
BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
diff --git a/pidgin/win32/wspell.c b/pidgin/win32/wspell.c
index 2e3cdcc93f..dec6f8dd23 100644
--- a/pidgin/win32/wspell.c
+++ b/pidgin/win32/wspell.c
@@ -73,25 +73,29 @@ void (*wpidginspell_recheck_all) (GtkSpell*) = wgtkspel
static void load_gtkspell() {
UINT old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
gchar *tmp, *tmp2;
+
const char *path = g_getenv("PATH");
tmp = g_build_filename(wpurple_install_dir(), "spellcheck", NULL);
- tmp2 = g_strdup_printf("%s%s%s", (path ? path : ""),
+ tmp2 = g_strdup_printf("%s%s%s", tmp,
(path ? G_SEARCHPATH_SEPARATOR_S : ""),
- tmp);
+ (path ? path : ""));
g_free(tmp);
g_setenv("PATH", tmp2, TRUE);
+ g_free(tmp2);
+ tmp = g_build_filename(wpurple_install_dir(), "spellcheck", GTKSPELL_DLL, NULL);
/* Suppress error popups */
- wpidginspell_new_attach_proxy = (void*) wpurple_find_and_loadproc(GTKSPELL_DLL, "gtkspell_new_attach" );
+ wpidginspell_new_attach_proxy = (void*) wpurple_find_and_loadproc(tmp, "gtkspell_new_attach" );
if (wpidginspell_new_attach_proxy) {
- wpidginspell_get_from_text_view = (void*) wpurple_find_and_loadproc(GTKSPELL_DLL, "gtkspell_get_from_text_view");
- wpidginspell_detach = (void*) wpurple_find_and_loadproc(GTKSPELL_DLL, "gtkspell_detach");
- wpidginspell_set_language = (void*) wpurple_find_and_loadproc(GTKSPELL_DLL, "gtkspell_set_language");
- wpidginspell_recheck_all = (void*) wpurple_find_and_loadproc(GTKSPELL_DLL, "gtkspell_recheck_all");
+ wpidginspell_get_from_text_view = (void*) wpurple_find_and_loadproc(tmp, "gtkspell_get_from_text_view");
+ wpidginspell_detach = (void*) wpurple_find_and_loadproc(tmp, "gtkspell_detach");
+ wpidginspell_set_language = (void*) wpurple_find_and_loadproc(tmp, "gtkspell_set_language");
+ wpidginspell_recheck_all = (void*) wpurple_find_and_loadproc(tmp, "gtkspell_recheck_all");
} else {
- purple_debug_warning("wspell", "Couldn't load gtkspell (%s) \n", GTKSPELL_DLL);
+ purple_debug_warning("wspell", "Couldn't load gtkspell (%s) \n", tmp);
/*wpidginspell_new_attach = wgtkspell_new_attach;*/
}
+ g_free(tmp);
SetErrorMode(old_error_mode);
}
diff --git a/po/ChangeLog b/po/ChangeLog
index 93041c78a3..9943047f77 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -3,10 +3,16 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
version 2.7.3
* Bengali translation updated (Jamil Ahmed)
* Chinese (Simplified) translation updated (Aron Xu)
+ * Czech translation updated (David Vachulka)
* Dutch translation updated (Gideon van Melle)
+ * Hebrew translation updated (Shalom Craimer)
* Norwegian Nynorsk translation updated (Yngve Spjeld Landro)
+ * Polish translation updated (Piotr Drąg)
+ * Punjabi translation updated (Amanpreet Singh Alam)
* Russian translation updated (Антон Самохвалов)
+ * Slovenian translation updated (Martin Srebotnjak)
* Spanish translation updated (Javier Fernández-Sanguino Peña)
+ * Ukrainian translation updated (Oleksandr Kovalenko)
version 2.7.2
* No changes
diff --git a/po/af.po b/po/af.po
index c416f4ef73..704eb843f7 100644
--- a/po/af.po
+++ b/po/af.po
@@ -802,7 +802,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "Wag vir oordrag om te begin"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Gekanselleer"
msgid "Failed"
@@ -15698,15 +15698,6 @@ msgstr "U het nie toestemming om hierdie toepassing te verwyder nie."
#~ "afkomstig te wees. Dit kan beteken dat u nie tans aan die diens gekoppel "
#~ "is wat u dink nie."
-#~ msgid "You canceled the transfer of %s"
-#~ msgstr "U het die oordrag van %s gekanselleer"
-
-#~ msgid "%s canceled the transfer of %s"
-#~ msgstr "%s het die oordrag van %s gekanselleer"
-
-#~ msgid "%s canceled the file transfer"
-#~ msgstr "%s het die lêeroordrag gekanselleer"
-
#~ msgid "Join/Part Hiding Configuration"
#~ msgstr "Opstelling vir in- en uitgaanversteking"
@@ -16292,7 +16283,7 @@ msgstr "U het nie toestemming om hierdie toepassing te verwyder nie."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Kon nie %s vir skryf open nie!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Lêeroordrag het misluk; ander kant het waarskynlik gekanselleer."
#~ msgid "Could not connect for transfer."
diff --git a/po/am.po b/po/am.po
index e3c938968e..9565c93d43 100644
--- a/po/am.po
+++ b/po/am.po
@@ -812,7 +812,7 @@ msgid "Waiting for transfer to begin"
msgstr ""
#, fuzzy
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ተወው"
#, fuzzy
diff --git a/po/ar.po b/po/ar.po
index a4c773572a..5f2d0cdf03 100644
--- a/po/ar.po
+++ b/po/ar.po
@@ -791,7 +791,7 @@ msgstr "قف"
msgid "Waiting for transfer to begin"
msgstr "في انتظار بدء النقل"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "أُلغِيَ"
msgid "Failed"
@@ -16584,7 +16584,7 @@ msgstr "لا تملك الصلاحيات لتثبيت هذا التطبيق."
#~ msgid "Could not open %s for writing!"
#~ msgstr "لايمكن فتح %s للكتابة!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "فشل ارسال الملف: من المحتمل أن المستقبِل ألغى العملية."
#~ msgid "Could not connect for transfer."
diff --git a/po/as.po b/po/as.po
index a846ca155d..b12a9053bf 100644
--- a/po/as.po
+++ b/po/as.po
@@ -789,7 +789,7 @@ msgstr "ৰখক"
msgid "Waiting for transfer to begin"
msgstr "বিনিময়ৰ আৰম্ভত অপেক্ষা কৰা হৈছে"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "বাতিল কৰা হৈছে"
msgid "Failed"
diff --git a/po/az.po b/po/az.po
index 94f1c86d38..27340255bc 100644
--- a/po/az.po
+++ b/po/az.po
@@ -809,7 +809,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr ""
msgid "Failed"
@@ -16008,7 +16008,7 @@ msgstr ""
#~ msgid "Invalid Groupname"
#~ msgstr "Səhv istifadəçi adı."
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Fayl transferi bacarılmadı, güman ki digər tərəfdən ləğv edildi."
#~ msgid "Could not connect for transfer."
diff --git a/po/be@latin.po b/po/be@latin.po
index c10eaa0757..9b602bd10f 100644
--- a/po/be@latin.po
+++ b/po/be@latin.po
@@ -801,7 +801,7 @@ msgstr "Spyni"
msgid "Waiting for transfer to begin"
msgstr "Čakańnie pačatku pieradačy"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Anulavanaja"
msgid "Failed"
@@ -16704,7 +16704,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Niemahčyma adčynić %s dziela zapisu!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Pamyłka pieradačy fajłu; aperacyja, mabyć, anulavanaja z taho boku."
#~ msgid "Could not connect for transfer."
diff --git a/po/bg.po b/po/bg.po
index d69fbfcfd4..2a01412886 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -820,7 +820,7 @@ msgstr "Зареждане при стартиране"
msgid "Waiting for transfer to begin"
msgstr "Изчакване пренасянето да започне"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Отказан"
msgid "Failed"
@@ -16574,7 +16574,7 @@ msgstr "Нямате права да деинсталирате тази про
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s не може да бъде отворен за запис!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Неуспешен пренос на файла. Получателят вероятно е отказал получаването."
diff --git a/po/bn.po b/po/bn.po
index 54a5102468..38a9d88036 100644
--- a/po/bn.po
+++ b/po/bn.po
@@ -843,7 +843,7 @@ msgstr "স্থগিত"
msgid "Waiting for transfer to begin"
msgstr "স্থানান্তর শুরু করার জন্য অপেক্ষা করা হচ্ছে"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "বাতিল করা হয়েছে"
# mark6
diff --git a/po/bn_IN.po b/po/bn_IN.po
index 6357aa423c..2d8a9ddd68 100644
--- a/po/bn_IN.po
+++ b/po/bn_IN.po
@@ -795,7 +795,7 @@ msgstr "বন্ধ"
msgid "Waiting for transfer to begin"
msgstr "পরিবহণ আরম্ভে অপেক্ষা চলছে"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "বাতিল করা হয়েছে"
msgid "Failed"
diff --git a/po/bs.po b/po/bs.po
index 7fd6951908..d32707e169 100644
--- a/po/bs.po
+++ b/po/bs.po
@@ -822,7 +822,7 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Cekanje na pocetak transfera"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Otkazano"
msgid "Failed"
@@ -17049,7 +17049,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Nije bilo moguce otvoriti %s za pisanje!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Transfer datoteke je neuspio; druga strana je vjerovatno odustala."
#~ msgid "Could not connect for transfer."
diff --git a/po/ca.po b/po/ca.po
index 025d65fb9f..407b78a455 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -33,8 +33,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-05-30 16:10+0200\n"
+"POT-Creation-Date: 2010-08-01 08:49+0200\n"
+"PO-Revision-Date: 2010-08-01 08:46+0200\n"
"Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
"Language-Team: Catalan <tradgnome@softcatala.net>\n"
"Language: ca\n"
@@ -87,9 +87,8 @@ msgstr ""
msgid "Error"
msgstr "Error"
-#, fuzzy
msgid "Account was not modified"
-msgstr "No s'ha afegit el compte"
+msgstr "No s'ha modificat el compte"
msgid "Account was not added"
msgstr "No s'ha afegit el compte"
@@ -100,10 +99,12 @@ msgstr "El nom d'usuari d'un compte no pot ser buit."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"No es pot canviar el protocol del compte si s'està connectat al servidor."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"No es pot canviar el nom d'usuari del compte si s'està connectat al servidor."
msgid "New mail notifications"
msgstr "Notifica si hi ha correu nou"
@@ -833,7 +834,7 @@ msgstr "Atura"
msgid "Waiting for transfer to begin"
msgstr "S'està esperant a iniciar la transferència"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "S'ha cancel·lat"
msgid "Failed"
@@ -1724,6 +1725,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"El certificat encara no és vàlid. Comproveu que la data i l'hora de "
+"l'ordinador siguin correctes."
msgid "The certificate has expired and should not be considered valid."
msgstr "El certificat ha expirat i no s'hauria de considerar vàlid."
@@ -2293,7 +2296,7 @@ msgid "You are using %s, but this plugin requires %s."
msgstr "Esteu emprant %s, però aquest connector requereix %s."
msgid "This plugin has not defined an ID."
-msgstr "Aquest connector no ha definit cap ID."
+msgstr "Aquest connector no ha definit cap identificador."
#, c-format
msgid "Plugin magic mismatch %d (need %d)"
@@ -3880,17 +3883,18 @@ msgstr "Repte del servidor invàlid"
msgid "Server thinks authentication is complete, but client does not"
msgstr "El servidor creu que s'ha completat l'autenticació, però el client no"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
-msgstr "El servidor requereix autenticació de text sobre un flux no xifrat"
+msgstr ""
+"Podria ser que el servidor requerís autenticació de text sobre un flux no "
+"xifrat"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s requereix autenticació de text sobre un flux no xifrat. Voleu permetre-ho "
-"i continuar amb l'autenticació?"
+"Podria ser que %s requerís autenticació de text sobre un flux no xifrat. "
+"Voleu permetre-ho i continuar amb l'autenticació?"
msgid "SASL authentication failed"
msgstr "Ha fallat l'autenticació SASL"
@@ -3953,7 +3957,7 @@ msgid "The BOSH connection manager terminated your session."
msgstr "El gestor de connexions BOSH ha tancat la connexió."
msgid "No session ID given"
-msgstr "No s'ha indicat cap ID"
+msgstr "No s'ha indicat cap identificador"
msgid "Unsupported version of BOSH protocol"
msgstr "Aquesta versió del protocol BOSH no està implementada"
@@ -4254,13 +4258,13 @@ msgid "Ping timed out"
msgstr "S'ha esgitat el temps d'espera (ping)"
msgid "Invalid XMPP ID"
-msgstr "ID de l'XMPP invàlid"
+msgstr "L'identificador XMPP no és vàlid"
msgid "Invalid XMPP ID. Username portion must be set."
-msgstr "L'ID de l'XMPP no és vàlid. Cal especificar el nom d'usuari."
+msgstr "L'identificador XMPP no és vàlid. Cal especificar el nom d'usuari."
msgid "Invalid XMPP ID. Domain must be set."
-msgstr "L'ID de l'XMPP no és vàlid. Cal especificar un domini."
+msgstr "L'identificador XMPP no és vàlid. Cal especificar un domini."
# FIXME
msgid "Malformed BOSH URL"
@@ -4479,7 +4483,7 @@ msgstr "No s'ha trobat l'element"
# FIX
msgid "Malformed XMPP ID"
-msgstr "L'ID de l'XMPP està malmès"
+msgstr "L'identificador XMPP està malmès"
msgid "Not Acceptable"
msgstr "No és acceptable"
@@ -4557,7 +4561,7 @@ msgid "Improper Addressing"
msgstr "Adreçament incorrecte"
msgid "Invalid ID"
-msgstr "ID invàlid"
+msgstr "L'identificador no és vàlid"
msgid "Invalid Namespace"
msgstr "Espai de noms invàlid"
@@ -4838,7 +4842,7 @@ msgid "XMPP Version Mismatch"
msgstr "Les versions del XMPP no coincideixen"
msgid "XMPP stream missing ID"
-msgstr "Manca l'ID del fluxe XMPP"
+msgstr "Manca l'identificador del fluxe XMPP"
msgid "XML Parse error"
msgstr "Error en l'anàlisi de l'XML"
@@ -5989,8 +5993,8 @@ msgstr "El PIN no és vàlid. Només pot contenir dígits [0-9]."
msgid "The two PINs you entered do not match."
msgstr "Els dos PIN que heu introduït no coincideixen."
-msgid "The name you entered is invalid."
-msgstr "El nom que heu introduït no és vàlid."
+msgid "The Display Name you entered is invalid."
+msgstr "El nom d'usuari que heu introduït no és vàlid."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -6012,9 +6016,8 @@ msgstr ""
"Encara no s'ha pogut recuperar la informació del vostre perfil. Torneu-ho a "
"intentar més tard."
-#, fuzzy
msgid "Your UID"
-msgstr "El vostre MXitID"
+msgstr "El vostre UID"
#. pin
#. pin (required)
@@ -6084,16 +6087,12 @@ msgstr "No s'ha pogut connectar al servidor MXit. Comproveu la configuració."
msgid "Connecting..."
msgstr "S'està connectant..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "El nom que heu introduït no és vàlid."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "La llargada del PIN que heu introduït no és vàlida [4-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "Identificador MXit"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6125,13 +6124,13 @@ msgstr "La vostra sessió ha expirat. Torneu-ho a intentar més tard."
msgid "Invalid country selected. Please try again."
msgstr "El país seleccionat no és vàlid. Intenteu-ho de nou."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "El nom d'usuari no està registrat, cal que primer el registreu."
+msgstr ""
+"L'identificador MXit que heu entrat no està registrat, cal que primer el "
+"registreu."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Aquest nom d'usuari ja està registrat, escolliu-ne un altre."
+msgstr "Aquest identificador MXit ja està registrat, escolliu-ne un altre."
msgid "Internal error. Please try again later."
msgstr "S'ha produït un error intern. Torneu-ho a provar més tard."
@@ -6176,9 +6175,8 @@ msgstr "Missatge de rebuig"
msgid "Hidden Number"
msgstr "Nombre ocult"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "El vostre MXitID"
+msgstr "El vostre identificador MXit..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6202,13 +6200,11 @@ msgid "_Room Name:"
msgstr "Nom de la _Sala:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Teniu correu!"
+msgstr "Heu convidat"
-#, fuzzy
msgid "Last Online"
-msgstr "En línia"
+msgstr "Darrer cop en línia"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -6880,7 +6876,7 @@ msgid "Mailstop"
msgstr "Oficina de correu electrònic"
msgid "User ID"
-msgstr "ID de l'usuari"
+msgstr "Identificador de l'usuari"
#. tag = _("DN");
#. value = nm_user_record_get_dn(user_record);
@@ -7531,8 +7527,8 @@ msgid ""
"You missed %hu message from %s because the rate limit has been exceeded."
msgid_plural ""
"You missed %hu messages from %s because the rate limit has been exceeded."
-msgstr[0] "S'ha perdut %hu missatge de %s perquè no era vàlid."
-msgstr[1] "S'han perdut %hu missatges de %s perquè no eren vàlids."
+msgstr[0] "S'ha perdut %hu missatge de %s perquè s'ha excedit el límit."
+msgstr[1] "S'han perdut %hu missatges de %s perquè s'ha excedit el límit."
#, c-format
msgid ""
@@ -7992,10 +7988,10 @@ msgid "Invalid SNAC"
msgstr "SNAC invàlid"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "S'ha excedit el límit de velocitat del servidor"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "S'ha excedit el límit de velocitat del client"
msgid "Service unavailable"
msgstr "Servei no disponible"
@@ -8313,10 +8309,10 @@ msgid "Message: %s"
msgstr "Missatge: %s"
msgid "ID: "
-msgstr "ID: "
+msgstr "Identificador: "
msgid "Group ID"
-msgstr "ID del Grup"
+msgstr "Identificador del Grup"
msgid "QQ Qun"
msgstr "QQ Qun"
@@ -8784,7 +8780,7 @@ msgstr "<b>Títol del grup:</b> %s<br>"
#, c-format
msgid "<b>Notes Group ID:</b> %s<br>"
-msgstr "<b>ID del grup Notes:</b> %s<br>"
+msgstr "<b>Identificador del grup Notes:</b> %s<br>"
#, c-format
msgid "Info for Group %s"
@@ -8946,10 +8942,10 @@ msgid "User Name"
msgstr "Nom d'usuari"
msgid "Sametime ID"
-msgstr "ID de Sametime"
+msgstr "Identificador de Sametime"
msgid "An ambiguous user ID was entered"
-msgstr "S'ha introduït un ID d'usuari ambigu"
+msgstr "S'ha introduït un identificador d'usuari ambigu"
#, c-format
msgid ""
@@ -10245,7 +10241,7 @@ msgid "doodle: Request user to start a Doodle session"
msgstr "doodle: fa una petició a l'usuari per iniciar una sessió Doodle"
msgid "Yahoo ID..."
-msgstr "ID de Yahoo..."
+msgstr "Identificador del Yahoo..."
#. *< type
#. *< ui_requirement
@@ -10277,15 +10273,15 @@ msgstr "Característiques locals de la sala de xat"
msgid "Ignore conference and chatroom invitations"
msgstr "Bloca invitacions a conferències i sales de xat"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Empra un compte per al servidor intermediari per a connexions SSL"
+msgstr ""
+"Empra un compte per al servidor intermediari per a connexions HTTP i HTTPS"
msgid "Chat room list URL"
msgstr "URL de la llista de sales de xat"
msgid "Yahoo JAPAN ID..."
-msgstr "ID de Yahoo del Japó..."
+msgstr "Identificador de Yahoo del Japó..."
#. *< type
#. *< ui_requirement
@@ -10497,13 +10493,13 @@ msgid "Start Doodling"
msgstr "Comença a dibuixar"
msgid "Select the ID you want to activate"
-msgstr "Seleccioneu l'ID que vulgueu activar"
+msgstr "Seleccioneu l'identificador que vulgueu activar"
msgid "Join whom in chat?"
msgstr "A qui us voleu unir al xat?"
msgid "Activate ID..."
-msgstr "Activa l'ID..."
+msgstr "Activa l'identificador..."
msgid "Join User in Chat..."
msgstr "Entra a un xat d'un usuari..."
@@ -10561,7 +10557,7 @@ msgstr ""
"navegador:"
msgid "Yahoo! ID"
-msgstr "ID de Yahoo!"
+msgstr "Identificador de Yahoo!"
msgid "Hobbies"
msgstr "Aficions"
@@ -13180,13 +13176,11 @@ msgstr ""
"Ara se sortirà atès que ja hi ha un altre client del libpurple executant-"
"se.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Medi"
+msgstr "_Medi"
-#, fuzzy
msgid "_Hangup"
-msgstr "Penja"
+msgstr "_Penja"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15512,6 +15506,9 @@ msgstr "Visita la pàgina web de Pidgin per Windows"
msgid "You do not have permission to uninstall this application."
msgstr "No tens permís per desinstal.lar aquesta aplicació."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "El nom que heu introduït no és vàlid."
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "El certificat encara no és vàlid."
@@ -16329,7 +16326,7 @@ msgstr "No tens permís per desinstal.lar aquesta aplicació."
#~ msgid "Could not open %s for writing!"
#~ msgstr "No s'ha pogut obrir %s per a escriure-hi."
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Ha fallat la transferència de fitxers. Probablement s'ha cancel·lat a "
#~ "l'altra banda."
diff --git a/po/ca@valencia.po b/po/ca@valencia.po
index 88f90939f7..880bca243f 100644
--- a/po/ca@valencia.po
+++ b/po/ca@valencia.po
@@ -33,14 +33,14 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-05-25 21:51+0200\n"
+"POT-Creation-Date: 2010-08-02 09:57-0400\n"
+"PO-Revision-Date: 2010-08-01 08:46+0200\n"
"Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
"Language-Team: Catalan <tradgnome@softcatala.net>\n"
-"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: ca\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#. Translators may want to transliterate the name.
@@ -87,9 +87,8 @@ msgstr ""
msgid "Error"
msgstr "Error"
-#, fuzzy
msgid "Account was not modified"
-msgstr "No s'ha afegit el compte"
+msgstr "No s'ha modificat el compte"
msgid "Account was not added"
msgstr "No s'ha afegit el compte"
@@ -100,10 +99,12 @@ msgstr "El nom d'usuari d'un compte no pot ser buit."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"No es pot canviar el protocol del compte si s'està connectat al servidor."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"No es pot canviar el nom d'usuari del compte si s'està connectat al servidor."
msgid "New mail notifications"
msgstr "Notifica si hi ha correu nou"
@@ -335,7 +336,8 @@ msgstr ""
"En suprimir este contacte, també se suprimiran tots els amics que hi haja"
msgid "Removing this group will also remove all the buddies in the group"
-msgstr "En suprimir este grup, també se suprimiran tots els amics que hi haja"
+msgstr ""
+"En suprimir este grup, també se suprimiran tots els amics que hi haja"
#, c-format
msgid "Are you sure you want to remove %s?"
@@ -594,7 +596,8 @@ msgstr "No existeix l'orde."
msgid "Syntax Error: You typed the wrong number of arguments to that command."
msgstr ""
-"Error de sintaxi: heu escrit un nombre d'arguments equivocat per a esta orde."
+"Error de sintaxi: heu escrit un nombre d'arguments equivocat per a esta "
+"orde."
msgid "Your command failed for an unknown reason."
msgstr "L'orde ha fallat per motius desconeguts."
@@ -766,8 +769,8 @@ msgstr ""
"de les diferents classes de missatge en les finestres de conversa.<br> "
"&lt;classe&gt;: receive (rep), send (envia), highlight (ressalta), action "
"(acció), timestamp (marca de temps)<br> &lt;primer pla/fons&gt;: black "
-"(negre), red (roig), green (verd), blue (blau), white (blanc), gray (gris), "
-"darkgray (gris fosc), magenta, cyan (cian), default (per defecte)"
+"(negre), red (roig), green (verd), blue (blau), white (blanc), gray "
+"(gris), darkgray (gris fosc), magenta, cyan (cian), default (per defecte)"
"<br><br>EXEMPLE:<br> msgcolor send cyan default"
msgid "Unable to open file."
@@ -831,7 +834,7 @@ msgstr "Atura"
msgid "Waiting for transfer to begin"
msgstr "S'està esperant a iniciar la transferència"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "S'ha cancel·lat"
msgid "Failed"
@@ -890,8 +893,8 @@ msgstr ""
msgid ""
"Chats will only be logged if the \"Log all chats\" preference is enabled."
msgstr ""
-"Els xats només es registraran si s'habilita la preferència «Registra tots "
-"els xats»."
+"Els xats només es registraran si s'habilita la preferència «Registra tots els "
+"xats»."
msgid "No logs were found"
msgstr "No s'ha trobat cap registre"
@@ -1722,6 +1725,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"El certificat encara no és vàlid. Comproveu que la data i l'hora de "
+"l'ordinador siguen correctes."
msgid "The certificate has expired and should not be considered valid."
msgstr "El certificat ha expirat i no s'hauria de considerar vàlid."
@@ -2183,7 +2188,8 @@ msgid ""
"True if the command used to handle this type of URL should be run in a "
"terminal."
msgstr ""
-"Cert si l'orde emprada per este tipus d'URL s'ha d'executar en un terminal."
+"Cert si l'orde emprada per este tipus d'URL s'ha d'executar en un "
+"terminal."
msgid "Whether the specified command should handle \"aim\" URLs"
msgstr "Si l'orde especificada ha de gestionar URL «aim»"
@@ -2290,7 +2296,7 @@ msgid "You are using %s, but this plugin requires %s."
msgstr "Esteu emprant %s, però este connector requereix %s."
msgid "This plugin has not defined an ID."
-msgstr "Este connector no ha definit cap ID."
+msgstr "Este connector no ha definit cap identificador."
#, c-format
msgid "Plugin magic mismatch %d (need %d)"
@@ -2736,8 +2742,8 @@ msgid ""
"Prepends a newline to messages so that the rest of the message appears below "
"the username in the conversation window."
msgstr ""
-"Afig una línia nova abans de cada missatge de manera que, en les finestres "
-"de conversa, els missatges apareixen sota el nom d'usuari."
+"Afig una línia nova abans de cada missatge de manera que, en les "
+"finestres de conversa, els missatges apareixen sota el nom d'usuari."
msgid "Offline Message Emulation"
msgstr "Emulació de missatge de fora de línia"
@@ -2805,7 +2811,8 @@ msgid ""
msgstr ""
"Vos permet forçar que les contrasenyes siguen d'un sol ús per a comptes dels "
"quals no s'alcen les contrasenyes.\n"
-"Nota: per poder fer servir això, cal que no s'alce la contrasenya del compte."
+"Nota: per poder fer servir això, cal que no s'alce la contrasenya del "
+"compte."
#. *< type
#. *< ui_requirement
@@ -2832,8 +2839,8 @@ msgid ""
"Causes conversation windows to appear as other users begin to message you. "
"This works for AIM, ICQ, XMPP, Sametime, and Yahoo!"
msgstr ""
-"Fa que apareguen finestres de conversa així que altres usuaris vos comencen "
-"a enviar missatges. Funciona per a AIM, ICQ, XMPP, Sametime, i Yahoo!"
+"Fa que apareguen finestres de conversa així que altres usuaris vos comencen a "
+"enviar missatges. Funciona per a AIM, ICQ, XMPP, Sametime, i Yahoo!"
msgid "You feel a disturbance in the force..."
msgstr "Sentireu un certa pertorbació en la força..."
@@ -3669,8 +3676,8 @@ msgid ""
"must be a channel operator to do this."
msgstr ""
"devoice &lt;sobrenom1&gt; [sobrenom2] ...: treu l'estat de veu a algú, "
-"prevenint que parlin al canal si este està moderat (+m). Heu de ser operador "
-"del canal per poder fer això."
+"prevenint que parlin al canal si este està moderat (+m). Heu de ser "
+"operador del canal per poder fer això."
msgid ""
"invite &lt;nick&gt; [room]: Invite someone to join you in the specified "
@@ -3876,17 +3883,18 @@ msgstr "Repte del servidor invàlid"
msgid "Server thinks authentication is complete, but client does not"
msgstr "El servidor creu que s'ha completat l'autenticació, però el client no"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
-msgstr "El servidor requereix autenticació de text sobre un flux no xifrat"
+msgstr ""
+"Podria ser que el servidor requerís autenticació de text sobre un flux no "
+"xifrat"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s requereix autenticació de text sobre un flux no xifrat. Voleu permetre-ho "
-"i continuar amb l'autenticació?"
+"Podria ser que %s requerís autenticació de text sobre un flux no xifrat. "
+"Voleu permetre-ho i continuar amb l'autenticació?"
msgid "SASL authentication failed"
msgstr "Ha fallat l'autenticació SASL"
@@ -3949,7 +3957,7 @@ msgid "The BOSH connection manager terminated your session."
msgstr "El gestor de connexions BOSH ha tancat la connexió."
msgid "No session ID given"
-msgstr "No s'ha indicat cap ID"
+msgstr "No s'ha indicat cap identificador"
msgid "Unsupported version of BOSH protocol"
msgstr "Esta versió del protocol BOSH no està implementada"
@@ -4250,13 +4258,13 @@ msgid "Ping timed out"
msgstr "S'ha esgitat el temps d'espera (ping)"
msgid "Invalid XMPP ID"
-msgstr "ID de l'XMPP invàlid"
+msgstr "L'identificador XMPP no és vàlid"
msgid "Invalid XMPP ID. Username portion must be set."
-msgstr "L'ID de l'XMPP no és vàlid. Cal especificar el nom d'usuari."
+msgstr "L'identificador XMPP no és vàlid. Cal especificar el nom d'usuari."
msgid "Invalid XMPP ID. Domain must be set."
-msgstr "L'ID de l'XMPP no és vàlid. Cal especificar un domini."
+msgstr "L'identificador XMPP no és vàlid. Cal especificar un domini."
# FIXME
msgid "Malformed BOSH URL"
@@ -4475,7 +4483,7 @@ msgstr "No s'ha trobat l'element"
# FIX
msgid "Malformed XMPP ID"
-msgstr "L'ID de l'XMPP està malmés"
+msgstr "L'identificador XMPP està malmés"
msgid "Not Acceptable"
msgstr "No és acceptable"
@@ -4553,7 +4561,7 @@ msgid "Improper Addressing"
msgstr "Adreçament incorrecte"
msgid "Invalid ID"
-msgstr "ID invàlid"
+msgstr "L'identificador no és vàlid"
msgid "Invalid Namespace"
msgstr "Espai de noms invàlid"
@@ -4834,7 +4842,7 @@ msgid "XMPP Version Mismatch"
msgstr "Les versions del XMPP no coincideixen"
msgid "XMPP stream missing ID"
-msgstr "Manca l'ID del fluxe XMPP"
+msgstr "Manca l'identificador del fluxe XMPP"
msgid "XML Parse error"
msgstr "Error en l'anàlisi de l'XML"
@@ -5488,7 +5496,8 @@ msgstr "No hi ha text blocat per este compte."
#, c-format
msgid ""
"MSN servers are currently blocking the following regular expressions:<br/>%s"
-msgstr "Actualment, servidors MSN bloquen estes expressions regulars:<br/>%s"
+msgstr ""
+"Actualment, servidors MSN bloquen estes expressions regulars:<br/>%s"
msgid "This account does not have email enabled."
msgstr "Este compte no té el correu habilitat."
@@ -5984,8 +5993,8 @@ msgstr "El PIN no és vàlid. Només pot contindre dígits [0-9]."
msgid "The two PINs you entered do not match."
msgstr "Els dos PIN que heu introduït no coincideixen."
-msgid "The name you entered is invalid."
-msgstr "El nom que heu introduït no és vàlid."
+msgid "The Display Name you entered is invalid."
+msgstr "El nom d'usuari que heu introduït no és vàlid."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -6007,9 +6016,8 @@ msgstr ""
"Encara no s'ha pogut recuperar la informació del vostre perfil. Torneu-ho a "
"intentar més tard."
-#, fuzzy
msgid "Your UID"
-msgstr "El vostre MXitID"
+msgstr "El vostre UID"
#. pin
#. pin (required)
@@ -6079,16 +6087,12 @@ msgstr "No s'ha pogut connectar al servidor MXit. Comproveu la configuració."
msgid "Connecting..."
msgstr "S'està connectant..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "El nom que heu introduït no és vàlid."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "La llargada del PIN que heu introduït no és vàlida [4-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "Identificador MXit"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6120,13 +6124,13 @@ msgstr "La vostra sessió ha expirat. Torneu-ho a intentar més tard."
msgid "Invalid country selected. Please try again."
msgstr "El país seleccionat no és vàlid. Intenteu-ho de nou."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "El nom d'usuari no està registrat, cal que primer el registreu."
+msgstr ""
+"L'identificador MXit que heu entrat no està registrat, cal que primer el "
+"registreu."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Este nom d'usuari ja està registrat, escolliu-ne un altre."
+msgstr "Este identificador MXit ja està registrat, escolliu-ne un altre."
msgid "Internal error. Please try again later."
msgstr "S'ha produït un error intern. Torneu-ho a provar més tard."
@@ -6171,9 +6175,8 @@ msgstr "Missatge de rebuig"
msgid "Hidden Number"
msgstr "Nombre ocult"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "El vostre MXitID"
+msgstr "El vostre identificador MXit..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6187,26 +6190,21 @@ msgid "Enable splash-screen popup"
msgstr "Habilita la pantalla de presentació emergent"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Vos han fet fora: (%s)"
+msgstr "Vos han fet fora d'este MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "bufetejat"
+msgstr "ha estat fet fora"
-#, fuzzy
msgid "_Room Name:"
-msgstr "_Sala:"
+msgstr "Nom de la _Sala:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Teniu correu!"
+msgstr "Heu convidat"
-#, fuzzy
msgid "Last Online"
-msgstr "En línia"
+msgstr "Darrer cop en línia"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -6478,8 +6476,8 @@ msgstr "Gestor d'URL myim"
msgid "No suitable MySpaceIM account could be found to open this myim URL."
msgstr ""
-"No s'ha pogut trobar cap compte adequat a MySpaceIM per poder obrir este URL "
-"myim."
+"No s'ha pogut trobar cap compte adequat a MySpaceIM per poder obrir este "
+"URL myim."
msgid "Enable the proper MySpaceIM account and try again."
msgstr "Habiliteu el compte MySpaceIM adequat i proveu-ho de nou."
@@ -6773,7 +6771,8 @@ msgid ""
"This evaluation version does not allow more than ten users to log in at one "
"time"
msgstr ""
-"Esta versió d'avaluació no permet que entren més de deu usuaris a la vegada"
+"Esta versió d'avaluació no permet que entren més de deu usuaris a la "
+"vegada"
msgid "The user is either offline or you are blocked"
msgstr "L'usuari està fora de línia o bé esteu blocat"
@@ -6789,8 +6788,8 @@ msgstr "No s'ha pogut entrar: %s"
#, c-format
msgid "Unable to send message. Could not get details for user (%s)."
msgstr ""
-"No s'ha pogut enviar el missatge. No s'han pogut obtindre detalls de "
-"l'usuari (%s)."
+"No s'ha pogut enviar el missatge. No s'han pogut obtindre detalls de l'usuari "
+"(%s)."
#, c-format
msgid "Unable to add %s to your buddy list (%s)."
@@ -6808,8 +6807,8 @@ msgstr "No s'ha pogut convidar l'usuari (%s)."
#, c-format
msgid "Unable to send message to %s. Could not create the conference (%s)."
msgstr ""
-"No s'ha pogut enviar el missatge a %s. No s'ha pogut crear la conferència "
-"(%s)."
+"No s'ha pogut enviar el missatge a %s. No s'ha pogut crear la conferència (%"
+"s)."
#, c-format
msgid "Unable to send message. Could not create the conference (%s)."
@@ -6855,8 +6854,8 @@ msgstr "No s'ha pogut suprimir %s de la llista de privadesa (%s)."
#, c-format
msgid "Unable to change server side privacy settings (%s)."
msgstr ""
-"No s'han pogut canviar els paràmetres de privadesa en la part del servidor "
-"(%s)."
+"No s'han pogut canviar els paràmetres de privadesa en la part del servidor (%"
+"s)."
#, c-format
msgid "Unable to create conference (%s)."
@@ -6877,7 +6876,7 @@ msgid "Mailstop"
msgstr "Oficina de correu electrònic"
msgid "User ID"
-msgstr "ID de l'usuari"
+msgstr "Identificador de l'usuari"
#. tag = _("DN");
#. value = nm_user_record_get_dn(user_record);
@@ -7197,8 +7196,8 @@ msgid ""
"%s tried to send you a %s file, but we only allow files up to %s over Direct "
"IM. Try using file transfer instead.\n"
msgstr ""
-"%s vos ha intentat enviar un fitxer %s, però ara mateix només permetem "
-"enviar fitxers de fins a %s a través de MI directa. Proveu-ho fent servir la "
+"%s vos ha intentat enviar un fitxer %s, però ara mateix només permetem enviar "
+"fitxers de fins a %s a través de MI directa. Proveu-ho fent servir la "
"transferència de fitxers.\n"
# FIXME
@@ -7222,8 +7221,9 @@ msgid ""
"(There was an error receiving this message. Either you and %s have "
"different encodings selected, or %s has a buggy client.)"
msgstr ""
-"(S'ha produït un error en rebre este missatge. És molt possible que %s empri "
-"una codificació diferent a la vostra, o que %s tinga un client defectuós)"
+"(S'ha produït un error en rebre este missatge. És molt possible que %s "
+"empri una codificació diferent a la vostra, o que %s tinga un client "
+"defectuós)"
#. Label
msgid "Buddy Icon"
@@ -7358,9 +7358,9 @@ msgid ""
"a valid email address, or start with a letter and contain only letters, "
"numbers and spaces, or contain only numbers."
msgstr ""
-"No s'ha pogut entrar com a %s perquè este nom d'usuari no és vàlid. Els noms "
-"d'usuari han de ser adreces de correu vàlides, o començar amb una lletra i "
-"contindre només lletres, nombres o espais, o només nombres."
+"No s'ha pogut entrar com a %s perquè este nom d'usuari no és vàlid. Els "
+"noms d'usuari han de ser adreces de correu vàlides, o començar amb una "
+"lletra i contindre només lletres, nombres o espais, o només nombres."
#, c-format
msgid "You may be disconnected shortly. If so, check %s for updates."
@@ -7527,8 +7527,8 @@ msgid ""
"You missed %hu message from %s because the rate limit has been exceeded."
msgid_plural ""
"You missed %hu messages from %s because the rate limit has been exceeded."
-msgstr[0] "S'ha perdut %hu missatge de %s perquè no era vàlid."
-msgstr[1] "S'han perdut %hu missatges de %s perquè no eren vàlids."
+msgstr[0] "S'ha perdut %hu missatge de %s perquè s'ha excedit el límit."
+msgstr[1] "S'han perdut %hu missatges de %s perquè s'ha excedit el límit."
#, c-format
msgid ""
@@ -7895,8 +7895,8 @@ msgid ""
"You can re-request authorization from these buddies by right-clicking on "
"them and selecting \"Re-request Authorization.\""
msgstr ""
-"Podeu tornar a demanar l'autorització d'estos amics fent-hi clic a sobre amb "
-"el botó dret del ratolí, i seleccionant «Torna a demanar l'autorització»."
+"Podeu tornar a demanar l'autorització d'estos amics fent-hi clic a sobre "
+"amb el botó dret del ratolí, i seleccionant «Torna a demanar l'autorització»."
msgid "Find Buddy by Email"
msgstr "Troba un amic per l'adreça de correu"
@@ -7988,10 +7988,10 @@ msgid "Invalid SNAC"
msgstr "SNAC invàlid"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "S'ha excedit el límit de velocitat del servidor"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "S'ha excedit el límit de velocitat del client"
msgid "Service unavailable"
msgstr "Servei no disponible"
@@ -8027,7 +8027,7 @@ msgid "Insufficient rights"
msgstr "Drets insuficients"
msgid "In local permit/deny"
-msgstr "En la llista de permès/denegat local"
+msgstr "En la llista de permés/denegat local"
msgid "Warning level too high (sender)"
msgstr "Nivell d'avís massa alt (remitent)"
@@ -8051,7 +8051,7 @@ msgid "Queue full"
msgstr "Cua plena"
msgid "Not while on AOL"
-msgstr "No es pot fer mentre estigui a AOL"
+msgstr "No es pot fer mentre estiga a AOL"
msgid "Aquarius"
msgstr "Aquari"
@@ -8309,10 +8309,10 @@ msgid "Message: %s"
msgstr "Missatge: %s"
msgid "ID: "
-msgstr "ID: "
+msgstr "Identificador: "
msgid "Group ID"
-msgstr "ID del Grup"
+msgstr "Identificador del Grup"
msgid "QQ Qun"
msgstr "QQ Qun"
@@ -8429,8 +8429,7 @@ msgstr "No s'ha pogut entrar al Qun %u, administrat per %u"
#, c-format
msgid "<b>Joining Qun %u is approved by admin %u for %s</b>"
-msgstr ""
-"<b>L'administrador %2$u vos ha permés unir-vos al Qun %1$u per %3$s</b>"
+msgstr "<b>L'administrador %2$u vos ha permés unir-vos al Qun %1$u per %3$s</b>"
#, c-format
msgid "<b>Removed buddy %u.</b>"
@@ -8560,8 +8559,7 @@ msgstr "i més, per favor feu-m'ho saber... gràcies!!!))"
msgid "<p><i>And, all the boys in the backroom...</i><br>\n"
msgstr "<p><i>I tothom que ho ha fet possible...<i><br>\n"
-#, fuzzy
-msgid "<i>Feel free to join us!</i> :)"
+msgid "<i>Feel free to join vos!</i> :)"
msgstr "<i>No dubteu a col·laborar amb nosaltres!</i> :)"
#, c-format
@@ -8782,7 +8780,7 @@ msgstr "<b>Títol del grup:</b> %s<br>"
#, c-format
msgid "<b>Notes Group ID:</b> %s<br>"
-msgstr "<b>ID del grup Notes:</b> %s<br>"
+msgstr "<b>Identificador del grup Notes:</b> %s<br>"
#, c-format
msgid "Info for Group %s"
@@ -8944,10 +8942,10 @@ msgid "User Name"
msgstr "Nom d'usuari"
msgid "Sametime ID"
-msgstr "ID de Sametime"
+msgstr "Identificador de Sametime"
msgid "An ambiguous user ID was entered"
-msgstr "S'ha introduït un ID d'usuari ambigu"
+msgstr "S'ha introduït un identificador d'usuari ambigu"
#, c-format
msgid ""
@@ -9881,7 +9879,8 @@ msgid "topic [&lt;new topic&gt;]: View or change the topic"
msgstr "topic [&lt;tema nou&gt;]: mostra o canvia el tema"
msgid "join &lt;channel&gt; [&lt;password&gt;]: Join a chat on this network"
-msgstr "join &lt;canal&gt; [&lt;contrasenya&gt;]: entra en un xat d'esta xarxa"
+msgstr ""
+"join &lt;canal&gt; [&lt;contrasenya&gt;]: entra en un xat d'esta xarxa"
msgid "list: List channels on this network"
msgstr "list: llista els canals en esta xarxa"
@@ -10242,7 +10241,7 @@ msgid "doodle: Request user to start a Doodle session"
msgstr "doodle: fa una petició a l'usuari per iniciar una sessió Doodle"
msgid "Yahoo ID..."
-msgstr "ID de Yahoo..."
+msgstr "Identificador del Yahoo..."
#. *< type
#. *< ui_requirement
@@ -10274,15 +10273,15 @@ msgstr "Característiques locals de la sala de xat"
msgid "Ignore conference and chatroom invitations"
msgstr "Bloca invitacions a conferències i sales de xat"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Empra un compte per al servidor intermediari per a connexions SSL"
+msgstr ""
+"Empra un compte per al servidor intermediari per a connexions HTTP i HTTPS"
msgid "Chat room list URL"
msgstr "URL de la llista de sales de xat"
msgid "Yahoo JAPAN ID..."
-msgstr "ID de Yahoo del Japó..."
+msgstr "Identificador de Yahoo del Japó..."
#. *< type
#. *< ui_requirement
@@ -10300,8 +10299,8 @@ msgstr "Connector per al protocol Yahoo! del Japó"
#, c-format
msgid "%s has sent you a webcam invite, which is not yet supported."
msgstr ""
-"%s vos ha enviat una invitació a la seua càmera web, però això encara no "
-"està implementat."
+"%s vos ha enviat una invitació a la seua càmera web, però això encara no està "
+"implementat."
msgid "Your SMS was not delivered"
msgstr "No s'ha enviat l'SMS"
@@ -10318,15 +10317,14 @@ msgid ""
"%s has (retroactively) denied your request to add them to your list for the "
"following reason: %s."
msgstr ""
-"%s vos ha denegat (retroactivament) la petició d'afegir-lo a la vostra "
-"llista pel següent motiu:\n"
+"%s vos ha denegat (retroactivament) la petició d'afegir-lo a la vostra llista "
+"pel següent motiu:\n"
"%s"
#, c-format
msgid "%s has (retroactively) denied your request to add them to your list."
msgstr ""
-"%s vos ha denegat (retroactivament) la petició d'afegir-lo a la vostra "
-"llista."
+"%s vos ha denegat (retroactivament) la petició d'afegir-lo a la vostra llista."
msgid "Add buddy rejected"
msgstr "S'ha rebutjat afegir l'amic"
@@ -10495,13 +10493,13 @@ msgid "Start Doodling"
msgstr "Comença a dibuixar"
msgid "Select the ID you want to activate"
-msgstr "Seleccioneu l'ID que vulgueu activar"
+msgstr "Seleccioneu l'identificador que vulgueu activar"
msgid "Join whom in chat?"
msgstr "A qui vos voleu unir al xat?"
msgid "Activate ID..."
-msgstr "Activa l'ID..."
+msgstr "Activa l'identificador..."
msgid "Join User in Chat..."
msgstr "Entra a un xat d'un usuari..."
@@ -10555,10 +10553,11 @@ msgid ""
"If you wish to view this profile, you will need to visit this link in your "
"web browser:"
msgstr ""
-"Si voleu veure este perfil, haureu de visitar este enllaç amb el navegador:"
+"Si voleu veure este perfil, haureu de visitar este enllaç amb el "
+"navegador:"
msgid "Yahoo! ID"
-msgstr "ID de Yahoo!"
+msgstr "Identificador de Yahoo!"
msgid "Hobbies"
msgstr "Aficions"
@@ -10597,9 +10596,9 @@ msgid ""
"does not exist; however, Yahoo! sometimes does fail to find a user's "
"profile. If you know that the user exists, please try again later."
msgstr ""
-"No s'ha pogut obtindre el perfil de l'usuari. El més segur és que l'usuari "
-"no existisca, tot i que a vegades Yahoo! no pot trobar els perfils d'usuari. "
-"Si sabeu del cert que l'usuari existeix, torneu-ho a intentar més tard."
+"No s'ha pogut obtindre el perfil de l'usuari. El més segur és que l'usuari no "
+"existisca, tot i que a vegades Yahoo! no pot trobar els perfils d'usuari. Si "
+"sabeu del cert que l'usuari existeix, torneu-ho a intentar més tard."
msgid "The user's profile is empty."
msgstr "El perfil d'usuari està buit."
@@ -10627,8 +10626,8 @@ msgid ""
"Unknown error. You may need to logout and wait five minutes before being "
"able to rejoin a chatroom"
msgstr ""
-"S'ha produït un error desconegut. Potser caldrà que eixiu i espereu uns cinc "
-"minuts abans d'intentar tornar a entrar a la sala de xat"
+"S'ha produït un error desconegut. Potser caldrà que eixiu i espereu uns "
+"cinc minuts abans d'intentar tornar a entrar a la sala de xat"
#, c-format
msgid "You are now chatting in %s."
@@ -10708,11 +10707,13 @@ msgstr ""
msgid "inst &lt;instance&gt;: Set the instance to be used on this class"
msgstr ""
-"inst &lt;instància&gt;: especifica la instància a fer servir en esta classe"
+"inst &lt;instància&gt;: especifica la instància a fer servir en esta "
+"classe"
msgid "topic &lt;instance&gt;: Set the instance to be used on this class"
msgstr ""
-"topic &lt;instància&gt;: especifica la instància a fer servir en esta classe"
+"topic &lt;instància&gt;: especifica la instància a fer servir en esta "
+"classe"
msgid "sub &lt;class&gt; &lt;instance&gt; &lt;recipient&gt;: Join a new chat"
msgstr ""
@@ -11198,8 +11199,8 @@ msgstr ""
"voleu que el %s es connecte amb més comptes de missatgeria instantània (MI), "
"torneu a prémer <b>Afig</b> fins a configurar-los tots.\n"
"\n"
-"Podeu tornar a esta finestra per afegir, editar o suprimir comptes, a partir "
-"del menú <b>Comptes->Gestiona els comptes</b> a finestra de la llista "
+"Podeu tornar a esta finestra per afegir, editar o suprimir comptes, a "
+"partir del menú <b>Comptes->Gestiona els comptes</b> a finestra de la llista "
"d'amics."
#. Buddy List
@@ -11335,8 +11336,8 @@ msgid ""
"choosing 'Expand' from the contact's context menu"
msgstr ""
"En fusionar estos contactes fareu que compartisquen una mateixa entrada en "
-"la llista d'amics i en la finestra de conversa. Més avant els podreu separar "
-"amb l'opció 'Expandeix' del menú contextual del contacte."
+"la llista d'amics i en la finestra de conversa. Més avant els podreu "
+"separar amb l'opció 'Expandeix' del menú contextual del contacte."
msgid "Please update the necessary fields."
msgstr "Actualitzeu els camps necessaris."
@@ -12493,8 +12494,8 @@ msgid ""
"to multiple messaging services at once. %s is written in C using GTK+. %s "
"is released, and may be modified and redistributed, under the terms of the "
"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s. There is no warranty for %s.<BR><BR>"
msgstr ""
"El %s és un client de missatgeria basat en libpurple que permet connectar-"
"vos a diferents serveis de missatgeria instantània al mateix temps. El %s "
@@ -12527,11 +12528,11 @@ msgid ""
"<br/>"
msgstr ""
"<font size=\"4\"><b>Ajuda d'altres usuaris del Pidgin</b>:</font> <a href="
-"\"mailto:support@pidgin.im\">support@pidgin.im</a><br/>Esta és una llista de "
-"correu <b>pública</b>. (<a href=\"http://pidgin.im/pipermail/support/"
+"\"mailto:support@pidgin.im\">support@pidgin.im</a><br/>Esta és una llista "
+"de correu <b>pública</b>. (<a href=\"http://pidgin.im/pipermail/support/"
"\">arxiu</a>)<br/>No vos podem ajudar amb connectors d'altres proveïdors.<br/"
-">En esta llista s'hi empra principalment l'<b>anglés</b>. Podeu escriure-hi "
-"en un altre idioma, però és possible que les respostes no siguen de gaire "
+">En esta llista s'hi empra principalment l'<b>anglés</b>. Podeu escriure-"
+"hi en un altre idioma, però és possible que les respostes no siguen de gaire "
"ajuda.<br/>"
#, c-format
@@ -12933,8 +12934,8 @@ msgid ""
"This smiley is disabled because a custom smiley exists for this shortcut:\n"
" %s"
msgstr ""
-"Esta emoticona està inhabilitada perquè hi ha una emoticona personalitzada "
-"per esta drecera:\n"
+"Esta emoticona està inhabilitada perquè hi ha una emoticona "
+"personalitzada per esta drecera:\n"
" %s"
msgid "Smile!"
@@ -13057,16 +13058,16 @@ msgstr ""
#, c-format
msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
msgstr ""
"Esteu segur que voleu suprimir el registre de la conversa a %s iniciada a "
"les %s?"
#, c-format
msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
msgstr ""
"Esteu segur que voleu suprimir permanentment el registre del sistema iniciat "
"a les %s?"
@@ -13172,15 +13173,14 @@ msgstr ""
#, c-format
msgid "Exiting because another libpurple client is already running.\n"
msgstr ""
-"Ara s'eixirà atès que ja hi ha un altre client del libpurple executant-se.\n"
+"Ara s'eixirà atès que ja hi ha un altre client del libpurple executant-"
+"se.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Medi"
+msgstr "_Medi"
-#, fuzzy
msgid "_Hangup"
-msgstr "Penja"
+msgstr "_Penja"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -13962,8 +13962,7 @@ msgstr "Estat per a %s"
msgid ""
"A custom smiley for '%s' already exists. Please use a different shortcut."
msgstr ""
-"Ja hi ha una emoticona personalitzada per a «%s». Indiqueu-ne una de "
-"diferent."
+"Ja hi ha una emoticona personalitzada per a «%s». Indiqueu-ne una de diferent."
msgid "Custom Smiley"
msgstr "Emoticona personalitzada"
@@ -14043,8 +14042,8 @@ msgid ""
"You can send this image as a file transfer, embed it into this message, or "
"use it as the buddy icon for this user."
msgstr ""
-"Podeu enviar esta imatge com una transferència de fitxer, incrustar-la en el "
-"missatge, o emprar-la com a icona d'amic per a este usuari."
+"Podeu enviar esta imatge com una transferència de fitxer, incrustar-la en "
+"el missatge, o emprar-la com a icona d'amic per a este usuari."
msgid "Set as buddy icon"
msgstr "Estableix com a icona de l'amic"
@@ -14062,15 +14061,15 @@ msgid ""
"You can send this image as a file transfer, or use it as the buddy icon for "
"this user."
msgstr ""
-"Podeu enviar esta imatge com una transferència de fitxer, o emprar-la com a "
-"icona d'amic per a este usuari."
+"Podeu enviar esta imatge com una transferència de fitxer, o emprar-la com "
+"a icona d'amic per a este usuari."
msgid ""
"You can insert this image into this message, or use it as the buddy icon for "
"this user"
msgstr ""
-"Podeu incrustar esta imatge en el missatge o utilitzar-la com a icona per a "
-"este usuari."
+"Podeu incrustar esta imatge en el missatge o utilitzar-la com a icona per "
+"a este usuari."
#. I don't know if we really want to do anything here. Most of
#. * the desktop item types are crap like "MIME Type" (I have no
@@ -15267,8 +15266,7 @@ msgstr "_Transparència de la finestra de la llista d'amics"
msgid "Remove Buddy List window transparency on focus"
msgstr ""
-"Treu la transparència de la finestra de la llista d'amics en obtindre el "
-"focus"
+"Treu la transparència de la finestra de la llista d'amics en obtindre el focus"
#. *< type
#. *< ui_requirement
@@ -15292,8 +15290,8 @@ msgid ""
"\n"
"* Note: This plugin requires Win2000 or greater."
msgstr ""
-"Este connector habilita la transparència variables en finestres de conversa, "
-"i la llista d'amics.\n"
+"Este connector habilita la transparència variables en finestres de "
+"conversa, i la llista d'amics.\n"
"\n"
"* Nota: este connector requereix Windows 2000 o superior."
@@ -15423,13 +15421,13 @@ msgstr ""
#, no-c-format
msgid ""
"Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
"S'ha produït un error en instal·lar el corrector ortogràfic ($R3).$\\rSi "
"falla en reintentar-ho, podeu seguir les instruccions d'instal·lació manual "
-"d'ací: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"d'ací: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
#. Installer Subsection Text
msgid "GTK+ Runtime (required if not present)"
@@ -15506,6 +15504,9 @@ msgstr "Visita la pàgina web de Pidgin per Windows"
msgid "You do not have permission to uninstall this application."
msgstr "No tens permís per desinstal.lar esta aplicació."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "El nom que heu introduït no és vàlid."
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "El certificat encara no és vàlid."
@@ -16323,7 +16324,7 @@ msgstr "No tens permís per desinstal.lar esta aplicació."
#~ msgid "Could not open %s for writing!"
#~ msgstr "No s'ha pogut obrir %s per a escriure-hi."
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Ha fallat la transferència de fitxers. Probablement s'ha cancel·lat a "
#~ "l'altra banda."
@@ -17302,8 +17303,8 @@ msgstr "No tens permís per desinstal.lar esta aplicació."
#~ "Server requires TLS/SSL for login. Select \"Use TLS if available\" in "
#~ "account properties"
#~ msgstr ""
-#~ "El servidor requereix TLS/SSL per a entrar. Seleccioneu «Empra TLS si "
-#~ "està disponible» en les propietats del compte"
+#~ "El servidor requereix TLS/SSL per a entrar. Seleccioneu «Empra TLS si està "
+#~ "disponible» en les propietats del compte"
#~ msgid "Use TLS if available"
#~ msgstr "Empra TLS si està disponible"
diff --git a/po/cs.po b/po/cs.po
index 443ceea9a7..88f8fea6ca 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: pidgin VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-05-26 18:44+0100\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-01 18:18+0100\n"
"Last-Translator: David Vachulka <david@konstrukce-cad.com>\n"
"Language-Team: Czech <cs@li.org>\n"
"Language: cs\n"
@@ -63,9 +63,8 @@ msgstr ""
msgid "Error"
msgstr "Chyba"
-#, fuzzy
msgid "Account was not modified"
-msgstr "Účet nebyl přidán"
+msgstr "Účet nebyl upraven"
msgid "Account was not added"
msgstr "Účet nebyl přidán"
@@ -75,11 +74,11 @@ msgstr "Jméno uživatele účtu nesmí být prázdné."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "Protokol účtu nemůže být změněn, když je připojen k serveru."
msgid ""
"The account's username cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "Jméno uživatele účtu nemůže být změněno, když je připojen k serveru."
msgid "New mail notifications"
msgstr "Upozornění na nové zprávy"
@@ -794,7 +793,7 @@ msgstr "Zastavit"
msgid "Waiting for transfer to begin"
msgstr "Čekám na začátek přenosu"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Zrušeno"
msgid "Failed"
@@ -1680,7 +1679,7 @@ msgstr ""
msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
-msgstr ""
+msgstr "Certifikát je neplatný. Zkontrolujte datum a čas počítače."
msgid "The certificate has expired and should not be considered valid."
msgstr "Certifikát vypršel a neměl by být považován za platný."
@@ -3818,17 +3817,16 @@ msgstr "Neplatná výzva od serveru"
msgid "Server thinks authentication is complete, but client does not"
msgstr "Server považuje ověření za kompletní, ale klient ne"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
-msgstr "Server vyžaduje textovou autentizaci v nešifrovaném proudu"
+msgstr "Server může vyžadovat textovou autentizaci v nešifrovaném proudu"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s vyžaduje textovou autentizaci přes nešifrované spojení. Povolit to a "
-"pokračovat v autentizaci?"
+"%s může vyžadovat textovou autentizaci přes nešifrované spojení. Povolit to "
+"a pokračovat v autentizaci?"
msgid "SASL authentication failed"
msgstr "SASL autentizace selhala"
@@ -5882,8 +5880,8 @@ msgstr "PIN není platný. Může obsahovat jen čísla [0-9]."
msgid "The two PINs you entered do not match."
msgstr "PINy nesouhlasí."
-msgid "The name you entered is invalid."
-msgstr "Zadaný jméno není platné"
+msgid "The Display Name you entered is invalid."
+msgstr "Zadaný jméno pro zobrazení není platné"
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5901,9 +5899,8 @@ msgstr "Profil"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "Informace z profilu nebyly získány, zkuste to prosím později."
-#, fuzzy
msgid "Your UID"
-msgstr "Tvoje MXitId"
+msgstr "Tvoje UID"
#. pin
#. pin (required)
@@ -5971,16 +5968,12 @@ msgstr "Nemohu se připojit k MXit serveru. Zkontrolujte nastavení."
msgid "Connecting..."
msgstr "Připojování..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Zadaný jméno není platné"
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Zadaný PIN má neplatnou délku [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6008,13 +6001,11 @@ msgstr "Sezení vypršelo, zkuste to prosím později."
msgid "Invalid country selected. Please try again."
msgstr "Vybrána neplatná země, zkuste to prosím později."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "Uživatelské jméno není registrováno. Nejdřív se registrujte."
+msgstr "MXit ID není registrováno. Nejdřív se registrujte."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Uživatelské jméno už je registrované, zkuste jiné."
+msgstr "MXit ID už je registrované, zkuste jiné."
msgid "Internal error. Please try again later."
msgstr "Chyba. Zkuste to prosím později"
@@ -6058,9 +6049,8 @@ msgstr "Zamítnutí zprávy"
msgid "Hidden Number"
msgstr "Skryté číslo"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Tvoje MXitId"
+msgstr "Tvoje MXit ID..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6074,26 +6064,21 @@ msgid "Enable splash-screen popup"
msgstr "Povolit zobrazení spouštěcí obrazovky"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Byl jste vykopnut: (%s)"
+msgstr "Byl jste vykopnut z MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "Špatný lístek"
+msgstr "byl vykopnut"
-#, fuzzy
msgid "_Room Name:"
msgstr "_Místnost:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Přišla vám pošta!"
+msgstr "Přišlo vám pozvání"
-#, fuzzy
msgid "Last Online"
-msgstr "Připojen"
+msgstr "Naposledy připojen"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7865,10 +7850,10 @@ msgid "Invalid SNAC"
msgstr "Neplatné SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "Překročen limit poměru serveru"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "Překročen limit poměru klienta"
msgid "Service unavailable"
msgstr "Služba nedostupná"
@@ -10123,9 +10108,8 @@ msgstr "Locale místnosti chatu"
msgid "Ignore conference and chatroom invitations"
msgstr "Ignorovat pozvání do konferencí a místností chatu"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Použít proxy pro SSL připojení"
+msgstr "Použít proxy účtu pro HTTP a HTTPS připojení"
msgid "Chat room list URL"
msgstr "URL seznamu místností chatu"
@@ -12746,7 +12730,7 @@ msgstr ""
" %s"
msgid "Smile!"
-msgstr "Úsměv!"
+msgstr "Smajlík!"
msgid "_Manage custom smileys"
msgstr "_Spravovat uživatelské smajlíky"
@@ -12845,7 +12829,7 @@ msgid "_Smile!"
msgstr "Ú_směv!"
msgid "_Attention!"
-msgstr "Vaše pozornost!"
+msgstr "Vyžádat pozornost!"
msgid "Log Deletion Failed"
msgstr "Selhalo mazání záznamu"
@@ -12976,13 +12960,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Exiting because another libpurple client is already running.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Multimédia"
+msgstr "_Média"
-#, fuzzy
msgid "_Hangup"
-msgstr "Zavěsit"
+msgstr "_Zavěsit"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -13043,7 +13025,7 @@ msgid "Dismiss"
msgstr "Odmítnout"
msgid "<span weight=\"bold\" size=\"larger\">You have pounced!</span>"
-msgstr "<span weight=\"bold\" size=\"larger\">Jste sledován!</span>"
+msgstr "<span weight=\"bold\" size=\"larger\">Sledování</span>"
msgid "The following plugins will be unloaded."
msgstr "Následující zásuvné moduly budou odebrány."
@@ -15256,6 +15238,9 @@ msgstr "Navštívit Pidgin Web Page"
msgid "You do not have permission to uninstall this application."
msgstr "Nemáte oprávnění k odinstalaci této aplikace."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "Zadaný jméno není platné"
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "Certifikát je neplatný."
@@ -16057,7 +16042,7 @@ msgstr "Nemáte oprávnění k odinstalaci této aplikace."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Nemohu otevřít %s pro zápis!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Přenos souboru selhal; druhá strana jej pravděpodobně přerušila."
#~ msgid "Could not connect for transfer."
diff --git a/po/da.po b/po/da.po
index 582e77a1e7..188ead28b1 100644
--- a/po/da.po
+++ b/po/da.po
@@ -812,7 +812,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "Venter på at overførsel skal starte"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Annulleret"
msgid "Failed"
@@ -16489,7 +16489,7 @@ msgstr "Du har ikke tilladelse til at afinstallere dette program."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Kunne ikke åbne %s til skrivning!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Filoverførsel fejlede - den anden side har sikkert afbrudt."
#~ msgid "Could not connect for transfer."
diff --git a/po/de.po b/po/de.po
index a95400c2d8..7bbd348a6b 100644
--- a/po/de.po
+++ b/po/de.po
@@ -11,14 +11,14 @@ msgid ""
msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-07-20 18:52+0200\n"
+"POT-Creation-Date: 2010-09-02 19:45+0200\n"
+"PO-Revision-Date: 2010-09-06 10:01+0200\n"
"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
"Language-Team: Deutsch <de@li.org>\n"
-"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Translators may want to transliterate the name.
@@ -813,7 +813,7 @@ msgstr "Stopp"
msgid "Waiting for transfer to begin"
msgstr "Warte auf den Beginn der Dateiübertragung"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Abgebrochen"
msgid "Failed"
@@ -4772,11 +4772,17 @@ msgstr "XMPP-Protokoll-Plugin"
msgid "Domain"
msgstr "Domain"
-msgid "Require SSL/TLS"
-msgstr "SSL/TLS voraussetzen"
+msgid "Require encryption"
+msgstr "Verschlüsselung fordern"
+
+msgid "Use encryption if available"
+msgstr "Verschlüsselung benutzen, wenn verfügbar"
-msgid "Force old (port 5223) SSL"
-msgstr "Erzwinge altes SSL (Port 5223)"
+msgid "Use old-style SSL"
+msgstr "Alte SSL-Methode verwenden"
+
+msgid "Connection security"
+msgstr "Verbindungssicherheit"
msgid "Allow plaintext auth over unencrypted streams"
msgstr "Erlaube Klartext-Authentifikation über einen unverschlüsselten Kanal"
@@ -6002,8 +6008,8 @@ msgstr "Die PIN ist ungültig. Sie sollte nur aus Ziffern [0-9] bestehen."
msgid "The two PINs you entered do not match."
msgstr "Die beiden PINs, die Sie eingegeben haben, stimmen nicht überein."
-msgid "The name you entered is invalid."
-msgstr "Der eingegebene Name ist ungültig."
+msgid "The Display Name you entered is invalid."
+msgstr "Der eingegebene Anzeigename ist ungültig."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -6025,9 +6031,8 @@ msgstr ""
"Ihre Profil-Informationen wurden noch nicht abgerufen. Bitte versuchen Sie "
"es später noch einmal."
-#, fuzzy
msgid "Your UID"
-msgstr "Ihre MXit-ID"
+msgstr "Ihre UID"
#. pin
#. pin (required)
@@ -6099,16 +6104,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Verbinde..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Der eingegebene Name ist ungültig."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Die eingegebene PIN hat eine ungültige Länge [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit-ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6143,16 +6144,15 @@ msgstr ""
msgid "Invalid country selected. Please try again."
msgstr "Ungültiges Land gewählt. Bitte versuchen Sie es noch einmal."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
msgstr ""
-"Benutzername ist nicht registriert. Bitte registrieren Sie Sich zuerst."
+"Die von Ihnen eingegebene MXit-ID ist nicht registriert. Bitte registrieren "
+"Sie Sich zuerst."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
msgstr ""
-"Der Benutzername ist bereits registriert. Bitte wählen Sie einen anderen "
-"Benutzernamen."
+"Die von Ihnen eingegebene MXit-ID ist bereits registriert. Bitte wählen Sie "
+"eine andere."
msgid "Internal error. Please try again later."
msgstr "Internet Fehler. Versuchen Sie es später noch einmal."
@@ -6196,9 +6196,8 @@ msgstr "Ablehnungsnachricht"
msgid "Hidden Number"
msgstr "Versteckte Nummer"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Ihre MXit-ID"
+msgstr "Ihre MXit-ID..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6222,13 +6221,11 @@ msgid "_Room Name:"
msgstr "_Raumname:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Sie haben Post!"
+msgstr "Sie haben eingeladen"
-#, fuzzy
msgid "Last Online"
-msgstr "Online"
+msgstr "Zuletzt online"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -6810,8 +6807,8 @@ msgstr "Anmeldung nicht möglich: %s"
#, c-format
msgid "Unable to send message. Could not get details for user (%s)."
msgstr ""
-"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen "
-"(%s)."
+"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen (%"
+"s)."
#, c-format
msgid "Unable to add %s to your buddy list (%s)."
@@ -6829,8 +6826,8 @@ msgstr "Kann den Benutzer nicht einladen (%s)."
#, c-format
msgid "Unable to send message to %s. Could not create the conference (%s)."
msgstr ""
-"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen "
-"(%s)."
+"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen (%"
+"s)."
#, c-format
msgid "Unable to send message. Could not create the conference (%s)."
@@ -7227,96 +7224,6 @@ msgstr ""
msgid "File %s is %s, which is larger than the maximum size of %s."
msgstr "Datei %s (%s) ist größer als die maximale Größe von %s."
-msgid ""
-"(There was an error receiving this message. The buddy you are speaking with "
-"is probably using a different encoding than expected. If you know what "
-"encoding he is using, you can specify it in the advanced account options for "
-"your AIM/ICQ account.)"
-msgstr ""
-"(Es gab einen Fehler beim Empfangen dieser Nachricht. Der Buddy, mit dem "
-"Sie sich unterhalten benutzt wahrscheinlich eine andere Kodierung als "
-"erwartet. Wenn Sie wissen, welche Kodierung er benutzt, können Sie diese in "
-"den erweiterten Konto-Optionen Ihres AIM/ICQ-Kontos angeben.)"
-
-#, c-format
-msgid ""
-"(There was an error receiving this message. Either you and %s have "
-"different encodings selected, or %s has a buggy client.)"
-msgstr ""
-"(Es gab einen Fehler beim Empfang dieser Nachricht. Entweder haben Sie und "
-"%s unterschiedliche Kodierungen gesetzt oder %s hat einen fehlerhaften "
-"Client.)"
-
-#. Label
-msgid "Buddy Icon"
-msgstr "Buddy-Icon"
-
-msgid "Voice"
-msgstr "Stimme"
-
-msgid "AIM Direct IM"
-msgstr "AIM direkte Nachricht"
-
-msgid "Get File"
-msgstr "Datei abrufen"
-
-msgid "Games"
-msgstr "Spiele"
-
-msgid "ICQ Xtraz"
-msgstr "ICQ Xtraz"
-
-msgid "Add-Ins"
-msgstr "Zusätze"
-
-msgid "Send Buddy List"
-msgstr "Buddy-Liste senden"
-
-msgid "ICQ Direct Connect"
-msgstr "ICQ direkte Verbindung"
-
-msgid "AP User"
-msgstr "AP Benutzer"
-
-msgid "ICQ RTF"
-msgstr "ICQ RTF"
-
-msgid "Nihilist"
-msgstr "Nihilist"
-
-msgid "ICQ Server Relay"
-msgstr "ICQ Server Relay"
-
-msgid "Old ICQ UTF8"
-msgstr "Altes ICQ UTF-8"
-
-msgid "Trillian Encryption"
-msgstr "Trillian-Verschlüsselung"
-
-msgid "ICQ UTF8"
-msgstr "ICQ UTF-8"
-
-msgid "Hiptop"
-msgstr "Hiptop"
-
-msgid "Security Enabled"
-msgstr "Sicherheit aktiviert"
-
-msgid "Video Chat"
-msgstr "Video-Chat"
-
-msgid "iChat AV"
-msgstr "iChat AV"
-
-msgid "Live Video"
-msgstr "Live-Video"
-
-msgid "Camera"
-msgstr "Kamera"
-
-msgid "Screen Sharing"
-msgstr "Gemeinsamer Bildschirm"
-
msgid "Free For Chat"
msgstr "Bereit zum Chatten"
@@ -7347,15 +7254,6 @@ msgstr "Bei der Arbeit"
msgid "At lunch"
msgstr "Zur Mittagspause"
-msgid "IP Address"
-msgstr "IP-Adresse"
-
-msgid "Warning Level"
-msgstr "Warnstufe"
-
-msgid "Buddy Comment"
-msgstr "Buddy-Kommentar"
-
#, c-format
msgid "Unable to connect to authentication server: %s"
msgstr "Verbindung zum Authentifizierungsserver nicht möglich: %s"
@@ -7455,17 +7353,6 @@ msgstr "Passwort gesendet"
msgid "Unable to initialize connection"
msgstr "Kann Verbindung nicht erstellen"
-msgid "Please authorize me so I can add you to my buddy list."
-msgstr ""
-"Bitte autorisieren Sie mich, sodass ich Sie in meine Buddy-Liste aufnehmen "
-"kann."
-
-msgid "No reason given."
-msgstr "Kein Grund angegeben."
-
-msgid "Authorization Denied Message:"
-msgstr "Nachricht für die Ablehnung der Autorisierung:"
-
#, c-format
msgid ""
"The user %u has denied your request to add them to your buddy list for the "
@@ -7476,6 +7363,9 @@ msgstr ""
"Liste hinzufügen zu dürfen, und zwar aus folgendem Grund:\n"
"%s"
+msgid "No reason given."
+msgstr "Kein Grund angegeben."
+
msgid "ICQ authorization denied."
msgstr "ICQ-Autorisierung verweigert."
@@ -7591,60 +7481,13 @@ msgstr[0] ""
msgstr[1] ""
"Sie haben %hu Nachrichten von %s aus unbekannten Gründen nicht erhalten."
-#, c-format
-msgid "User information not available: %s"
-msgstr "Benutzerinformation nicht verfügbar: %s"
-
-msgid "Online Since"
-msgstr "Online seit"
-
-msgid "Member Since"
-msgstr "Mitglied seit"
-
-msgid "Capabilities"
-msgstr "Fähigkeiten"
-
msgid "Your AIM connection may be lost."
msgstr "Ihre AIM-Verbindung könnte unterbrochen sein."
-#. The conversion failed!
-msgid ""
-"[Unable to display a message from this user because it contained invalid "
-"characters.]"
-msgstr ""
-"[Kann die Nachricht von diesem Benutzer nicht anzeigen, da sie ungültige "
-"Zeichen enthält.]"
-
#, c-format
msgid "You have been disconnected from chat room %s."
msgstr "Die Verbindung zum Raum %s wurde unterbrochen."
-msgid "Mobile Phone"
-msgstr "Handynummer"
-
-msgid "Personal Web Page"
-msgstr "Persönliche Webseite"
-
-#. aim_userinfo_t
-#. strip_html_tags
-msgid "Additional Information"
-msgstr "Zusätzliche Informationen"
-
-msgid "Zip Code"
-msgstr "PLZ"
-
-msgid "Work Information"
-msgstr "Information (Arbeit)"
-
-msgid "Division"
-msgstr "Abteilung"
-
-msgid "Position"
-msgstr "Position"
-
-msgid "Web Page"
-msgstr "Webseite"
-
msgid "Pop-Up Message"
msgstr "Pop-Up Nachricht"
@@ -7931,8 +7774,8 @@ msgstr ""
msgid "Change Address To:"
msgstr "Ändere die Adresse zu:"
-msgid "<i>you are not waiting for authorization</i>"
-msgstr "<i>Sie warten derzeit auf keine Autorisierungen</i>"
+msgid "you are not waiting for authorization"
+msgstr "Sie warten derzeit auf keine Autorisierungen"
msgid "You are awaiting authorization from the following buddies"
msgstr "Sie warten auf Autorisierung von den folgenden Buddys"
@@ -7987,9 +7830,6 @@ msgstr "Zeige Buddys, von denen Sie Autorisierung erwarten"
msgid "Search for Buddy by Email Address..."
msgstr "Suche Buddys nach E-Mail-Adresse..."
-msgid "Search for Buddy by Information"
-msgstr "Suche Buddy nach Information"
-
msgid "Use clientLogin"
msgstr "clientLogin benutzen"
@@ -8277,8 +8117,8 @@ msgid "Your request was rejected."
msgstr "Ihre Anfrage wurde abgelehnt."
#, c-format
-msgid "%u requires verification"
-msgstr "%u erfordert Autorisierung"
+msgid "%u requires verification: %s"
+msgstr "%u erfordert Überprüfung: %s"
msgid "Add buddy question"
msgstr "Buddy-Frage hinzufügen"
@@ -8471,8 +8311,8 @@ msgstr "Dem Qun %u, moderiert von admin %u, konnte nicht beigetreten werden"
#, c-format
msgid "<b>Joining Qun %u is approved by admin %u for %s</b>"
msgstr ""
-"<b>Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for "
-"%s</b>"
+"<b>Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for %"
+"s</b>"
#, c-format
msgid "<b>Removed buddy %u.</b>"
@@ -10155,6 +9995,9 @@ msgstr "Videokonferenz"
msgid "Computer"
msgstr "Computer"
+msgid "Mobile Phone"
+msgstr "Handynummer"
+
msgid "PDA"
msgstr "PDA"
@@ -10589,6 +10432,9 @@ msgstr "%s versucht, Ihnen eine Gruppe von %d Dateien zu senden.\n"
msgid "Write Error"
msgstr "Schreibfehler"
+msgid "IP Address"
+msgstr "IP-Adresse"
+
msgid "Yahoo! Japan Profile"
msgstr "Yahoo!-Japan-Profil"
@@ -10630,6 +10476,9 @@ msgstr "Cooler Link 2"
msgid "Cool Link 3"
msgstr "Cooler Link 3"
+msgid "Member Since"
+msgstr "Mitglied seit"
+
msgid "Last Update"
msgstr "Letzte Aktualisierung"
@@ -11256,6 +11105,11 @@ msgstr ""
"Listenfenster zu diesem Dialog zurückkehren und Konten hinzufügen, "
"bearbeiten oder löschen"
+#, c-format
+msgid "%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"
+msgstr ""
+"%s%s%s%s möchte Sie (%s) zu seiner oder ihrer Buddy-Liste hinzufügen%s%s"
+
#. Buddy List
msgid "Background Color"
msgstr "Hintergrundfarbe"
@@ -11515,6 +11369,8 @@ msgstr "Nachricht (optional)"
msgid "Edit User Mood"
msgstr "Benutzerstimmung ändern"
+#. NOTE: Do not set any accelerator to Control+O. It is mapped by
+#. gtk_blist_key_press_cb to "Get User Info" on the selected buddy.
#. Buddies menu
msgid "/_Buddies"
msgstr "/_Buddys"
@@ -12544,8 +12400,8 @@ msgid ""
"to multiple messaging services at once. %s is written in C using GTK+. %s "
"is released, and may be modified and redistributed, under the terms of the "
"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s. There is no warranty for %s.<BR><BR>"
msgstr ""
"%s ist ein Nachrichtendienst, basierend auf libpurple, der die Verbindung zu "
"mehreren Nachrichtendiensten gleichzeitig unterstützt. %s wird in C "
@@ -13117,16 +12973,16 @@ msgstr ""
#, c-format
msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
msgstr ""
"Wollen Sie wirklich den Mitschnitt der Unterhaltung in %s, gestartet am %s, "
"permanent löschen?"
#, c-format
msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
msgstr ""
"Wollen Sie wirklich den Systemmitschnitt, gestartet am %s, permanent löschen?"
@@ -13234,13 +13090,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Medien"
+msgstr "_Medien"
-#, fuzzy
msgid "_Hangup"
-msgstr "Auflegen"
+msgstr "_Auflegen"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -13659,6 +13513,9 @@ msgstr "Relay-Server (TURN)"
msgid "_TURN server:"
msgstr "_TURN-Server:"
+msgid "_UDP Port:"
+msgstr "_UDP-Port:"
+
msgid "Use_rname:"
msgstr "_Benutzername:"
@@ -14154,6 +14011,10 @@ msgstr ""
"<b>Dateigröße:</b> %s\n"
"<b>Bildgröße:</b> %dx%d"
+#. Label
+msgid "Buddy Icon"
+msgstr "Buddy-Icon"
+
#, c-format
msgid "The file '%s' is too large for %s. Please try a smaller image.\n"
msgstr ""
@@ -14239,7 +14100,7 @@ msgstr "keine"
msgid "Small"
msgstr "Klein"
-msgid "Smaller versions of the default smilies"
+msgid "Smaller versions of the default smileys"
msgstr "Kleinere Versionen der Default-Smileys"
msgid "Response Probability:"
@@ -15090,6 +14951,9 @@ msgstr "Operator"
msgid "Half Operator"
msgstr "Half-Operator"
+msgid "Voice"
+msgstr "Stimme"
+
msgid "Authorization dialog"
msgstr "Autorisierungsdialog"
@@ -15279,6 +15143,9 @@ msgstr "G_erät"
msgid "Voice/Video Settings"
msgstr "Sprach-/Video-Einstellungen"
+msgid "Voice and Video Settings"
+msgstr "Sprach- und Video-Einstellungen"
+
#. *< name
#. *< version
msgid "Configure your microphone and webcam."
@@ -15408,7 +15275,7 @@ msgid "This plugin is useful for debugging XMPP servers or clients."
msgstr ""
"Dieses Plugin ist nützlich zur Fehlersuche in XMPP-Servern oder -Clients."
-#. $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue."
+#. $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue." DO NOT translate the CLICK in $_CLICK. It will break the installer.
msgid ""
"$(^Name) is released under the GNU General Public License (GPL). The license "
"is provided here for information purposes only. $_CLICK"
@@ -15471,13 +15338,13 @@ msgstr ""
#, no-c-format
msgid ""
"Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
"Fehler beim Installieren der Rechtschreibkontrolle ($R3).$\\rFalls ein "
"erneuter Versuch fehlschlägt, finden Sie Anweisungen zur manuellen "
-"Installation unter: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"Installation unter: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
#. Installer Subsection Text
msgid "GTK+ Runtime (required if not present)"
@@ -15552,188 +15419,7 @@ msgstr ""
#. Text displayed on Installer Finish Page
msgid "Visit the Pidgin Web Page"
-msgstr "Besuchen Sie die Pidgin Webseite"
+msgstr "Besuchen Sie die Pidgin-Webseite"
msgid "You do not have permission to uninstall this application."
msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren."
-
-#~ msgid "The nick name you entered is invalid."
-#~ msgstr "Der eingegebene Spitzname ist ungültig."
-
-#~ msgid "MXit Login Name"
-#~ msgstr "MXit-Login-Name"
-
-#~ msgid "Nick Name"
-#~ msgstr "Spitzname"
-
-#~ msgid "Your Mobile Number..."
-#~ msgstr "Ihre Handynummer..."
-
-#~ msgid "/Media/_Hangup"
-#~ msgstr "/Medien/_Auflegen"
-
-#~ msgid "The certificate is not valid yet."
-#~ msgstr "Das Zertifikat ist noch nicht gültig."
-
-#~ msgid "Rate to host"
-#~ msgstr "Bewertung zum Host"
-
-#~ msgid "Rate to client"
-#~ msgstr "Bewertung zum Client"
-
-#~ msgid "Unknown reason."
-#~ msgstr "Unbekannter Grund."
-
-#~ msgid "Current Mood"
-#~ msgstr "Momentane Stimmung"
-
-#~ msgid "New Mood"
-#~ msgstr "Neue Stimmung"
-
-#~ msgid "Change your Mood"
-#~ msgstr "Ihre Stimmung ändern"
-
-#~ msgid "How do you feel right now?"
-#~ msgstr "Wie fühlen Sie sich gerade?"
-
-#~ msgid "Change Mood..."
-#~ msgstr "Stimmung ändern..."
-
-#~ msgid "Artist"
-#~ msgstr "Interpret"
-
-#~ msgid "Album"
-#~ msgstr "Album"
-
-#~ msgid "Pager server"
-#~ msgstr "Pager-Server"
-
-#~ msgid "Yahoo Chat server"
-#~ msgstr "Yahoo-Chat-Server"
-
-#~ msgid "Yahoo Chat port"
-#~ msgstr "Yahoo-Chat-Port"
-
-#~ msgid "Orientation"
-#~ msgstr "Ausrichtung"
-
-#~ msgid "The orientation of the tray."
-#~ msgstr "Die Ausrichtung der Kontrollleiste."
-
-#~ msgid "Error creating conference."
-#~ msgstr "Fehler beim Erstellen der Konferenz."
-
-#~ msgid "Unable to bind socket to port: %s"
-#~ msgstr "Kann die Socket nicht an den Port binden: %s"
-
-#~ msgid "Unable to listen on socket: %s"
-#~ msgstr "Lauschen auf Socket nicht möglich: %s"
-
-#~ msgid "%s just sent you a Nudge!"
-#~ msgstr "%s hat Sie gerade angestoßen!"
-
-#~ msgid "Friendly name changes too rapidly"
-#~ msgstr "Benutzernamen werden zu oft geändert"
-
-#~ msgid "This Hotmail account may not be active."
-#~ msgstr "Dieses Hotmail-Konto ist vielleicht nicht aktiv."
-
-#~ msgid "Profile URL"
-#~ msgstr "URL des Profils"
-
-#~ msgid "MSN Protocol Plugin"
-#~ msgstr "MSN-Protokoll-Plugin"
-
-#~ msgid "%s is not a valid group."
-#~ msgstr "%s ist keine gültige Gruppe."
-
-#~ msgid "Unknown error."
-#~ msgstr "Unbekannter Fehler."
-
-#~ msgid "%s on %s (%s)"
-#~ msgstr "%s auf %s (%s)"
-
-#~ msgid "Unable to add user on %s (%s)"
-#~ msgstr "Kann den Benutzer nicht zu %s (%s) hinzufügen"
-
-#~ msgid "Unable to block user on %s (%s)"
-#~ msgstr "Kann den Benutzer nicht für %s (%s) blockieren"
-
-#~ msgid "Unable to permit user on %s (%s)"
-#~ msgstr "Kann den Benutzer nicht für %s (%s) erlauben"
-
-#~ msgid "%s could not be added because your buddy list is full."
-#~ msgstr "%s konnte nicht hinzugefügt werden, da Ihre Buddy-Liste voll ist."
-
-#~ msgid "%s is not a valid passport account."
-#~ msgstr "%s ist kein gültiges Passport-Konto."
-
-#~ msgid "Service Temporarily Unavailable."
-#~ msgstr "Dienst momentan nicht verfügbar."
-
-#~ msgid "Unable to rename group"
-#~ msgstr "Kann die Gruppe nicht umbenennen"
-
-#~ msgid "Unable to delete group"
-#~ msgstr "Kann die Gruppe nicht löschen"
-
-#~ msgid "%s has added you to his or her buddy list."
-#~ msgstr "Der Benutzer %s hat Sie zu seiner Buddy-Liste hinzugefügt."
-
-#~ msgid "%s has removed you from his or her buddy list."
-#~ msgstr "Der Benutzer %s hat Sie von seiner Buddy-Liste gelöscht."
-
-#~ msgid ""
-#~ "<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"http://developer.pidgin.im/wiki/FAQ"
-#~ "\">http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"
-#~ msgstr ""
-#~ "<FONT SIZE=\"4\">FAQ:</FONT> <A HREF=\"http://developer.pidgin.im/wiki/FAQ"
-#~ "\">http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"
-
-#~ msgid ""
-#~ "<FONT SIZE=\"4\">IRC Channel:</FONT> #pidgin on irc.freenode.net<BR><BR>"
-#~ msgstr ""
-#~ "<FONT SIZE=\"4\">IRC-Kanal:</FONT> #pidgin auf irc.freenode.net<BR><BR>"
-
-#~ msgid "<FONT SIZE=\"4\">XMPP MUC:</FONT> devel@conference.pidgin.im<BR><BR>"
-#~ msgstr ""
-#~ "<FONT SIZE=\"4\">XMPP-MUC:</FONT> devel@conference.pidgin.im<BR><BR>"
-
-#~ msgid "Debugging Information"
-#~ msgstr "Debugging-Information"
-
-#~ msgid ""
-#~ "Unrecognized file type\n"
-#~ "\n"
-#~ "Defaulting to PNG."
-#~ msgstr ""
-#~ "Nicht erkannter Dateityp\n"
-#~ "\n"
-#~ "Verwende Standard (PNG)."
-
-#~ msgid ""
-#~ "Error saving image\n"
-#~ "\n"
-#~ "%s"
-#~ msgstr ""
-#~ "Fehler beim Speichern des Bildes\n"
-#~ "\n"
-#~ "%s"
-
-#~ msgid "Failed to open file '%s': %s"
-#~ msgstr "Öffnen der Datei '%s' fehlgeschlagen: %s"
-
-#~ msgid ""
-#~ "Failed to load image '%s': reason not known, probably a corrupt image file"
-#~ msgstr ""
-#~ "Bild '%s' konnte nicht geladen werden: Grund unbekannt, vermutlich eine "
-#~ "korrupte Bilddatei"
-
-#~ msgid "Insert an <iq/> stanza."
-#~ msgstr "Einen <iq/> Block einfügen."
-
-#~ msgid "Insert a <presence/> stanza."
-#~ msgstr "Einen <presence/> Block einfügen."
-
-#~ msgid "Insert a <message/> stanza."
-#~ msgstr "Einen <message/> Block einfügen."
diff --git a/po/dz.po b/po/dz.po
index 774bf7a676..ad95321495 100644
--- a/po/dz.po
+++ b/po/dz.po
@@ -818,7 +818,7 @@ msgstr "གཞི་སྒྲིག"
msgid "Waiting for transfer to begin"
msgstr "གནས་སོར་འགོ་བཙུགས་ནིའི་དོན་ལུ་བསྒུག་དོ།"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ཆ་མེད་བཏང་ཡི།"
msgid "Failed"
@@ -16889,7 +16889,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "བྲིས་ནིའི་དོན་ལུ %s ཁ་ཕྱེ་མ་ཚུགས།"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "ཡིག་སྣོད་གནས་སོར་འཐུས་ཤོར་བྱུང་ནུག ཕྱོགས་གཞན་མི་འདི་ཆ་མེད་བཏང་ཡི།"
#~ msgid "Could not connect for transfer."
diff --git a/po/el.po b/po/el.po
index 91a969f072..8885aac39f 100644
--- a/po/el.po
+++ b/po/el.po
@@ -804,7 +804,7 @@ msgstr "Σταμάτημα"
msgid "Waiting for transfer to begin"
msgstr "Αναμονή έναρξης μεταφοράς"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Ακυρώθηκε"
msgid "Failed"
@@ -16284,7 +16284,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Αδύνατο το άνοιγμα του %s για εγγραφή!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Αποτυχία μεταφοράς αρχείου. Πιθανώς να ακυρώθηκε από την άλλη πλευρά."
diff --git a/po/en_AU.po b/po/en_AU.po
index 38e0ae892f..f84276a34c 100644
--- a/po/en_AU.po
+++ b/po/en_AU.po
@@ -834,8 +834,8 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Waiting for transfer to begin"
-msgid "Canceled"
-msgstr "Canceled"
+msgid "Cancelled"
+msgstr "Cancelled"
msgid "Failed"
msgstr "Failed"
@@ -2128,14 +2128,14 @@ msgstr "File transfer complete"
#, fuzzy, c-format
msgid "You cancelled the transfer of %s"
-msgstr "You canceled the transfer of %s"
+msgstr "You cancelled the transfer of %s"
msgid "File transfer cancelled"
msgstr "File transfer cancelled"
#, fuzzy, c-format
msgid "%s cancelled the transfer of %s"
-msgstr "%s canceled the transfer of %s"
+msgstr "%s cancelled the transfer of %s"
#, fuzzy, c-format
msgid "%s cancelled the file transfer"
@@ -9265,7 +9265,7 @@ msgstr "File Send Failed"
#, fuzzy, c-format
msgid "%d cancelled the transfer of %s"
-msgstr "%s canceled the transfer of %s"
+msgstr "%s cancelled the transfer of %s"
#, fuzzy, c-format
msgid "<b>Group Title:</b> %s<br>"
@@ -9346,7 +9346,7 @@ msgstr "Unable to send message to %s:"
#, fuzzy
msgid "Place Closed"
-msgstr "Canceled"
+msgstr "Cancelled"
msgid "Microphone"
msgstr ""
@@ -17062,8 +17062,8 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Could not open %s for writing!"
-#~ msgid "File transfer failed; other side probably canceled."
-#~ msgstr "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
+#~ msgstr "File transfer failed; other side probably cancelled."
#~ msgid "Could not connect for transfer."
#~ msgstr "Could not connect for transfer."
diff --git a/po/en_CA.po b/po/en_CA.po
index 34774f4ce9..627efef93e 100644
--- a/po/en_CA.po
+++ b/po/en_CA.po
@@ -834,7 +834,7 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Waiting for transfer to begin"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelled"
msgid "Failed"
@@ -17050,7 +17050,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Could not open %s for writing!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "File transfer failed; other side probably cancelled."
#~ msgid "Could not connect for transfer."
diff --git a/po/en_GB.po b/po/en_GB.po
index 78398ab360..61e8fa2139 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -793,7 +793,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "Waiting for transfer to begin"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelled"
msgid "Failed"
diff --git a/po/eo.po b/po/eo.po
index edbe016b65..b66d13e24c 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -766,7 +766,7 @@ msgstr "Haltu"
msgid "Waiting for transfer to begin"
msgstr "Atendante la alŝutoeko"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Rezignita"
msgid "Failed"
diff --git a/po/es.po b/po/es.po
index c1f7cd9c14..0cd7dd45d4 100644
--- a/po/es.po
+++ b/po/es.po
@@ -5,10 +5,10 @@
# Copyright (C) April 2003, JM Pérez Cáncer <jm@cocoloco.dyn.dhs.org>
# Copyright (c) December 2003, Francisco Javier F. Serrador
# <franciscojavier.fernandez.serrador@hispalinux.es>, 2003.
+# Copyright (C) February 2010, Francisco Javier F. Serrador <fserrador@gmail.com>
# Copyright (C) June 2002, April 2003, January 2004, March 2004, September 2004,
-# January 2005, 2006-2008, July 2009, July 2010
+# January 2005, 2006-2008, July 2009, July 2010, August 2010
# Javier Fernández-Sanguino Peña <jfs@debian.org>
-# Copyright (C) February 2010, Francisco Javier F. Serrador <fserrador@gmail.com>
#
# Agradecemos la ayuda de revisión realizada por:
# Nathaniel Case, Santiago Erquicia, Francisco Javier F. Serrador,
@@ -53,8 +53,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 02:07-0400\n"
-"PO-Revision-Date: 2010-07-25 16:41+0200\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-02 23:10+0200\n"
"Last-Translator: Javier Fernández-Sanguino <jfs@debian.org>\n"
"Language-Team: Spanish team <es@li.org>\n"
"Language: \n"
@@ -916,7 +916,7 @@ msgstr "Parar"
msgid "Waiting for transfer to begin"
msgstr "Esperando el comienzo de la transferencia"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelado"
msgid "Failed"
@@ -6088,7 +6088,7 @@ msgstr "El PIN es inválido. Debería sólo consistir dígitos [0-9]."
msgid "The two PINs you entered do not match."
msgstr "Las dos PINes que introdujo no coinciden."
-msgid "The name you entered is invalid."
+msgid "The Display Name you entered is invalid."
msgstr "El nombre que introdujo es inválido."
msgid ""
@@ -6183,9 +6183,6 @@ msgstr ""
msgid "Connecting..."
msgstr "Conectando..."
-msgid "The Display Name you entered is invalid."
-msgstr "El nombre que introdujo es inválido."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "El PIN que ha introducido no tiene una longitud válida [7-10]."
@@ -13236,13 +13233,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Saliendo porque está ejecutándose otro cliente de libpurple.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Media"
+msgstr "_Media"
-#, fuzzy
msgid "_Hangup"
-msgstr "Colgar"
+msgstr "_Colgar"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15571,6 +15566,9 @@ msgstr "Visite la página Web de Pidgin"
msgid "You do not have permission to uninstall this application."
msgstr "No tiene permisos para desinstalar esta aplicación."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "El nombre que introdujo es inválido."
+
#~ msgid "/Media/_Hangup"
#~ msgstr "/Media/_Colgar"
diff --git a/po/et.po b/po/et.po
index 407ae59dc3..eed5d13d28 100644
--- a/po/et.po
+++ b/po/et.po
@@ -795,7 +795,7 @@ msgstr "Seiska"
msgid "Waiting for transfer to begin"
msgstr "Oodatakse ülekande algust"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Tühistatud"
msgid "Failed"
@@ -16081,7 +16081,7 @@ msgstr ""
#~ msgid "Password Change Successful"
#~ msgstr "Paroolimuutmine õnnestus"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Tõrge ülekandmisel, ilmselt tühistas teine pool ülekande."
#~ msgid "Could not connect for transfer."
diff --git a/po/eu.po b/po/eu.po
index 04e1f9a65a..271fa1ccae 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -801,7 +801,7 @@ msgstr "Gelditu"
msgid "Waiting for transfer to begin"
msgstr "Transferentzia hasteko zain"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Bertan behera utzi da"
msgid "Failed"
@@ -16340,7 +16340,7 @@ msgstr "Ez daukazu aplikazio hau kentzeko baimenik."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Ezin izan da %s ireki idazteko!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Fitxategi-transferentziak huts egin du; beste aldekoak beharbada bertan "
#~ "behera utziko zuen."
diff --git a/po/fa.po b/po/fa.po
index e5b63bee12..0d407b9808 100644
--- a/po/fa.po
+++ b/po/fa.po
@@ -808,7 +808,7 @@ msgstr "توقف"
msgid "Waiting for transfer to begin"
msgstr "در حال انتظار برای آغاز انتقال"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "صرف نظر شد"
msgid "Failed"
@@ -16683,7 +16683,7 @@ msgstr "شما اجازه لازم براى حذف اين برنامه را ند
#~ msgid "Could not open %s for writing!"
#~ msgstr "نمی‌توان %s را برای نوشتن باز کرد!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "انتقال پرونده شکست خورد؛ احتمالاً طرف دیگر انصراف داده است."
#~ msgid "Could not connect for transfer."
diff --git a/po/fi.po b/po/fi.po
index 7834086643..b0307e43fa 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -802,7 +802,7 @@ msgstr "Pysäytä"
msgid "Waiting for transfer to begin"
msgstr "Odotetaan lähetyksen alkamista"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Peruutettu"
msgid "Failed"
@@ -16262,7 +16262,7 @@ msgstr "Sinulla ei ole valtuuksia poistaa ohjelmaa."
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s:n avaaminen kirjoitusta varten epäonnistui!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Tiedostonsiirto epäonnistui. Toinen osapuoli luultavasti katkaisi siirron."
@@ -17459,7 +17459,7 @@ msgstr "Sinulla ei ole valtuuksia poistaa ohjelmaa."
#~ msgid "Your request to send file[%s] has been rejected by buddy[%d]"
#~ msgstr "Pyyntösi lähettää tiedosto (%s) one evätty tuttavan (%d) toimesta"
-#~ msgid "The sending process of file[%s] has been canceled by buddy[%d]"
+#~ msgid "The sending process of file[%s] has been cancelled by buddy[%d]"
#~ msgstr "Tiedoston (%s) lähetys on peruutettu tuttavan (%d) toimesta"
#~ msgid "Blink tray icon for unread..."
diff --git a/po/fr.po b/po/fr.po
index 2f3284517f..7af8c6ffcd 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -21,14 +21,14 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-02-22 17:08+0200\n"
+"POT-Creation-Date: 2010-08-03 18:32+0200\n"
+"PO-Revision-Date: 2010-08-03 18:31+0200\n"
"Last-Translator: Éric Boumaour <zongo_fr@users.sourceforge.net>\n"
"Language-Team: fr <fr@li.org>\n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
"Plural-Forms: nplurals=2; plural=n>1;\n"
#. Translators may want to transliterate the name.
@@ -75,9 +75,8 @@ msgstr ""
msgid "Error"
msgstr "Erreur"
-#, fuzzy
msgid "Account was not modified"
-msgstr "Le compte n'a pas été ajouté."
+msgstr "Le compte n'a pas été modifié."
msgid "Account was not added"
msgstr "Le compte n'a pas été ajouté."
@@ -88,10 +87,14 @@ msgstr "Le nom d'utilisateur d'un compte ne doit pas être vide."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"Le protocole du compte ne peut pas être changé pendant que celui-ci est "
+"connecté."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"Le nom d'utilisateur du compte ne peut pas être changé pendant que celui-ci "
+"est connecté."
msgid "New mail notifications"
msgstr "Avertir des nouveaux courriers"
@@ -818,7 +821,7 @@ msgstr "Arrêter"
msgid "Waiting for transfer to begin"
msgstr "En attente de début de transfert"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Annulé"
msgid "Failed"
@@ -862,8 +865,8 @@ msgid ""
"System events will only be logged if the \"Log all status changes to system "
"log\" preference is enabled."
msgstr ""
-"Les événements système ne seront archivés que si l'option « Archiver tous "
-"les changements d'état dans les archives système » est activée."
+"Les événements système ne seront archivés que si l'option « Archiver tous les "
+"changements d'état dans les archives système » est activée."
msgid ""
"Instant messages will only be logged if the \"Log all instant messages\" "
@@ -1705,6 +1708,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"Ce certificat n'est pas encore valide. Veuillez vérifier que la date et "
+"l'heure sur cette machine sont bien réglées."
msgid "The certificate has expired and should not be considered valid."
msgstr "Le certificat a expiré et ne devrait pas être considéré valide."
@@ -2759,8 +2764,7 @@ msgid "Offline Message"
msgstr "Message déconnecté"
msgid "You can edit/delete the pounce from the `Buddy Pounces' dialog"
-msgstr ""
-"Vous pouvez modifier ou supprimer l'alerte dans la fenêtre « Alertes »."
+msgstr "Vous pouvez modifier ou supprimer l'alerte dans la fenêtre « Alertes »."
msgid "Yes"
msgstr "Oui"
@@ -3880,19 +3884,19 @@ msgid "Server thinks authentication is complete, but client does not"
msgstr ""
"Le serveur pense que l'authentification est terminée, et le client non."
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
msgstr ""
-"Le serveur demande une authentification en texte non chiffré au travers d'un "
-"flux crypté."
+"Le serveur peut demander une authentification en texte non chiffré au "
+"travers d'un flux non crypté."
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s demande une authentification en texte clair au travers d'une connexion "
-"non cryptée. Voulez-vous autoriser ceci et continuer l'authentification ?"
+"%s peut demander une authentification en texte clair au travers d'une "
+"connexion non cryptée. Voulez-vous autoriser ceci et continuer "
+"l'authentification ?"
msgid "SASL authentication failed"
msgstr "Échec de l'authentification SASL"
@@ -5984,8 +5988,8 @@ msgstr ""
msgid "The two PINs you entered do not match."
msgstr "Les nouveaux codes d'accès diffèrent."
-msgid "The name you entered is invalid."
-msgstr "Le nom saisi est non valide."
+msgid "The Display Name you entered is invalid."
+msgstr "Le nom à afficher saisi est non valide."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -6006,9 +6010,8 @@ msgstr ""
"Les informations de votre profil n'ont pu être récupérées. Veuillez "
"réessayer plus tard."
-#, fuzzy
msgid "Your UID"
-msgstr "Votre MXitId"
+msgstr "Votre UID"
#. pin
#. pin (required)
@@ -6080,16 +6083,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Connexion..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Le nom saisi est non valide."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Le code d'accès saisi n'a pas la bonne taille [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "Identifiant MXit"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6120,15 +6119,14 @@ msgstr "Votre session a expirée. Veuillez réessayer plus tard."
msgid "Invalid country selected. Please try again."
msgstr "Pays choisi non valide. Veuillez réessayer plus tard."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
msgstr ""
-"Le nom d'utilisateur n'est pas enregistré. Veuillez l'enregistrer d'abord."
+"L'identifiant MXit saisi n'est pas enregistré. Veuillez l'enregistrer "
+"d'abord."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
msgstr ""
-"Le nom d'utilisateur est déjà enregistré. Veuillez en choisir un autre."
+"L'identifiant MXit saisi est déjà enregistré. Veuillez en choisir un autre."
msgid "Internal error. Please try again later."
msgstr "Erreur interne. Veuillez réessayer plus tard."
@@ -6172,9 +6170,8 @@ msgstr "Message de refus"
msgid "Hidden Number"
msgstr "Numéro caché"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Votre MXitId"
+msgstr "Votre identifiant MXitId..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6188,26 +6185,21 @@ msgid "Enable splash-screen popup"
msgstr "Activer l'affichage de la bannière"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Vous avez été expulsé : (%s)"
+msgstr "Vous avez été expulsé de ce MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "Mauvais ticket"
+msgstr "a été expulsé"
-#, fuzzy
msgid "_Room Name:"
msgstr "_Salon :"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Vous avez du courrier !"
+msgstr "Vous avez été invité"
-#, fuzzy
msgid "Last Online"
-msgstr "En ligne"
+msgstr "En ligne dernièrement"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7983,15 +7975,14 @@ msgstr ""
"d'images. Votre adresse IP sera révélée et ceci peut être considéré comme "
"une faille de sécurité."
-#, fuzzy
msgid "Invalid SNAC"
-msgstr "Identifiant non valide"
+msgstr "SNAC non valide"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "Vitesse du serveur dépassée"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "Vitesse du client dépassée"
msgid "Service unavailable"
msgstr "Service non disponible"
@@ -10260,9 +10251,8 @@ msgstr "Langue du salon de discussions"
msgid "Ignore conference and chatroom invitations"
msgstr "Ignorer les invitations aux conférences et salons de discussions"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Utiliser le proxy du compte pour les connexions SSL"
+msgstr "Utiliser le proxy du compte pour les connexions HTTP et HTTPS"
msgid "Chat room list URL"
msgstr "URL de liste des salons de discussions"
@@ -10356,8 +10346,8 @@ msgid ""
msgstr ""
"Le serveur Yahoo! a demandé une méthode d'authentification non reconnue. "
"Cette version de l'application n'arrivera probablement pas à se connecter au "
-"service Yahoo!. Vous pouvez vérifier qu'une mise à jour est disponible sur "
-"%s."
+"service Yahoo!. Vous pouvez vérifier qu'une mise à jour est disponible sur %"
+"s."
msgid "Failed Yahoo! Authentication"
msgstr "Échec de l'authentification Yahoo!"
@@ -12472,8 +12462,8 @@ msgid ""
"to multiple messaging services at once. %s is written in C using GTK+. %s "
"is released, and may be modified and redistributed, under the terms of the "
"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s. There is no warranty for %s.<BR><BR>"
msgstr ""
"%s est un client de messagerie basé sur libpurple capable de se connecter à "
"de multiples services de messageries instantanées. %s est écrit en C et "
@@ -13028,16 +13018,16 @@ msgstr ""
#, c-format
msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
msgstr ""
"Êtes-vous sûr de vouloir supprimer les archives de la conversation dans %s "
"datée du %s ?"
#, c-format
msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
msgstr "Êtes-vous sûr de vouloir supprimer les archives système datées du %s ?"
msgid "Delete Log?"
@@ -13143,13 +13133,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Arrêt à cause d'un autre client libpurple existant.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Média"
+msgstr "_Média"
-#, fuzzy
msgid "_Hangup"
-msgstr "Raccrocher"
+msgstr "_Raccrocher"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -14852,8 +14840,8 @@ msgid ""
"'Enter' in the entry box to send. Watch the debug window."
msgstr ""
"Permet d'envoyer des données brutes aux protocoles en mode texte (XMPP, MSN, "
-"IRC, TOC). Tapez « Entrée » dans la boîte de saisie pour envoyer. Observez "
-"le résultat dans la fenêtre de debug."
+"IRC, TOC). Tapez « Entrée » dans la boîte de saisie pour envoyer. Observez le "
+"résultat dans la fenêtre de debug."
#, c-format
msgid "You can upgrade to %s %s today."
@@ -15378,13 +15366,13 @@ msgstr ""
#, no-c-format
msgid ""
"Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
"Erreur lors de l'installation du correcteur orthographique ($R3).$\\rSi une "
"nouvelle tentative échoue, veuillez suivre les instructions sur http://"
-"developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
#. Installer Subsection Text
msgid "GTK+ Runtime (required if not present)"
@@ -15463,6 +15451,9 @@ msgstr "Visitez la page web de Pidgin"
msgid "You do not have permission to uninstall this application."
msgstr "Vous n'avez pas les permissions pour supprimer cette application."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "Le nom saisi est non valide."
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "Le certificat n'est pas encore valide."
@@ -16018,7 +16009,7 @@ msgstr "Vous n'avez pas les permissions pour supprimer cette application."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Impossible d'ouvrir %s pour l'écriture"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Échec du transfert de fichier. Annulation probable du correspondant."
diff --git a/po/ga.po b/po/ga.po
index b094288d75..1554da08f5 100644
--- a/po/ga.po
+++ b/po/ga.po
@@ -750,7 +750,7 @@ msgid "Waiting for transfer to begin"
msgstr ""
#, fuzzy
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cealaithe"
#, fuzzy
diff --git a/po/gl.po b/po/gl.po
index 4a6fba35b7..f067cc5bb1 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -807,7 +807,7 @@ msgstr "Deter"
msgid "Waiting for transfer to begin"
msgstr "Agardando o comezo da transferencia"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelado"
msgid "Failed"
diff --git a/po/gu.po b/po/gu.po
index 01f59401ee..185bd10573 100644
--- a/po/gu.po
+++ b/po/gu.po
@@ -789,7 +789,7 @@ msgstr "અટકાવો"
msgid "Waiting for transfer to begin"
msgstr "પરિવહન શરૂ થવા માટે રાહ જોઈ રહ્યા છીએ"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "રદ થયેલ"
msgid "Failed"
diff --git a/po/he.po b/po/he.po
index d508ce18c1..18d992cd3a 100644
--- a/po/he.po
+++ b/po/he.po
@@ -1,5 +1,5 @@
# Pidgin Hebrew translation
-# Copyright (C) 2005-2009, Shalom Craimer <scraimer at gmail dot com>
+# Copyright (C) 2005-2010, Shalom Craimer <scraimer at gmail dot com>
# Copyright (C) 2003, Pavel Bibergal cyberkm@barak-online.net
#
# This file is distributed under the same license as the Pidgin package.
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: he\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-05-24 15:59+0200\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-01 09:55+0200\n"
"Last-Translator: Shalom Craimer <scraimer at g mail dot com>\n"
"Language-Team: Hebrew <he@li.org>\n"
"Language: he\n"
@@ -60,9 +60,8 @@ msgstr ""
msgid "Error"
msgstr "שגיאה"
-#, fuzzy
msgid "Account was not modified"
-msgstr "החשבון לא נוסף"
+msgstr "החשבון לא עודכן"
msgid "Account was not added"
msgstr "החשבון לא נוסף"
@@ -72,11 +71,11 @@ msgstr "שם המשתמש של החשבון חייב להיות לא-ריק."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "לא ניתן לשנות את הפרוטוקול של החשבון בעודו מחובר."
msgid ""
"The account's username cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "לא ניתן לשנות את שם המשתמש בעודו מחובר לשרת."
msgid "New mail notifications"
msgstr "הודעה על דואר חדש"
@@ -782,7 +781,7 @@ msgstr "עצור"
msgid "Waiting for transfer to begin"
msgstr "ממתין להעברה להתחיל"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "בוטל"
msgid "Failed"
@@ -1652,7 +1651,7 @@ msgstr "לא ניתן לבטוח בתעודה כיוון שאין תעודה מ
msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
-msgstr ""
+msgstr "התעודה עוד לא בתוקף. יש לוודא כי השעה והתאריך של מחשבך מדוייקים."
msgid "The certificate has expired and should not be considered valid."
msgstr "תוקף התעודה פג, ולכן אין להחשיבה כתקפה."
@@ -3747,15 +3746,16 @@ msgstr "תשובת אימות לא תקפה מהשרת"
msgid "Server thinks authentication is complete, but client does not"
msgstr "השרת סבור שהאימות הסתיים בהצלחה, אבל תוכנת הלקוח לא מסכימה"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
-msgstr "השרת דורש אימות לא מוצפן מעל תקשורת לא מוצפנת"
+msgstr "ייתכן והשרת דורש אימות לא מוצפן מעל תקשורת לא מוצפנת"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
-msgstr "%s דורש אימות לא מוצפן מעל תקשורת לא מוצפנת. לאפשר ולהמשיך בכל זאת?"
+msgstr ""
+"ייתכן והשרת %s דורש אימות לא מוצפן מעל תקשורת לא מוצפנת. לאפשר ולהמשיך בכל "
+"זאת?"
msgid "SASL authentication failed"
msgstr "אימות SASL נכשל"
@@ -5786,8 +5786,8 @@ msgstr "ה-PIN אינו חוקי. על הקוד להכיל רק ספרות [0-9]
msgid "The two PINs you entered do not match."
msgstr "שני ה-PIN שהזנת אינם זהים."
-msgid "The name you entered is invalid."
-msgstr "השם שהזנת אינו חוקי."
+msgid "The Display Name you entered is invalid."
+msgstr "הזנת שם-תצוגה לא תקף."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5805,9 +5805,8 @@ msgstr "פרופיל"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "פרטי הפרופיל שלך עוד לא התקבלו. יש לנסות שנית מאוחר יותר."
-#, fuzzy
msgid "Your UID"
-msgstr "מזהה MXit שלך"
+msgstr "ה-UID שלך"
#. pin
#. pin (required)
@@ -5875,16 +5874,12 @@ msgstr "לא ניתן להתחבר לשרת ה-MXit. יש לוודא את הגד
msgid "Connecting..."
msgstr "מתחבר..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "השם שהזנת אינו חוקי."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "ה-PIN שהזנת בעל אורך לא-חוקי [7-10[."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "מזהה MXit"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -5912,13 +5907,11 @@ msgstr "פג תוקפו של החיבור. יש לנסות בשנית מאוחר
msgid "Invalid country selected. Please try again."
msgstr "נבחרה ארץ לא-חוקית. יש לנסות שנית."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "שם המשתמש אינו רשום. חובה להירשם קודם."
+msgstr "מזהה ה- Mxit שהוזן אינו רשום. חובה להירשם קודם."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "שם המשתמש כבר רשום. יש לבחור שם משתמש אחר."
+msgstr "מזהה MXit זה כבר רשום. יש לבחור שם משתמש אחר."
msgid "Internal error. Please try again later."
msgstr "שגיאה פנימית. יש לנסות מאוחר יותר."
@@ -5962,9 +5955,8 @@ msgstr "הודעת דחייה"
msgid "Hidden Number"
msgstr "מספר סמוי"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "מזהה MXit שלך"
+msgstr "מזהה MXit שלך.."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -5978,26 +5970,21 @@ msgid "Enable splash-screen popup"
msgstr "אפשר פתיחת חלון-הקדמה"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "נבעטת: (%s)"
+msgstr "נבעטת מתוך MultiMX זה."
-#, fuzzy
msgid "was kicked"
-msgstr "כרטיס לא תקין"
+msgstr "נבעט/ה"
-#, fuzzy
msgid "_Room Name:"
-msgstr "_חדר:"
+msgstr "שם _חדר:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "יש לך דואר!"
+msgstr "הוזמנת"
-#, fuzzy
msgid "Last Online"
-msgstr "מחובר"
+msgstr "חיבור אחרון"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7708,10 +7695,10 @@ msgid "Invalid SNAC"
msgstr "SNAC לא תקף"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "הפרזת מעבר למגבלת השרת"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "הפרזת מעבר למגבלת הלקוח"
msgid "Service unavailable"
msgstr "השירות אינו זמין"
@@ -9945,9 +9932,8 @@ msgstr "הגדרה איזורית לחדר צ'אט"
msgid "Ignore conference and chatroom invitations"
msgstr "התעלם מהזמנות לשיחות-ועידה ולחדרי-צ'אט"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "השתמש בחשבון שרת-תיווך עבור חיבורי SSL"
+msgstr "התשמש במתווך עבור החשבון בשביל חיבורי HTTP ו-HTTPS"
msgid "Chat room list URL"
msgstr "מיקום של רשימת חדרי הצ'אט"
@@ -12749,13 +12735,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "מסיים מכיוון שכבר רצה תוכנה אחרת שהמשתמש בספריית libpurple.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_מדיה"
+msgstr "_מדיה"
-#, fuzzy
msgid "_Hangup"
-msgstr "התנתק"
+msgstr "הת_נתק"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15008,6 +14992,9 @@ msgstr ".Pidginבקרו באתר של "
msgid "You do not have permission to uninstall this application."
msgstr ".אין לך זכות למחוק תוכנה זאת"
+#~ msgid "The name you entered is invalid."
+#~ msgstr "השם שהזנת אינו חוקי."
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "התעודה עדיין אינה תקפה."
diff --git a/po/hi.po b/po/hi.po
index f81a1b578a..035bd019ef 100644
--- a/po/hi.po
+++ b/po/hi.po
@@ -780,7 +780,7 @@ msgstr "रूकें"
msgid "Waiting for transfer to begin"
msgstr "हस्तांतरण के शुरु होने की प्रतीक्षा करता है."
-msgid "Canceled"
+msgid "Cancelled"
msgstr "रद्द"
msgid "Failed"
diff --git a/po/hu.po b/po/hu.po
index c3441b0d39..b343de7ce2 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -9,14 +9,14 @@ msgid ""
msgstr ""
"Project-Id-Version: pidgin 2.7\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:17-0400\n"
-"PO-Revision-Date: 2010-05-29 02:36+0200\n"
+"POT-Creation-Date: 2010-08-15 21:49+0200\n"
+"PO-Revision-Date: 2010-08-15 21:48+0200\n"
"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
"Language-Team: Hungarian <gnome at fsf dot hu>\n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: KBabel 1.11.4\n"
@@ -64,9 +64,8 @@ msgstr ""
msgid "Error"
msgstr "Hiba"
-#, fuzzy
msgid "Account was not modified"
-msgstr "A fiók nem lett felvéve"
+msgstr "A fiók nem lett módosítva"
msgid "Account was not added"
msgstr "A fiók nem lett felvéve"
@@ -77,10 +76,13 @@ msgstr "A fiók felhasználóneve nem lehet üres."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"A fiók protokollja nem módosítható, ha épp csatlakozva van a kiszolgálóhoz."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"A fiók felhasználóneve nem módosítható, ha épp csatlakozva van a "
+"kiszolgálóhoz."
msgid "New mail notifications"
msgstr "Értesítések új levélre"
@@ -691,7 +693,7 @@ msgstr "say &lt;üzenet&gt;: Üzenet küldése, mintha nem használná a parancs
msgid "me &lt;action&gt;: Send an IRC style action to a buddy or chat."
msgstr ""
-"me &lt;művelet&gt;: IRC stílusú művelet küldése egy partnernak vagy "
+"me &lt;művelet&gt;: IRC stílusú művelet küldése egy partnernek vagy "
"csevegésnek."
msgid ""
@@ -802,7 +804,7 @@ msgstr "Leállítás"
msgid "Waiting for transfer to begin"
msgstr "Várakozás az átvitel indulására"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Megszakítva"
msgid "Failed"
@@ -1689,6 +1691,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"A tanúsítvány még nem érvényes. Ellenőrizze a számítógép dátumának és "
+"idejének pontosságát."
msgid "The certificate has expired and should not be considered valid."
msgstr "A tanúsítvány lejárt és nem tekinthető érvényesnek."
@@ -3834,7 +3838,7 @@ msgid ""
"this and continue authentication?"
msgstr ""
"%s szöveges hitelesítést követel meg egy nem titkosított csatornán. "
-"Engedélyezi ezt és folytatja a hitelesítést?"
+"Engedélyezi ezt, és folytatja a hitelesítést?"
msgid "Plaintext Authentication"
msgstr "Egyszerű szöveges hitelesítés"
@@ -3848,18 +3852,18 @@ msgstr "Érvénytelen hívás a kiszolgálótól"
msgid "Server thinks authentication is complete, but client does not"
msgstr "A kiszolgáló szerint a hitelesítés kész, a kliens szerint nem"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
msgstr ""
-"A kiszolgáló szöveges hitelesítést követel meg egy nem titkosított csatornán"
+"A kiszolgáló egyszerű szöveges hitelesítést követel meg egy nem titkosított "
+"csatornán"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s szöveges hitelesítést követel meg egy nem titkosított csatornán. "
-"Engedélyezi ezt és folytatja a hitelesítést?"
+"%s egyszerű szöveges hitelesítést követelhet meg egy nem titkosított "
+"kapcsolaton. Engedélyezi ezt, és folytatja a hitelesítést?"
msgid "SASL authentication failed"
msgstr "A SASL hitelesítés meghiúsult"
@@ -5939,8 +5943,8 @@ msgstr "A PIN érvénytelen. Csak számokból állhat [0-9]."
msgid "The two PINs you entered do not match."
msgstr "A megadott két PIN nem egyezik."
-msgid "The name you entered is invalid."
-msgstr "A megadott név érvénytelen."
+msgid "The Display Name you entered is invalid."
+msgstr "A megadott megjelenő név érvénytelen."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5958,9 +5962,8 @@ msgstr "Profil"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "A profilinformációi még nincsenek lekérve. Próbálja újra később."
-#, fuzzy
msgid "Your UID"
-msgstr "Az Ön MXitId-ja"
+msgstr "Az Ön UID-ja"
#. pin
#. pin (required)
@@ -6032,16 +6035,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Kapcsolódás…"
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "A megadott név érvénytelen."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "A megadott PIN érvénytelen hosszúságú [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit azonosító"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6069,14 +6068,13 @@ msgstr "A munkamenet lejárt. Próbálja újra később."
msgid "Invalid country selected. Please try again."
msgstr "Érvénytelen országot választott. Próbálja újra később."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "A felhasználónév nincs regisztrálva. Először regisztráljon."
+msgstr "A megadott MXit azonosító nincs regisztrálva. Először regisztráljon."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
msgstr ""
-"A felhasználónév már használatban van. Válasszon másik felhasználónevet."
+"A megadott MXit azonosító már használatban van. Válasszon másik "
+"felhasználónevet."
msgid "Internal error. Please try again later."
msgstr "Belső hiba. Próbálja újra később."
@@ -6120,9 +6118,8 @@ msgstr "Visszautasítási üzenet"
msgid "Hidden Number"
msgstr "Rejtett szám"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Az Ön MXitId-ja"
+msgstr "Az Ön MXit ID-ja…"
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6136,26 +6133,21 @@ msgid "Enable splash-screen popup"
msgstr "Felugró indítókép engedélyezése"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Kirúgták Önt: (%s)"
+msgstr "Kirúgták ebből a MultiMX-ből."
-#, fuzzy
msgid "was kicked"
-msgstr "Rossz jegy"
+msgstr "kirúgva"
-#, fuzzy
msgid "_Room Name:"
-msgstr "Sz_oba:"
+msgstr "Sz_obanév:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Levele érkezett!"
+msgstr "Meghívták"
-#, fuzzy
msgid "Last Online"
-msgstr "Elérhető"
+msgstr "Utoljára elérhető"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -6727,8 +6719,8 @@ msgstr "Nem lehet bejelentkezni: %s"
#, c-format
msgid "Unable to send message. Could not get details for user (%s)."
msgstr ""
-"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le "
-"(%s)."
+"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le (%"
+"s)."
#, c-format
msgid "Unable to add %s to your buddy list (%s)."
@@ -7128,102 +7120,13 @@ msgid ""
"%s tried to send you a %s file, but we only allow files up to %s over Direct "
"IM. Try using file transfer instead.\n"
msgstr ""
-"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak "
-"%s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n"
+"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak %"
+"s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n"
#, c-format
msgid "File %s is %s, which is larger than the maximum size of %s."
msgstr "A(z) %s fájl %s, amely nagyobb, mint a legnagyobb méret (%s)."
-msgid ""
-"(There was an error receiving this message. The buddy you are speaking with "
-"is probably using a different encoding than expected. If you know what "
-"encoding he is using, you can specify it in the advanced account options for "
-"your AIM/ICQ account.)"
-msgstr ""
-"(Hiba történt az üzenet fogadása során. A partner, akivel cseveg "
-"valószínűleg a várttól eltérő kódolást használ. Ha tudja, hogy a partner "
-"milyen kódolást használ, akkor megadhatja azt az AIM/ICQ fiók haladó "
-"fiókbeállításainál.)"
-
-#, c-format
-msgid ""
-"(There was an error receiving this message. Either you and %s have "
-"different encodings selected, or %s has a buggy client.)"
-msgstr ""
-"(Hiba az üzenet fogadása közben. Lehetséges, hogy Ön és %s különböző "
-"kódolást használnak, vagy %s hibás klienst használ.)"
-
-#. Label
-msgid "Buddy Icon"
-msgstr "Partnerikon"
-
-msgid "Voice"
-msgstr "Hang"
-
-msgid "AIM Direct IM"
-msgstr "AIM közvetlen azonnali üzenetek"
-
-msgid "Get File"
-msgstr "Fájl letöltése"
-
-msgid "Games"
-msgstr "Játékok"
-
-msgid "ICQ Xtraz"
-msgstr "ICQ Xtraz"
-
-msgid "Add-Ins"
-msgstr "Kiegészítők"
-
-msgid "Send Buddy List"
-msgstr "Partnerlista küldése"
-
-msgid "ICQ Direct Connect"
-msgstr "ICQ közvetlen kapcsolat"
-
-msgid "AP User"
-msgstr "AP felhasználó"
-
-msgid "ICQ RTF"
-msgstr "ICQ RTF"
-
-msgid "Nihilist"
-msgstr "Nihilista"
-
-msgid "ICQ Server Relay"
-msgstr "ICQ közvetítő kiszolgáló"
-
-msgid "Old ICQ UTF8"
-msgstr "Régi ICQ UTF8"
-
-msgid "Trillian Encryption"
-msgstr "Trillian titkosítás"
-
-msgid "ICQ UTF8"
-msgstr "ICQ UTF8"
-
-msgid "Hiptop"
-msgstr "Hiptop"
-
-msgid "Security Enabled"
-msgstr "Biztonság engedélyezve"
-
-msgid "Video Chat"
-msgstr "Videócsevegés"
-
-msgid "iChat AV"
-msgstr "iChat AV"
-
-msgid "Live Video"
-msgstr "Élő videó"
-
-msgid "Camera"
-msgstr "Fényképezőgép"
-
-msgid "Screen Sharing"
-msgstr "Képernyőmegosztás"
-
msgid "Free For Chat"
msgstr "Ráérek csevegni"
@@ -7254,15 +7157,6 @@ msgstr "Munkában"
msgid "At lunch"
msgstr "Ebédel"
-msgid "IP Address"
-msgstr "IP cím"
-
-msgid "Warning Level"
-msgstr "Figyelmeztetési szint"
-
-msgid "Buddy Comment"
-msgstr "Partnermegjegyzés"
-
#, c-format
msgid "Unable to connect to authentication server: %s"
msgstr "Nem lehet kapcsolódni a hitelesítési kiszolgálóhoz: %s"
@@ -7361,15 +7255,6 @@ msgstr "Jelszó elküldve"
msgid "Unable to initialize connection"
msgstr "A kapcsolat nem inicializálható"
-msgid "Please authorize me so I can add you to my buddy list."
-msgstr "Kérem engedélyezze, hogy felvehessem a partnereim közé."
-
-msgid "No reason given."
-msgstr "Nincs ok megadva."
-
-msgid "Authorization Denied Message:"
-msgstr "Engedélyezést elutasító üzenet:"
-
#, c-format
msgid ""
"The user %u has denied your request to add them to your buddy list for the "
@@ -7380,6 +7265,9 @@ msgstr ""
"következő indoklással:\n"
"%s"
+msgid "No reason given."
+msgstr "Nincs ok megadva."
+
msgid "ICQ authorization denied."
msgstr "ICQ engedélyezés elutasítva."
@@ -7498,60 +7386,13 @@ msgid_plural "You missed %hu messages from %s for an unknown reason."
msgstr[0] "Nem kapott meg %hu üzenetet a következőtől: %s, ismeretlen okból."
msgstr[1] "Nem kapott meg %hu üzenetet a következőtől: %s, ismeretlen okból."
-#, c-format
-msgid "User information not available: %s"
-msgstr "A felhasználó információi nem érhetőek el: %s"
-
-msgid "Online Since"
-msgstr "Kapcsolódva ezóta"
-
-msgid "Member Since"
-msgstr "Tagság kezdete"
-
-msgid "Capabilities"
-msgstr "Képességek"
-
msgid "Your AIM connection may be lost."
msgstr "Az AIM kapcsolata megszakadhatott."
-#. The conversion failed!
-msgid ""
-"[Unable to display a message from this user because it contained invalid "
-"characters.]"
-msgstr ""
-"[Nem lehet megjeleníteni az üzenetet ettől a felhasználótól, mert az "
-"érvénytelen karaktereket tartalmazott.]"
-
#, c-format
msgid "You have been disconnected from chat room %s."
msgstr "Kilépett a(z) %s csevegőszobából."
-msgid "Mobile Phone"
-msgstr "Mobiltelefon"
-
-msgid "Personal Web Page"
-msgstr "Saját weboldal"
-
-#. aim_userinfo_t
-#. strip_html_tags
-msgid "Additional Information"
-msgstr "További információ"
-
-msgid "Zip Code"
-msgstr "Irányítószám"
-
-msgid "Work Information"
-msgstr "Munkahelyi adatok"
-
-msgid "Division"
-msgstr "Részleg"
-
-msgid "Position"
-msgstr "Pozíció"
-
-msgid "Web Page"
-msgstr "Weboldal"
-
msgid "Pop-Up Message"
msgstr "Felbukkanó üzenet"
@@ -7831,8 +7672,8 @@ msgstr ""
msgid "Change Address To:"
msgstr "Cím módosítása a következőre:"
-msgid "<i>you are not waiting for authorization</i>"
-msgstr "<i>Ön nem vár engedélyezésre</i>"
+msgid "you are not waiting for authorization"
+msgstr "Ön nem vár engedélyezésre"
msgid "You are awaiting authorization from the following buddies"
msgstr "A következő partnerektől vár engedélyezésre"
@@ -7886,9 +7727,6 @@ msgstr "Engedélyezésre váró partnerek megjelenítése"
msgid "Search for Buddy by Email Address..."
msgstr "Partner keresése e-mail cím szerint…"
-msgid "Search for Buddy by Information"
-msgstr "Partner keresése információ alapján"
-
msgid "Use clientLogin"
msgstr "Kliensbejelentkezés használata"
@@ -7929,85 +7767,74 @@ msgstr ""
"képekhez. Ezzel láthatóvá válik az IP címe, ami veszélyeztetheti a "
"magánszférája biztonságát."
-#, fuzzy
msgid "Invalid SNAC"
-msgstr "Érvénytelen azonosító"
+msgstr "Érvénytelen SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "A kiszolgáló sebességkorlátja túllépve"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "A kliens sebességkorlátja túllépve"
-#, fuzzy
msgid "Service unavailable"
msgstr "A szolgáltatás nem érhető el"
-#, fuzzy
msgid "Service not defined"
-msgstr "A konferencia nem található"
+msgstr "A szolgáltatás nincs meghatározva"
msgid "Obsolete SNAC"
-msgstr ""
+msgstr "Elavult SNAC"
-#, fuzzy
msgid "Not supported by host"
-msgstr "Nem támogatott"
+msgstr "A kiszolgáló nem támogatja"
-#, fuzzy
msgid "Not supported by client"
-msgstr "Nem támogatott"
+msgstr "A kliens nem támogatja"
msgid "Refused by client"
-msgstr ""
+msgstr "A kliens visszautasította"
msgid "Reply too big"
-msgstr ""
+msgstr "A válasz túl nagy"
-#, fuzzy
msgid "Responses lost"
-msgstr "Válasz valószínűsége:"
+msgstr "A válaszok elvesztek"
-#, fuzzy
msgid "Request denied"
-msgstr "Kérés"
+msgstr "A kérés elutasítva"
msgid "Busted SNAC payload"
-msgstr ""
+msgstr "Sérült SNAC tartalom"
msgid "Insufficient rights"
-msgstr ""
+msgstr "Elégtelen jogosultságok"
msgid "In local permit/deny"
-msgstr ""
+msgstr "A helyi engedélyezésben/tiltásban"
msgid "Warning level too high (sender)"
-msgstr ""
+msgstr "A figyelmeztetési szint túl magas (küldő)"
msgid "Warning level too high (receiver)"
-msgstr ""
+msgstr "A figyelmeztetési szint túl magas (fogadó)"
-#, fuzzy
msgid "User temporarily unavailable"
-msgstr "A szolgáltatás átmenetileg nem érhető el"
+msgstr "A felhasználó átmenetileg nem érhető el"
-#, fuzzy
msgid "No match"
msgstr "Nincs találat"
-#, fuzzy
msgid "List overflow"
-msgstr "A lista megtelt"
+msgstr "A lista túlcsordult"
-#, fuzzy
msgid "Request ambiguous"
-msgstr "Kérés"
+msgstr "A kérés kétértelmű"
msgid "Queue full"
-msgstr ""
+msgstr "A sor tele"
msgid "Not while on AOL"
-msgstr ""
+msgstr "Nem az AOL-on"
msgid "Aquarius"
msgstr "Vízöntő"
@@ -10064,6 +9891,9 @@ msgstr "Videokonferencia"
msgid "Computer"
msgstr "Számítógép"
+msgid "Mobile Phone"
+msgstr "Mobiltelefon"
+
msgid "PDA"
msgstr "PDA"
@@ -10232,9 +10062,8 @@ msgstr "Csevegőszoba nyelve"
msgid "Ignore conference and chatroom invitations"
msgstr "Konferencia- és csevegőszoba-meghívások figyelmen kívül hagyása"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Fiókproxy használata SSL kapcsolatokhoz"
+msgstr "Fiókproxy használata HTTP és HTTPS kapcsolatokhoz"
msgid "Chat room list URL"
msgstr "Csevegőszobák listájának URL címe"
@@ -10493,6 +10322,9 @@ msgstr "%s felajánlja egy %d fájlból álló csoport elküldését.\n"
msgid "Write Error"
msgstr "Írási hiba"
+msgid "IP Address"
+msgstr "IP cím"
+
msgid "Yahoo! Japan Profile"
msgstr "Yahoo! Japán profil"
@@ -10534,6 +10366,9 @@ msgstr "Érdekes link 2"
msgid "Cool Link 3"
msgstr "Érdekes link 3"
+msgid "Member Since"
+msgstr "Tagság kezdete"
+
msgid "Last Update"
msgstr "Utolsó frissítés"
@@ -10762,8 +10597,8 @@ msgstr "%d HTTP proxy kapcsolathiba"
#, c-format
msgid "Access denied: HTTP proxy server forbids port %d tunneling"
msgstr ""
-"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) "
-"%d. porton"
+"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) %"
+"d. porton"
#, c-format
msgid "Error resolving %s"
@@ -11016,8 +10851,8 @@ msgid ""
"An error was encountered reading your %s. The file has not been loaded, and "
"the old file has been renamed to %s~."
msgstr ""
-"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl "
-"%s~ néven lett elmentve."
+"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl %"
+"s~ néven lett elmentve."
msgid ""
"Chat over IM. Supports AIM, Google Talk, Jabber/XMPP, MSN, Yahoo and more"
@@ -11154,6 +10989,10 @@ msgstr ""
"segítségével visszatérhet ehhez az ablakhoz fiókok hozzáadásához, "
"szerkesztéséhez vagy eltávolításához."
+#, c-format
+msgid "%s%s%s%s wants to add you (%s) to his or her buddy list%s%s"
+msgstr "%s%s%s%s felhasználó szeretné Önt (%s) felvenni a partnerlistájára%s%s"
+
#. Buddy List
msgid "Background Color"
msgstr "Háttérszín"
@@ -12437,8 +12276,8 @@ msgid ""
"to multiple messaging services at once. %s is written in C using GTK+. %s "
"is released, and may be modified and redistributed, under the terms of the "
"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s. There is no warranty for %s.<BR><BR>"
msgstr ""
"A %s egy libpurple alapú moduláris üzenetküldő kliens, amely egyszerre több "
"üzenetküldő szolgáltatáshoz is képes csatlakozni. A %s GTK+ használatával, C "
@@ -12988,16 +12827,16 @@ msgstr ""
#, c-format
msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
msgstr ""
"Biztos, hogy törölni akarja a(z) %s csatornán folytatott, %s időpontban "
"kezdődött beszélgetés naplóját?"
#, c-format
msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
msgstr ""
"Biztos, hogy törölni akarja a(z) %s időpontban kezdődött rendszernaplót?"
@@ -13103,13 +12942,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Kilépés, mert már fut egy másik libpurple kliens.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Média"
+msgstr "Méd_ia"
-#, fuzzy
msgid "_Hangup"
-msgstr "Lerakás"
+msgstr "_Lerakás"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -14016,6 +13853,10 @@ msgstr ""
"<b>Fájlméret:</b> %s\n"
"<b>Képméret:</b> %dx%d"
+#. Label
+msgid "Buddy Icon"
+msgstr "Partnerikon"
+
#, c-format
msgid "The file '%s' is too large for %s. Please try a smaller image.\n"
msgstr ""
@@ -14948,6 +14789,9 @@ msgstr "Operátor"
msgid "Half Operator"
msgstr "Féloperátor"
+msgid "Voice"
+msgstr "Hang"
+
msgid "Authorization dialog"
msgstr "Hitelesítési ablak"
@@ -15266,7 +15110,7 @@ msgstr ""
"Ez a bővítmény XMPP kiszolgálókban vagy kliensekben végzett hibakereséshez "
"hasznos."
-#. $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue."
+#. $(^Name) is the current Version name (e.g. Pidgin 2.7.0). $_CLICK will become a translated version of "Click Next to continue." DO NOT translate the CLICK in $_CLICK. It will break the installer.
msgid ""
"$(^Name) is released under the GNU General Public License (GPL). The license "
"is provided here for information purposes only. $_CLICK"
@@ -15328,8 +15172,8 @@ msgstr ""
#, no-c-format
msgid ""
"Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
"Hiba a helyesírás-ellenőrző telepítésekor. ($R3).$\\rHa az újrapróbálkozás "
"meghiúsul, akkor saját kezűleg is telepítheti a http://developer.pidgin.im/"
@@ -15411,29 +15255,3 @@ msgstr "A Pidgin weboldalának felkeresése"
msgid "You do not have permission to uninstall this application."
msgstr "Nincs jogosultsága az alkalmazás eltávolításához."
-
-#~ msgid "The certificate is not valid yet."
-#~ msgstr "A tanúsítvány még nem érvényes."
-
-#~ msgid "The nick name you entered is invalid."
-#~ msgstr "A megadott becenév érvénytelen."
-
-#~ msgid "MXit Login Name"
-#~ msgstr "MXit bejelentkezési név"
-
-#~ msgid "Nick Name"
-#~ msgstr "Becenév"
-
-#~ msgid "Your Mobile Number..."
-#~ msgstr "Az Ön mobiltelefonszáma…"
-
-#, fuzzy
-#~ msgid "Rate to host"
-#~ msgstr "Meghívás csevegésre"
-
-#, fuzzy
-#~ msgid "Rate to client"
-#~ msgstr "Utolsó ismert kliens"
-
-#~ msgid "/Media/_Hangup"
-#~ msgstr "/Média/_Lerakás"
diff --git a/po/hy.po b/po/hy.po
index 2960fdeee2..2e037d9893 100644
--- a/po/hy.po
+++ b/po/hy.po
@@ -755,7 +755,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr ""
msgid "Failed"
diff --git a/po/id.po b/po/id.po
index 695694c0ab..18e88e0467 100644
--- a/po/id.po
+++ b/po/id.po
@@ -815,7 +815,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "Menunggu transfer untuk mulai"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Dibatalkan"
msgid "Failed"
@@ -16769,7 +16769,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s tidak dapat dibuka untuk penulisan!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Transfer file gagal; sisi lainnya kemungkinan membatalkan."
#~ msgid "Could not connect for transfer."
diff --git a/po/it.po b/po/it.po
index 79c68b7e39..71e5350e19 100644
--- a/po/it.po
+++ b/po/it.po
@@ -808,7 +808,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "In attesa dell'inizio del trasferimento"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Annullato"
msgid "Failed"
diff --git a/po/ja.po b/po/ja.po
index 42598043eb..728e89b715 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -808,7 +808,7 @@ msgstr "停止する"
msgid "Waiting for transfer to begin"
msgstr "転送開始を待っています"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "キャンセルしました"
msgid "Failed"
@@ -16759,7 +16759,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "書き込みモードで %s を開けません!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "ファイル転送が失敗しました。おそらく向こう側がキャンセルしたのでしょう。"
diff --git a/po/ka.po b/po/ka.po
index 0ea495a7c6..27eff72d7b 100644
--- a/po/ka.po
+++ b/po/ka.po
@@ -807,7 +807,7 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "ველოდები გადატანის დაწყებას"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "გაუქმებულია"
#, fuzzy
diff --git a/po/km.po b/po/km.po
index 63cae0044e..01a05c2c99 100644
--- a/po/km.po
+++ b/po/km.po
@@ -777,7 +777,7 @@ msgstr "បញ្ឈប់"
msgid "Waiting for transfer to begin"
msgstr "រង់ចាំ​ការ​ផ្ទេរ​ចាប់ផ្ដើម"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "បានបោះបង់"
msgid "Failed"
diff --git a/po/kn.po b/po/kn.po
index 1e6031b57a..753bd1753e 100644
--- a/po/kn.po
+++ b/po/kn.po
@@ -802,7 +802,7 @@ msgstr "ನಿಲ್ಲಿಸು"
msgid "Waiting for transfer to begin"
msgstr "ವರ್ಗಾವಣೆಯ ಪ್ರಾರಂಭಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ರದ್ದಾಗಿದೆ"
msgid "Failed"
@@ -15930,7 +15930,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "ಬರೆಯುವದಕ್ಕಾಗಿ %s ತೆರೆಯಲು ಆಗಲಿಲ್ಲ"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "ಕಡತ ವರ್ಗಾವಣೆ ವಿಫಲ ; ಬಹುಶ: ಆಚೆಯವರು ರದ್ದು ಮಾಡಿದರು"
#~ msgid "Could not connect for transfer."
diff --git a/po/ko.po b/po/ko.po
index 40220869c9..fe3d6fcba6 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -816,7 +816,7 @@ msgstr "입력"
msgid "Waiting for transfer to begin"
msgstr "전송 시작을 기다리고 있습니다."
-msgid "Canceled"
+msgid "Cancelled"
msgstr "취소되었습니다."
msgid "Failed"
@@ -16691,7 +16691,7 @@ msgstr "이 프로그램을 제거할 수 있는 권한이 없습니다."
#~ msgid "Could not open %s for writing!"
#~ msgstr "쓰기 모드에서 %s 을(를) 열 수 없습니다!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "파일 전송에 실패했습니다. 아마도 상대측에서 취소한 것 같습니다."
#~ msgid "Could not connect for transfer."
diff --git a/po/ku.po b/po/ku.po
index f3f9e8cab9..f461b1fa4b 100644
--- a/po/ku.po
+++ b/po/ku.po
@@ -828,7 +828,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr "Li benda destpêkirina transferê ye"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Hate Betalkirin"
msgid "Failed"
diff --git a/po/lo.po b/po/lo.po
index 919e9ff705..71d22c2e3b 100644
--- a/po/lo.po
+++ b/po/lo.po
@@ -744,7 +744,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr ""
msgid "Failed"
diff --git a/po/lt.po b/po/lt.po
index 14f69d193a..5d78684b57 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -826,7 +826,7 @@ msgstr "Sustabdyti"
msgid "Waiting for transfer to begin"
msgstr "Laukiama perdavimo pradžios"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Atšaukta"
msgid "Failed"
diff --git a/po/mk.po b/po/mk.po
index 865431754f..a24446400a 100644
--- a/po/mk.po
+++ b/po/mk.po
@@ -806,7 +806,7 @@ msgstr "Стопирај"
msgid "Waiting for transfer to begin"
msgstr "Чекам да започне преносот"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Откажано"
msgid "Failed"
@@ -16667,7 +16667,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Не можам да ја отворам %s за запишување!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Размената на датотека не успеа. Другата страна веројатно откажа."
#~ msgid "Could not connect for transfer."
diff --git a/po/ml.po b/po/ml.po
index 9b70ddfd11..caf16d087e 100644
--- a/po/ml.po
+++ b/po/ml.po
@@ -788,7 +788,7 @@ msgstr "നിര്‍ത്തുക"
msgid "Waiting for transfer to begin"
msgstr "ഇടപാടു് ആരംഭിക്കുന്നതിനായി കാത്തിരിക്കുന്നു"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "റദ്ദാക്കിയിരിക്കുന്നു"
msgid "Failed"
diff --git a/po/mn.po b/po/mn.po
index 6217312a74..d6528b9e5d 100644
--- a/po/mn.po
+++ b/po/mn.po
@@ -774,7 +774,7 @@ msgstr "Зогсоох"
msgid "Waiting for transfer to begin"
msgstr "Файл шилжүүлэлт эхлүүлэхийг хүлээж байна"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Цуцлагдсан"
msgid "Failed"
@@ -15602,7 +15602,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Завсар хийхээр %sийг нээж чадсангүй!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Файл дамжуулалт амжилттгүй боллоо."
#~ msgid "Could not connect for transfer."
diff --git a/po/mr.po b/po/mr.po
index 3a1e1f6da6..530a3b84d1 100644
--- a/po/mr.po
+++ b/po/mr.po
@@ -779,7 +779,7 @@ msgstr "थांबा"
msgid "Waiting for transfer to begin"
msgstr "स्थानांतर सुरू करण्याची प्रतिक्षा करत आहे"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "रद्द केले"
msgid "Failed"
diff --git a/po/ms_MY.po b/po/ms_MY.po
index c2674ca2c6..b734d1ecdb 100644
--- a/po/ms_MY.po
+++ b/po/ms_MY.po
@@ -741,7 +741,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr ""
msgid "Failed"
diff --git a/po/my_MM.po b/po/my_MM.po
index 2dfe38ff61..057f736ddb 100644
--- a/po/my_MM.po
+++ b/po/my_MM.po
@@ -834,7 +834,7 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Waiting for transfer to begin"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelled"
msgid "Failed"
@@ -17057,7 +17057,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Could not open %s for writing!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "File transfer failed; other side probably cancelled."
#~ msgid "Could not connect for transfer."
diff --git a/po/nb.po b/po/nb.po
index 603b4f815b..4e5b66f64c 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -803,7 +803,7 @@ msgstr "Stopp"
msgid "Waiting for transfer to begin"
msgstr "Venter på at overføringen skal starte"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Avbrutt"
msgid "Failed"
@@ -16208,7 +16208,7 @@ msgstr "Du har ikke rettigheter til å avinstallere denne applikasjonen."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Klarte ikke åpne %s for skriving!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Filoverføringen mislyktes - sannsynligvis avbrutt på den andre siden."
diff --git a/po/ne.po b/po/ne.po
index e2216ebe04..2b2c9ae4f4 100644
--- a/po/ne.po
+++ b/po/ne.po
@@ -824,7 +824,7 @@ msgstr "हिपटप"
msgid "Waiting for transfer to begin"
msgstr "स्थानान्तरण सुरू गर्नकोलागि पर्खिरहेको"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "रद्द गरियो"
msgid "Failed"
@@ -17025,7 +17025,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "लेख्नका लागि %s खोल्न सकिदैन!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "फाइल स्थान्तरणमा असफल; अन्य साइड सम्भवत: रद्द गरियो ।"
#~ msgid "Could not connect for transfer."
diff --git a/po/nl.po b/po/nl.po
index a167177647..632920e02c 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -6,12 +6,12 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: pidgin 2.7.1\n"
+"Project-Id-Version: pidgin 2.7.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:18-0400\n"
-"PO-Revision-Date: 2010-07-25 14:26+0100\n"
-"Last-Translator: Gideon van Melle <translations@gvmelle.com>\n"
-"Language-Team: Dutch <translations@gmvelle.com>\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-01 09:08+0100\n"
+"Last-Translator: Dingoe <translations@gvmelle.com>\n"
+"Language-Team: Dutch <translations@gvmelle.com>\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -804,7 +804,7 @@ msgstr "Stoppen"
msgid "Waiting for transfer to begin"
msgstr "Wacht op starten van overdracht"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Geannuleerd"
msgid "Failed"
@@ -5970,8 +5970,8 @@ msgstr "De PINcode is ongeldig. Het kan uitsluiten cijfers bevatten [0-9]."
msgid "The two PINs you entered do not match."
msgstr "De twee PINcodes die u invulde zijn niet gelijk."
-msgid "The name you entered is invalid."
-msgstr "De naam die u invoerde is ongeldig."
+msgid "The Display Name you entered is invalid."
+msgstr "De schermnaam die u invoerde is ongeldig."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -6065,9 +6065,6 @@ msgstr ""
msgid "Connecting..."
msgstr "Bezig met Verbinden..."
-msgid "The Display Name you entered is invalid."
-msgstr "De schermnaam die u invoerde is ongeldig."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "De PINcode die u invulde heeft een ongeldige lengte [7-10]."
@@ -13133,13 +13130,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "We sluiten af, omdat een andere libpurple cliënt al actief is.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Media"
+msgstr "_Media"
-#, fuzzy
msgid "_Hangup"
-msgstr "Ophangen"
+msgstr "_Ophangen"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15325,7 +15320,7 @@ msgid ""
"is provided here for information purposes only. $_CLICK"
msgstr ""
"$(^Naam) is uitgegeven onder de GNU Generale Publieke Licentie (GPL). De "
-"licentie wordt hier slechts gegeven voor informatieve doeleinden. $_KLIK"
+"licentie wordt hier slechts gegeven voor informatieve doeleinden. $_CLICK"
#. Installer Subsection Detailed Description
msgid "A multi-platform GUI toolkit, used by Pidgin"
@@ -15467,6 +15462,9 @@ msgstr "Neem een kijkje op de Pidgin webpagina"
msgid "You do not have permission to uninstall this application."
msgstr "U mag dit programma niet verwijderen."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "De naam die u invoerde is ongeldig."
+
#~ msgid "/Media/_Hangup"
#~ msgstr "/Media/Op_hangen"
diff --git a/po/nn.po b/po/nn.po
index e72b3478df..42821657b9 100644
--- a/po/nn.po
+++ b/po/nn.po
@@ -1,11 +1,12 @@
#
# Yngve Spjeld Landro <l10n@landro.net>, 2010.
+#
msgid ""
msgstr ""
"Project-Id-Version: gtranslator\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 02:06-0400\n"
-"PO-Revision-Date: 2010-07-21 23:06+0100\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-01 22:11+0200\n"
"Last-Translator: Yngve Spjeld Landro <l10n@landro.net>\n"
"Language-Team: Norwegian Nynorsk <l10n@landro.net>\n"
"Language: nn\n"
@@ -796,7 +797,7 @@ msgstr "Stopp"
msgid "Waiting for transfer to begin"
msgstr "Ventar på at overføringa skal begynna"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Avbroten"
msgid "Failed"
@@ -5924,8 +5925,8 @@ msgstr "PIN er ugyldig - kan berre innehalda tala [0-9]."
msgid "The two PINs you entered do not match."
msgstr "Dei to PIN-ane du skreiv inn samsvarer ikkje."
-msgid "The name you entered is invalid."
-msgstr "Namnet du skreiv er ugyldig."
+msgid "The Display Name you entered is invalid."
+msgstr "Visingsnamnet du skreiv er ugyldig."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5944,9 +5945,8 @@ msgstr "Profil"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "Profilopplysningane dine er ikkje henta enno. Prøv igjen seinare."
-#, fuzzy
msgid "Your UID"
-msgstr "MXit-ID-en din"
+msgstr "UID-en din"
#. pin
#. pin (required)
@@ -6017,16 +6017,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Koplar til…"
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Namnet du skreiv er ugyldig."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "PIN-en du skreiv nyttar ei ulovleg lengd [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit-ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6054,13 +6050,11 @@ msgstr "Økta di har gått ut. Prøv igjen seinare."
msgid "Invalid country selected. Please try again."
msgstr "Du valde eit ugyldig land. Prøv igjen seinare."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "Brukarnamnet er ikkje registrert. Registrer deg først."
+msgstr "MXit-id-en du brukte er ikkje registrert. Registrer deg først."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Brukarnamnet er allereie registrert. Vel eit anna brukarnamn."
+msgstr "MXit-id-en er allereie registrert. Vel ein annan ein."
msgid "Internal error. Please try again later."
msgstr "Intern feil. Prøv igjen seinare."
@@ -6104,9 +6098,8 @@ msgstr "Avvisingsmelding"
msgid "Hidden Number"
msgstr "Skjult nummer"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "MXit-ID-en din"
+msgstr "MXit-id-en din…"
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6131,13 +6124,11 @@ msgid "_Room Name:"
msgstr "Rom_namn:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Du har fått e-post."
+msgstr "Du har invitert "
-#, fuzzy
msgid "Last Online"
-msgstr "Tilkopla"
+msgstr "Sist tilkopla"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -13035,13 +13026,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Avsluttar sidan en annan libpurple-klient allereie kjører.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Media"
+msgstr "_Media"
-#, fuzzy
msgid "_Hangup"
-msgstr "Legg på"
+msgstr "_Legg på"
#, c-format
msgid "%s wishes to start an audio/video session with you."
diff --git a/po/oc.po b/po/oc.po
index ad939c9540..be96b6b2c5 100644
--- a/po/oc.po
+++ b/po/oc.po
@@ -754,7 +754,7 @@ msgstr "Arrestar"
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Anullat"
msgid "Failed"
diff --git a/po/or.po b/po/or.po
index 9cd168bf55..bdb49bf17e 100644
--- a/po/or.po
+++ b/po/or.po
@@ -799,7 +799,7 @@ msgstr "ବନ୍ଦକର"
msgid "Waiting for transfer to begin"
msgstr "ସ୍ଥାନାନ୍ତରଣ ଆରମ୍ଭ ହେବାକୁ ଅପେକ୍ଷା କରୁଛି"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ବାତିଲ କରାଗଲା"
msgid "Failed"
diff --git a/po/pa.po b/po/pa.po
index a8747ba07c..64a06f98eb 100644
--- a/po/pa.po
+++ b/po/pa.po
@@ -8,10 +8,10 @@ msgid ""
msgstr ""
"Project-Id-Version: pa\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:18-0400\n"
-"PO-Revision-Date: 2010-01-26 05:27+0530\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-08 07:23+0530\n"
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
-"Language-Team: ਪੰਜਾਬੀ <punjabi-users@lists.sf.net>\n"
+"Language-Team: testLokalize <punjabi-users@lists.sf.net>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -64,9 +64,8 @@ msgstr ""
msgid "Error"
msgstr "ਗਲਤੀ"
-#, fuzzy
msgid "Account was not modified"
-msgstr "ਅਕਾਊਂਟ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"
+msgstr "ਅਕਾਊਂਟ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ"
msgid "Account was not added"
msgstr "ਅਕਾਊਂਟ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"
@@ -76,11 +75,11 @@ msgstr "ਇੱਕ ਅਕਾਊਂਟ ਦਾ ਯੂਜ਼ਰ ਨਾਂ ਖਾਲ
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "ਅਕਾਊਂਟ ਦਾ ਪਰੋਟੋਕਾਲ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਜਦੋਂ ਇਹ ਸਰਵਰ ਨਾਲ ਕੁਨਕੈਟ ਕੀਤਾ ਗਿਆ।"
msgid ""
"The account's username cannot be changed while it is connected to the server."
-msgstr ""
+msgstr "ਅਕਾਊਂਟ ਦਾ ਯੂਜ਼ਰ-ਨਾਂ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਜਦੋਂ ਇਹ ਸਰਵਰ ਨਾਲ ਕੁਨਕੈਟ ਕੀਤਾ ਗਿਆ।"
msgid "New mail notifications"
msgstr "ਨਵੀਂ ਮੇਲ ਨੋਟੀਫਿਕੇਸ਼ਨ"
@@ -785,7 +784,7 @@ msgstr "ਰੋਕੋ"
msgid "Waiting for transfer to begin"
msgstr "ਭੇਜਣ ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਉਡੀਕ ਜਾਰੀ"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ਰੱਦ ਹੈ"
msgid "Failed"
@@ -1251,9 +1250,8 @@ msgstr "ਗੱਲਬਾਤ ਵਿੱਚ ਹੋਰ ਵਿਸ਼ੇ"
msgid "Someone says your username in chat"
msgstr "ਕਿਸੇ ਨੇ ਤੁਹਾਡਾ ਨਾਂ ਗੱਲਬਾਤ ਦੌਰਾਨ ਲਿਆ ਹੈ"
-#, fuzzy
msgid "Attention received"
-msgstr "ਐਕਟੀਵੇਸ਼ਨ ਲੋੜੀਦੀ"
+msgstr "ਐਕਟੀਵੇਸ਼ਨ ਲੋੜੀਦੀ ਹੈ"
msgid "GStreamer Failure"
msgstr "ਜੀਸਟਰੀਮਰ ਫੇਲ੍ਹ"
@@ -1636,13 +1634,11 @@ msgstr "%s ਲਈ ਯੂਜ਼ਰ ਸੁਨੇਹਾ ਤਬਦੀਲ"
msgid "Set User Info"
msgstr "ਯੂਜ਼ਰ ਜਾਣਕਾਰੀ ਦਿਓ"
-#, fuzzy
msgid "This protocol does not support setting a public alias."
-msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਗੱਲਬਾਤ ਰੂਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।"
+msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਪਬਲਿਕ ਉਪ-ਨਾਂ ਲੈਣ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।"
-#, fuzzy
msgid "This protocol does not support fetching the public alias."
-msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਗੱਲਬਾਤ ਰੂਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।"
+msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਪਬਲਿਕ ਉਪ-ਨਾਂ ਲੈਣ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।"
msgid "Unknown"
msgstr "ਅਣਜਾਣ"
@@ -1664,7 +1660,7 @@ msgstr "ਸਰਟੀਫਿਕੇਟ ਉੱਤੇ ਭਰੋਸੇ ਨਹੀਂ
msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
-msgstr ""
+msgstr "ਸਰਟੀਫਿਕੇਟ ਹਾਲ ਲਾਗੂ ਨਹੀਂ ਹੈ। ਆਪਣੇ ਕੰਪਿਊਟਰ ਦੀ ਮਿਤੀ ਤੇ ਸਮਾਂ ਚੈੱਕ ਕਰੋ ਕਿ ਕੀ ਇਹ ਠੀਕ ਹੈ।"
msgid "The certificate has expired and should not be considered valid."
msgstr "ਸਰਟੀਫਿਕੇਟ ਦੀ ਮਿਆਦ ਪੁੱਗ ਚੁੱਕੀ ਹੈ ਅਤੇ ਜਾਇਜ਼ ਨਹੀਂ ਮੰਨਿਆ ਜਾ ਸਕਦਾ ਹੈ।"
@@ -3775,17 +3771,16 @@ msgstr "ਸਰਵਰ ਤੋਂ ਗਲਤ ਚੈਲੰਜ਼"
msgid "Server thinks authentication is complete, but client does not"
msgstr "ਸਰਵਰ ਸੋਚਦਾ ਹੈ ਕਿ ਪਰਮਾਣਕਿਤਾ ਪੂਰੀ ਹੋ ਗਈ ਹੈ, ਪਰ ਕਲਾਇਟ ਨਹੀਂ"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
-msgstr "ਸਰਵਰ ਨੂੰ ਇੱਕ ਗ਼ੈਰ-ਇੰਕ੍ਰਿਪਟਡ ਸਟਰੀਮ ਲਈ ਪਲੇਨ-ਟੈਕਸਟ ਪਰਮਾਣਕਿਤਾ ਦੀ ਲੋੜ ਹੈ।"
+msgstr "ਸਰਵਰ ਨੂੰ ਇੱਕ ਗ਼ੈਰ-ਇੰਕ੍ਰਿਪਟਡ ਸਟਰੀਮ ਲਈ ਪਲੇਨ-ਟੈਕਸਟ ਪਰਮਾਣਕਿਤਾ ਦੀ ਲੋੜ ਹੋ ਸਕਦੀ ਹੈ।"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s ਲਈ ਗ਼ੈਰ-ਇੰਕ੍ਰਿਪਟਡ ਕੁਨੈਕਸ਼ਨ ਉੱਤੇ ਪਲੇਨ-ਟੈਕਸਟ ਪਰਮਾਣਕਿਤਾ ਲੋੜੀਦੀ ਹੈ। ਕੀ ਇਹ ਪਰਮਾਣਿਕਤਾ ਮਨਜ਼ੂਰ "
-"ਕਰਕੇ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"
+"%s ਲਈ ਗ਼ੈਰ-ਇੰਕ੍ਰਿਪਟਡ ਕੁਨੈਕਸ਼ਨ ਉੱਤੇ ਪਲੇਨ-ਟੈਕਸਟ ਪਰਮਾਣਕਿਤਾ ਲੋੜੀਦੀ ਹੋ ਸਕਦੀ ਹੈ। ਕੀ ਇਹ ਪਰਮਾਣਿਕਤਾ "
+"ਮਨਜ਼ੂਰ ਕਰਕੇ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"
msgid "SASL authentication failed"
msgstr "SASL ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ"
@@ -3795,38 +3790,35 @@ msgstr "SASL ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ"
msgid "SASL error: %s"
msgstr "SASL ਗਲਤੀ: %s"
-#, fuzzy
msgid "Invalid Encoding"
-msgstr "ਗਲਤ ਇੰਪੁੱਟ ਹਾਲਤ"
+msgstr "ਗਲਤ ਇੰਕੋਡਿੰਗ"
-#, fuzzy
msgid "Unsupported Extension"
-msgstr "ਨਾਸਹਾਇਕ ਵਰਜਨ"
+msgstr "ਗ਼ੈਰ-ਸਹਾਇਕ ਇਕਸਟੈਨਸ਼ਨ"
msgid ""
"Unexpected response from the server. This may indicate a possible MITM "
"attack"
-msgstr ""
+msgstr "ਸਰਵਰ ਵਲੋਂ ਅਣਜਾਣ ਜਵਾਬ ਹੈ। ਇਹ ਸੰਭਵ MITM ਹਮਲੇ ਦਾ ਸੰਕੇਤ ਹੋ ਸਕਦਾ ਹੈ।"
msgid ""
"The server does support channel binding, but did not appear to advertise "
"it. This indicates a likely MITM attack"
msgstr ""
+"ਸਰਵਰ ਚੈਨਲ ਬਾਈਡਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ, ਪਰ ਐਲਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਪਦਾ ਹੈ। ਇਹ MITM ਹਮਲੇ ਦੇ ਸੰਕੇਤ "
+"ਹੋ ਸਕਦਾ ਹੈ।"
-#, fuzzy
msgid "Server does not support channel binding"
-msgstr "ਸਰਵਰ ਪਾਬੰਦੀ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ"
+msgstr "ਸਰਵਰ ਚੈਨਲ ਬਾਈਡਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ"
-#, fuzzy
msgid "Unsupported channel binding method"
-msgstr "ਨਾ-ਸਹਾਇਕ ਇੰਕੋਡਿੰਗ"
+msgstr "ਨਾ-ਸਹਾਇਕ ਚੈਨਲ ਬਾਈਡਿੰਗ ਢੰਗ"
msgid "User not found"
msgstr "ਯੂਜ਼ਰ ਮੌਜੂਦ ਨਹੀਂ ਹੈ"
-#, fuzzy
msgid "Invalid Username Encoding"
-msgstr "ਗਲਤ ਯੂਜ਼ਰ ਨਾਂ"
+msgstr "ਗਲਤ ਯੂਜ਼ਰ ਇੰਕੋਡਿੰਗ"
msgid "Resource Constraint"
msgstr "ਸਰੋਤ ਪਾਬੰਦੀ"
@@ -4144,9 +4136,8 @@ msgstr "ਪਿੰਗ ਟਾਈਮ-ਆਉਟ"
msgid "Invalid XMPP ID"
msgstr "ਗਲਤ XMPP ID"
-#, fuzzy
msgid "Invalid XMPP ID. Username portion must be set."
-msgstr "ਗਲਤ XMPP ID ਹੈ। ਡੋਮੇਨ ਸੈੱਟ ਕਰਨੀ ਲਾਜ਼ਮੀ ਹੈ।"
+msgstr "ਗਲਤ XMPP ID ਹੈ। ਯੂਜ਼ਰ-ਨਾਂ ਸੈੱਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ।"
msgid "Invalid XMPP ID. Domain must be set."
msgstr "ਗਲਤ XMPP ID ਹੈ। ਡੋਮੇਨ ਸੈੱਟ ਕਰਨੀ ਲਾਜ਼ਮੀ ਹੈ।"
@@ -4278,13 +4269,11 @@ msgstr "ਮੂਡ ਟੈਕਸਟ"
msgid "Allow Buzz"
msgstr "ਬੱਜ਼ ਮਨਜ਼ੂਰ"
-#, fuzzy
msgid "Mood Name"
-msgstr "ਮੱਧ ਨਾਂ"
+msgstr "ਮੂਡ ਨਾਂ"
-#, fuzzy
msgid "Mood Comment"
-msgstr "ਸੁਨੇਹੀ ਟਿੱਪਣੀ"
+msgstr "ਮੂਡ ਟਿੱਪਣੀ"
#. primitive
#. ID
@@ -4578,9 +4567,8 @@ msgstr "ਇੱਕ ਸਰੋਤ ਚੁਣੋ"
msgid "Initiate Media"
msgstr "ਮੀਡਿਆ ਸ਼ੁਰੂ"
-#, fuzzy
msgid "Account does not support PEP, can't set mood"
-msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਗੱਲਬਾਤ ਰੂਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।"
+msgstr "ਅਕਾਊਂਟ PEP ਲਈ ਸਹਾਇਕ ਨਹੀਂ, ਮੂਡ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"
msgid "config: Configure a chat room."
msgstr "config: Configure a chat room."
@@ -4634,9 +4622,8 @@ msgstr "ping &lt;jid&gt;:\tਇੱਕ ਯੂਜ਼ਰ/ਭਾਗ/ਸਰਵਰ ਪ
msgid "buzz: Buzz a user to get their attention"
msgstr "ਬੱਜ਼: ਯੂਜ਼ਰ ਦਾ ਧਿਆਨ ਦੁਆਉਣ ਵਾਸਤੇ ਉਸ ਨੂੰ ਬੱਜ਼ ਭੇਜੋ"
-#, fuzzy
msgid "mood: Set current user mood"
-msgstr "ਠੀਕ ਯੂਜ਼ਰ ਚੁਣੋ"
+msgstr "ਮੂਡ: ਮੌਜੂਦਾ ਯੂਜ਼ਰ ਮੂਡ ਸੈੱਟ ਕਰੋ"
msgid "Extended Away"
msgstr "ਪਹੁੰਚ ਤੋਂ ਦੂਰ"
@@ -4714,18 +4701,17 @@ msgstr "XMPP ਗਲਤੀ ਸੁਨੇਹਾ"
msgid "(Code %s)"
msgstr "(ਕੋਡ %s)"
-#, fuzzy
msgid "A custom smiley in the message is too large to send."
-msgstr "ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ ਅਸਫਲ ਹੈ। ਸੁਨੇਹਾ ਬਹੁਤ ਵੱਡਾ ਹੈ।"
+msgstr "ਸੁਨੇਹੇ 'ਚ ਪਸੰਦੀਦਾ ਸਮਾਈਲੀ ਬਹੁਤ ਵੱਡਾ ਹੈ।"
msgid "XMPP stream header missing"
-msgstr ""
+msgstr "XMPP ਸਟਰੀਮ ਹੈੱਡਰ ਸੰਭਵ ਨਹੀਂ ਹੈ"
msgid "XMPP Version Mismatch"
-msgstr ""
+msgstr "XMPP ਵਰਜਨ ਨਹੀਂ ਮਿਲਦਾ"
msgid "XMPP stream missing ID"
-msgstr ""
+msgstr "XMPP ਸਟੀਰਮ ID ਗੁੰਮ ਹੈ"
msgid "XML Parse error"
msgstr "XML ਪਾਰਸ ਗਲਤੀ"
@@ -4784,7 +4770,7 @@ msgid "Unable to send file to %s, user does not support file transfers"
msgstr "ਫਾਇਲ %s ਨੂੰ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ ਹੈ, ਫਾਇਲ ਟਰਾਂਸਫਰ ਲਈ ਸਹਿਯੋਗੀ ਨਹੀਂ"
msgid "File Send Failed"
-msgstr "ਫਾਇਲ ਭੇਜਣਾ ਅਸਫਲ"
+msgstr "ਫਾਇਲ ਭੇਜਣ ਲਈ ਫੇਲ੍ਹ"
#, c-format
msgid "Unable to send file to %s, invalid JID"
@@ -4803,31 +4789,26 @@ msgstr "%s ਨੂੰ ਫਾਇਲ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ ਹੈ,
msgid "Please select the resource of %s to which you would like to send a file"
msgstr "ਚੁਣੋ ਕਿ ਕਿਹੜੇ %s ਦੇ ਸਰੋਤ ਤੁਸੀਂ ਇੱਕ ਫਾਇਲ ਤੋਂ ਤੁਸੀਂ ਭੇਜਣੇ ਚਾਹੁੰਦੇ ਹੋ"
-#, fuzzy
msgid "Afraid"
-msgstr "ਅਰਬੀ"
+msgstr "ਡਰਿਆ"
-#, fuzzy
msgid "Amazed"
-msgstr "ਸ਼ਰਮਸ਼ਾਰ"
+msgstr "ਡੌਰ-ਭੌਰ"
-#, fuzzy
msgid "Amorous"
-msgstr "ਸ਼ਾਨਦਾਰ"
+msgstr "ਆਸ਼ਕਾਨਾ"
msgid "Angry"
msgstr "ਗੁੱਸੇ ਵਿੱਚ"
-#, fuzzy
msgid "Annoyed"
-msgstr "ਪਾਬੰਦੀਸ਼ੁਦਾ"
+msgstr "ਜ਼ਿੱਦੀ"
msgid "Anxious"
msgstr "ਬੇਚੈਨ"
-#, fuzzy
msgid "Aroused"
-msgstr "ਤੁਸੀਂ ਭੇਜਿਆ"
+msgstr "ਜਾਗਦਾ"
msgid "Ashamed"
msgstr "ਸ਼ਰਮਸ਼ਾਰ"
@@ -4835,279 +4816,231 @@ msgstr "ਸ਼ਰਮਸ਼ਾਰ"
msgid "Bored"
msgstr "ਅੱਕਿਆ"
-#, fuzzy
msgid "Brave"
-msgstr "ਸੰਭਾਲੋ"
+msgstr "ਦਲੇਰ"
-#, fuzzy
msgid "Calm"
-msgstr "ਰੀਲੇਮ"
+msgstr "ਸ਼ਾਂਤ"
-#, fuzzy
msgid "Cautious"
-msgstr "ਗੱਲਬਾਤ"
+msgstr "ਚੌਕਸ"
-#, fuzzy
msgid "Cold"
-msgstr "ਗੂੜੇ"
+msgstr "ਠੰਡ"
-#, fuzzy
msgid "Confident"
-msgstr "ਟਕਰਾ"
+msgstr "ਹੌਸਲੇ ਨਾਲ"
-#, fuzzy
msgid "Confused"
-msgstr "ਜਾਰੀ ਰੱਖੋ"
+msgstr "ਉਲਝਿਆ"
-#, fuzzy
msgid "Contemplative"
-msgstr "ਸੰਪਰਕ"
+msgstr "ਅੰਤਰ ਧਿਆਨ"
-#, fuzzy
msgid "Contented"
-msgstr "ਜੁੜਿਆ"
+msgstr "ਪਰਸੰਨ"
-#, fuzzy
msgid "Cranky"
-msgstr "ਕੰਪਨੀ"
+msgstr "ਵੈਹਮੀ"
msgid "Crazy"
-msgstr ""
+msgstr "ਝੱਲਾ"
-#, fuzzy
msgid "Creative"
-msgstr "ਬਣਾਓ"
+msgstr "ਸਿਰਜਣਸ਼ੀਲ"
-#, fuzzy
msgid "Curious"
-msgstr "ਸ਼ਾਨਦਾਰ"
+msgstr "ਜਿਆਸੂ"
-#, fuzzy
msgid "Dejected"
-msgstr "ਇਨਕਾਰ ਕੀਤਾ"
+msgstr "ਨਿੰਮੌਝੂਣਾ"
-#, fuzzy
msgid "Depressed"
-msgstr "ਹਟਾਇਆ"
+msgstr "ਦੁਖੀ"
-#, fuzzy
msgid "Disappointed"
-msgstr "ਕੁਨੈਕਸ਼ਨ ਬੰਦ ਹੈ।"
+msgstr "ਨਿਰਾਸ਼"
msgid "Disgusted"
-msgstr ""
+msgstr "ਅੱਕਿਆ"
-#, fuzzy
msgid "Dismayed"
-msgstr "ਆਯੋਗ ਹੈ"
+msgstr "ਡਰਿਆ"
-#, fuzzy
msgid "Distracted"
-msgstr "ਅੱਡ"
+msgstr "ਬੇਧਿਆਨਾ"
msgid "Embarrassed"
-msgstr ""
+msgstr "ਪਰੇਸ਼ਾਨ"
-#, fuzzy
msgid "Envious"
-msgstr "ਬੇਚੈਨ"
+msgstr "ਈਰਖਾਲੂ"
msgid "Excited"
msgstr "ਜੋਸ਼ ਵਿੱਚ"
-#, fuzzy
msgid "Flirtatious"
-msgstr "ਸ਼ਾਨਦਾਰ"
+msgstr "ਨਖ਼ਰੇ"
-#, fuzzy
msgid "Frustrated"
-msgstr "ਪਹਿਲਾਂ ਨਾਂ"
+msgstr "ਨਿਰਾਸ਼"
msgid "Grateful"
-msgstr ""
+msgstr "ਇਹਸਾਨਮੰਦ"
-#, fuzzy
msgid "Grieving"
-msgstr "ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ..."
+msgstr "ਸੋਗੀ"
msgid "Grumpy"
-msgstr "ਗਰੁੰਪੀ"
+msgstr "ਰੁੱਖਾ"
-#, fuzzy
msgid "Guilty"
-msgstr "ਸ਼ਹਿਰ"
+msgstr "ਸ਼ਰਮਿੰਦਾ"
msgid "Happy"
msgstr "ਖੁਸ਼"
msgid "Hopeful"
-msgstr ""
+msgstr "ਆਸਵੰਦ"
msgid "Hot"
msgstr "ਹਾਟ"
msgid "Humbled"
-msgstr ""
+msgstr "ਨਿਮਾਣਾ"
msgid "Humiliated"
-msgstr ""
+msgstr "ਜਲੀਲ ਕੀਤਾ"
-#, fuzzy
msgid "Hungry"
-msgstr "ਗੁੱਸੇ ਵਿੱਚ"
+msgstr "ਭੁੱਖਾ"
-#, fuzzy
msgid "Hurt"
-msgstr "ਹਾਸਾ"
+msgstr "ਬਦਸਲੂਕੀ"
msgid "Impressed"
-msgstr ""
+msgstr "ਪਰਭਾਵਿਤ"
-#, fuzzy
msgid "In awe"
-msgstr "ਪਿਆਰ ਨਾਲ"
+msgstr "ਸਨਮਾਨ 'ਚ"
msgid "In love"
msgstr "ਪਿਆਰ ਨਾਲ"
-#, fuzzy
msgid "Indignant"
-msgstr "ਇੰਡੋਨੇਸ਼ੀਆਈ"
+msgstr "ਰੁੱਸਿਆ"
-#, fuzzy
msgid "Interested"
-msgstr "ਦਿਲਚਸਪੀਆਂ"
+msgstr "ਉਤਸਕ"
-#, fuzzy
msgid "Intoxicated"
-msgstr "ਸੱਦਾ ਭੇਜਿਆ"
+msgstr "ਮਦਹੋਸ਼"
msgid "Invincible"
msgstr "ਅਜਿੱਤ"
msgid "Jealous"
-msgstr "ਈਰਖਾਲੂ"
+msgstr "ਈਰਖਈ"
-#, fuzzy
msgid "Lonely"
-msgstr "ਬਾਂਦਰ"
+msgstr "ਇੱਕਲੇ"
-#, fuzzy
msgid "Lost"
-msgstr "ਸਭ ਤੋਂ ਉੱਚੀ"
+msgstr "ਗੁਆਚਿਆ"
msgid "Lucky"
-msgstr ""
+msgstr "ਕਿਸਮਤ ਵਾਲਾ"
-#, fuzzy
msgid "Mean"
-msgstr "ਜਰਮਨ"
+msgstr "ਸ਼ੂਮ"
-#, fuzzy
msgid "Moody"
-msgstr "ਮੂਡ"
+msgstr "ਦਿਲਗੀਰ"
msgid "Nervous"
-msgstr ""
+msgstr "ਬੌਂਦਲਿਆ"
-#, fuzzy
msgid "Neutral"
-msgstr "ਵੇਰਵਾ"
+msgstr "ਅਨਿਸ਼ਚਤ"
-#, fuzzy
msgid "Offended"
-msgstr "ਆਫਲਾਈਨ"
+msgstr "ਦੋਸ਼ੀ"
msgid "Outraged"
-msgstr ""
+msgstr "ਅਤਿੱਆਚਾਰੀ"
-#, fuzzy
msgid "Playful"
-msgstr "ਚਲਾਓ"
+msgstr "ਰੌਣਕੀ"
-#, fuzzy
msgid "Proud"
-msgstr "ਉੱਚੀ"
+msgstr "ਮਜ਼ਾਜੀ"
-#, fuzzy
msgid "Relaxed"
-msgstr "ਅਸਲੀ ਨਾਂ"
+msgstr "ਸੁਸਤ"
-#, fuzzy
msgid "Relieved"
-msgstr "ਮਿਲੇ"
+msgstr "ਆਰਾਮ 'ਚ"
-#, fuzzy
msgid "Remorseful"
-msgstr "ਹਟਾਓ"
+msgstr "ਪਸ਼ਚਾਤਾਪਪੂਰਨ"
-#, fuzzy
msgid "Restless"
-msgstr "ਰਜਿਸਟਰ"
+msgstr "ਬੇਚੈਨ"
msgid "Sad"
msgstr "ਉਦਾਸ"
-#, fuzzy
msgid "Sarcastic"
-msgstr "ਮਰਾਠੀ"
+msgstr "ਵਿਅੰਗਮਈ"
msgid "Satisfied"
-msgstr ""
+msgstr "ਸੰਤੁਸ਼ਟ"
-#, fuzzy
msgid "Serious"
-msgstr "ਸ਼ਾਨਦਾਰ"
+msgstr "ਗੰਭੀਰ"
-#, fuzzy
msgid "Shocked"
-msgstr "ਪਾਬੰਦੀ"
+msgstr "ਸਦਮਾ"
msgid "Shy"
-msgstr ""
+msgstr "ਸੰਗਾਊ"
msgid "Sick"
msgstr "ਬੀਮਾਰ"
#. Sleepy / Tired
msgid "Sleepy"
-msgstr "ਉਬਾਸੀਆਂ"
+msgstr "ਉਨੀਂਦਾ"
msgid "Spontaneous"
-msgstr ""
+msgstr "ਲਗਾਤਾਰ"
-#, fuzzy
msgid "Stressed"
-msgstr "ਸਪੀਡ"
+msgstr "ਦਬਾਅ 'ਚ"
-#, fuzzy
msgid "Strong"
-msgstr "ਗੀਤ"
+msgstr "ਮਜ਼ਬੂਤ"
msgid "Surprised"
-msgstr ""
+msgstr "ਹੈਰਾਨ"
msgid "Thankful"
-msgstr ""
+msgstr "ਧੰਨਵਾਦੀ"
msgid "Thirsty"
-msgstr ""
+msgstr "ਇੱਛਕ"
-#, fuzzy
msgid "Tired"
-msgstr "ਫਾਇਰ"
+msgstr "ਥੱਕਿਆ/ਥੱਕੀ"
-#, fuzzy
msgid "Undefined"
-msgstr "ਹੇਠਾਂ ਲਾਈਨ"
+msgstr "ਅਸਪਸ਼ਟ"
-#, fuzzy
msgid "Weak"
-msgstr "ਧੱਫਾ"
+msgstr "ਹਲਕਾ"
-#, fuzzy
msgid "Worried"
-msgstr "ਅੱਕਿਆ"
+msgstr "ਚਿੰਤਾਤੁਰ"
msgid "Set User Nickname"
msgstr "ਯੂਜ਼ਰ ਨਾਂ ਸੈੱਟ ਕਰੋ"
@@ -5352,12 +5285,12 @@ msgstr "%s ਨੇ ਸੈਨਤ ਭੇਜੀ, ਪਰ ਇਸ ਨੂੰ ਸੰਭ
#, c-format
msgid "%s sent a voice clip. <a href='audio://%s'>Click here to play it</a>"
-msgstr "%s ਨੇ ਵੀਡਿਓ ਕਲਿੱਪ ਭੇਜੀ। <a href='audio://%s'>ਚਲਾਉਣ ਲਈ ਕਲਿੱਕ ਕਰੋ</a>"
+msgstr "%s ਨੇ ਵਿਡੀਓ ਕਲਿੱਪ ਭੇਜੀ। <a href='audio://%s'>ਚਲਾਉਣ ਲਈ ਕਲਿੱਕ ਕਰੋ</a>"
# , c-format
#, c-format
msgid "%s sent a voice clip, but it could not be saved"
-msgstr "%s ਨੇ ਵੀਡਿਓ ਕਲਿੱਪ ਭੇਜੀ, ਪਰ ਸੰਭਾਲੀ ਨਹੀਂ ਜਾ ਸਕੀ।"
+msgstr "%s ਨੇ ਵਿਡੀਓ ਕਲਿੱਪ ਭੇਜੀ, ਪਰ ਸੰਭਾਲੀ ਨਹੀਂ ਜਾ ਸਕੀ।"
# , c-format
#, c-format
@@ -5701,9 +5634,8 @@ msgstr "HTTP ਢੰਗ ਸਰਵਰ"
msgid "Show custom smileys"
msgstr "ਕਸਟਮ ਸਮਾਇਲੀ ਵੇਖੋ"
-#, fuzzy
msgid "Allow direct connections"
-msgstr "ਕੁਨੈਕਸ਼ਨ ਬਣਾਉਣ ਲਈ ਅਸਫਲ ਹੈ।"
+msgstr "ਸਿੱਧਾ ਕੁਨੈਕਸ਼ਨ ਮਨਜ਼ੂਰ ਹੈ"
msgid "nudge: nudge a user to get their attention"
msgstr "nudge: ਯੂਜ਼ਰ ਦਾ ਧਿਆਨ ਖਿੱਚਣ ਵਾਸਤੇ ਸੈਨਤ (ਸੰਕੇਤ) ਮਾਰੋ"
@@ -5902,8 +5834,8 @@ msgstr "PIN ਗਲਤ ਹੈ। ਇਸ ਵਿੱਚ ਕੇਵਲ ਅੰਕ [0-9]
msgid "The two PINs you entered do not match."
msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤੇ ਦੋਵੇਂ ਪਿੰਨ ਆਪਸ 'ਚ ਮਿਲਦੇ ਨਹੀਂ ਹਨ।"
-msgid "The name you entered is invalid."
-msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ ਨਾਂ ਗਲਤ ਹੈ।"
+msgid "The Display Name you entered is invalid."
+msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ ਡਿਸਪਲੇਅ ਨਾਂ ਗਲਤ ਹੈ।"
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5922,7 +5854,7 @@ msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "ਤੁਹਾਡੀ ਪਰੋਫਾਇਲ ਜਾਣਕਾਰੀ ਹਾਲੇ ਲਈ ਨਹੀਂ ਗਈ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
msgid "Your UID"
-msgstr ""
+msgstr "ਤੁਹਾਡਾ UID"
#. pin
#. pin (required)
@@ -5990,16 +5922,12 @@ msgstr "MXit ਸਰਵਰ ਨਾਲ ਕੁਨੈਕਟ ਹੋਣ ਲਈ ਅਸ
msgid "Connecting..."
msgstr "ਕੁਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ ਨਾਂ ਗਲਤ ਹੈ।"
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤੇ PIN ਦੀ ਲੰਬਾਈ ਗਲਤ ਹੈ [7-10]"
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6027,13 +5955,11 @@ msgstr "ਤੁਹਾਡੇ ਸ਼ੈਸ਼ਨ ਦੀ ਮਿਆਦ ਪੁੱਗ
msgid "Invalid country selected. Please try again."
msgstr "ਗਲਤ ਦੇਸ਼ ਚੁਣਿਆ। ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "ਯੂਜ਼ਰ-ਨਾਂ ਰਜਿਸਟਰ ਨਹੀਂ ਹੈ। ਪਹਿਲਾਂ ਰਜਿਸਟਰ ਕਰੋ ਜੀ।"
+msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ MXit ID ਰਜਿਸਟਰ ਨਹੀਂ ਹੈ। ਪਹਿਲਾਂ ਰਜਿਸਟਰ ਕਰੋ ਜੀ।"
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "ਯੂਜ਼ਰ-ਨਾਂ ਪਹਿਲਾਂ ਹੀ ਰਜਿਸਟਰ ਹੈ। ਵੱਖਰਾ ਯੂਜ਼ਰ ਨਾਂ ਚੁਣੋ ਜੀ।"
+msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ MXit ID ਪਹਿਲਾਂ ਹੀ ਰਜਿਸਟਰ ਹੈ। ਵੱਖਰਾ ਚੁਣੋ ਜੀ।"
msgid "Internal error. Please try again later."
msgstr "ਅੰਦਰੂਨੀ ਗਲਤੀ। ਬਾਅਦ 'ਚ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
@@ -6070,17 +5996,15 @@ msgstr "ਮੇਨੂ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."
msgid "Status Message"
msgstr "ਹਾਲਤ ਸੁਨੇਹਾ"
-#, fuzzy
msgid "Rejection Message"
-msgstr "ਪ੍ਰਾਪਤ ਹੋਏ ਸੁਨੇਹੇ"
+msgstr "ਇਨਕਾਰ ਸੁਨੇਹਾ"
#. hidden number
msgid "Hidden Number"
msgstr "ਨੰਬਰ ਓਹਲੇ"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Yahoo ID..."
+msgstr "ਤੁਹਾਡਾ MXit ID..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6095,26 +6019,21 @@ msgstr "ਸਵਾਗਤੀ-ਸਕਰੀਨ ਪੋਪਅੱਪ ਚਾਲੂ"
# , c-format
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "ਤੁਹਾਨੂੰ ਠੁੱਡਾ ਮਾਰਿਆ: (%s)"
+msgstr "ਤੁਹਾਨੰ ਇਸ ਮਲਟੀMX ਤੋਂ ਕਿੱਕ ਕੀਤਾ ਗਿਆ।"
-#, fuzzy
msgid "was kicked"
-msgstr "ਗਲਤ ਟਿਕਟ"
+msgstr "ਕਿੱਕ ਕੀਤਾ"
-#, fuzzy
msgid "_Room Name:"
-msgstr "ਰੂਮ(_R):"
+msgstr "ਰੂਮ ਨਾਂ(_R):"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "ਤੁਹਾਨੂੰ ਮੇਲ ਆਈ ਹੈ!"
+msgstr "ਤੁਹਾਨੂੰ ਸੱਦਾ ਹੈ"
-#, fuzzy
msgid "Last Online"
-msgstr "ਆਨਲਾਈਨ"
+msgstr "ਆਖਰੀ ਆਨਲਾਈਨ"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -6839,9 +6758,9 @@ msgstr "ਸਰਵਰ ਐਡਰੈੱਸ"
msgid "Server port"
msgstr "ਸਰਵਰ ਪੋਰਟ"
-#, fuzzy, c-format
+#, c-format
msgid "Received unexpected response from %s: %s"
-msgstr "%s ਤੋਂ ਅਚਾਨਕ ਜਵਾਬ ਮਿਲਿਆ"
+msgstr "%s ਤੋਂ ਅਚਾਨਕ ਜਵਾਬ ਮਿਲਿਆ: %s"
#, c-format
msgid "Received unexpected response from %s"
@@ -6865,14 +6784,16 @@ msgid ""
"Server requested that you fill out a CAPTCHA in order to sign in, but this "
"client does not currently support CAPTCHAs."
msgstr ""
+"ਸਰਵਰ ਨੇ ਮੰਗ ਕੀਤੀ ਹੈ ਕਿ ਤੁਸੀਂ ਸਾਈਨ ਕਰਨ ਲਈ CAPTCHA ਭਰੋ, ਪਰ ਇਹ ਕਲਾਇਟ CAPTCHA ਲਈ ਸਹਾਇਕ "
+"ਨਹੀਂ ਹੈ।"
msgid "AOL does not allow your screen name to authenticate here"
msgstr "AOL ਤੁਹਾਡੇ ਸਕਰੀਨ ਨਾਂ ਨੂੰ ਇੱਥੇ ਪਰਮਾਣਿਤ ਕਰਨ ਨਹੀਂ ਦਿੰਦਾ ਹੈ।"
# , c-format
-#, fuzzy, c-format
+#, c-format
msgid "Error requesting %s"
-msgstr "%s ਮੰਗ ਦੌਰਾਨ ਗਲਤੀ: %s"
+msgstr "%s ਮੰਗ ਦੌਰਾਨ ਗਲਤੀ"
msgid "Could not join chat room"
msgstr "ਚੈਟ ਰੂਮ ਵਿੱਚ ਦਾਖਲ ਨਹੀਂ ਹੋਇਆ ਜਾ ਸਕਿਆ"
@@ -6941,104 +6862,88 @@ msgid "Unable to send message to %s: %s"
msgstr "%s ਨੂੰ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ: %s"
msgid "Thinking"
-msgstr ""
+msgstr "ਸੋਚ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "Shopping"
-msgstr "ਲਿਖਣਾ ਬੰਦ ਕੀਤਾ"
+msgstr "ਖਰੀਦਦਾਰੀ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "Questioning"
-msgstr "ਸਵਾਲ ਡਾਈਲਾਗ"
+msgstr "ਸਵਾਲ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "Eating"
-msgstr "ਪੇਜ਼ਿੰਗ"
+msgstr "ਖਾਣਾ ਖਾ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "Watching a movie"
-msgstr "ਇੱਕ ਖੇਡ ਖੇਡੀ ਜਾ ਰਹੀ ਹੈ"
+msgstr "ਫਿਲਮ ਦੇ ਰਿਹਾ ਹਾਂ"
msgid "Typing"
msgstr "ਲਿਖ ਰਿਹਾ/ਰਹੀ ਹੈ"
-#, fuzzy
msgid "At the office"
-msgstr "ਦਫ਼ਤਰ 'ਚ ਨਹੀਂ"
+msgstr "ਦਫ਼ਤਰ 'ਚ ਹਾਂ"
msgid "Taking a bath"
-msgstr ""
+msgstr "ਇਸ਼ਨਾਨ ਕਰ ਰਿਹਾ ਹਾਂ"
msgid "Watching TV"
-msgstr ""
+msgstr "TV ਵੇਖਿਆ ਜਾ ਰਿਹਾ ਹੈ"
-#, fuzzy
msgid "Having fun"
-msgstr "ਹੈਂਡ ਅੱਪ"
+msgstr "ਮੌਜਾਂ ਕਰਦਾ"
-#, fuzzy
msgid "Sleeping"
-msgstr "ਉਬਾਸੀਆਂ"
+msgstr "ਸੌ ਰਹੇ"
msgid "Using a PDA"
-msgstr ""
+msgstr "PDA ਦੀ ਵਰਤੋਂ"
-#, fuzzy
msgid "Meeting friends"
-msgstr "IM ਦੋਸਤ"
+msgstr "ਦੋਸਤਾਂ ਨਾਲ ਮਿਲ ਰਹੇ"
-#, fuzzy
msgid "On the phone"
msgstr "ਫੋਨ ਉੱਤੇ"
-#, fuzzy
msgid "Surfing"
-msgstr "ਆਵਿਰਤੀ"
+msgstr "ਸਰਫ਼ ਕਰ ਰਹੇ"
#. "I am mobile." / "John is mobile."
msgid "Mobile"
msgstr "ਮੋਬਾਇਲ"
msgid "Searching the web"
-msgstr ""
+msgstr "ਵੈੱਬ ਉੱਤੇ ਖੋਜ ਜਾਰੀ"
msgid "At a party"
-msgstr ""
+msgstr "ਪਾਰਟੀ 'ਚ"
msgid "Having Coffee"
-msgstr ""
+msgstr "ਕਾਫ਼ੀ ਪੀ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
#. Playing video games
-#, fuzzy
msgid "Gaming"
-msgstr "ਯੂਜ਼ਰ ਗੇਮ"
+msgstr "ਖੇਡਾਂ"
msgid "Browsing the web"
-msgstr ""
+msgstr "ਵੈੱਬ ਬਰਾਊਜ਼ ਕਰੋ"
-#, fuzzy
msgid "Smoking"
-msgstr "ਗੀਤ"
+msgstr "ਸਿਗਰਟ ਪੀ ਰਹੇ"
-#, fuzzy
msgid "Writing"
-msgstr "ਕੰਮ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
+msgstr "ਲਿਖ ਰਹੇ"
#. Drinking [Alcohol]
-#, fuzzy
msgid "Drinking"
-msgstr "ਕੰਮ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
+msgstr "ਪੈੱਗ ਲਾ ਰਹੇ"
msgid "Listening to music"
msgstr "ਸੰਗੀਤ ਸੁਣ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "Studying"
-msgstr "ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ"
+msgstr "ਪੜ੍ਹ ਰਿਹਾ/ਰਹੀ ਹਾਂ"
-#, fuzzy
msgid "In the restroom"
-msgstr "ਦਿਲਚਸਪੀਆਂ"
+msgstr "ਆਰਾਮ-ਕਮਰੇ 'ਚ"
msgid "Received invalid data on connection with server"
msgstr "ਸਰਵਰ ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਉੱਤੇ ਗਲਤ ਡਾਟਾ ਮਿਲਿਆ ਹੈ।"
@@ -7141,7 +7046,7 @@ msgid "Games"
msgstr "ਖੇਡਾਂ"
msgid "ICQ Xtraz"
-msgstr ""
+msgstr "ICQ Xtraz"
msgid "Add-Ins"
msgstr "ਹੋਰ"
@@ -7209,25 +7114,20 @@ msgstr "ਵੈਬ ਜਾਣਕਾਰ"
msgid "Invisible"
msgstr "ਅਦਿੱਖ"
-#, fuzzy
msgid "Evil"
-msgstr "ਈਮੇਲ"
+msgstr "ਬੁਰਾ"
-#, fuzzy
msgid "Depression"
-msgstr "ਕਿੱਤਾ"
+msgstr "ਉਦਾਸੀ"
-#, fuzzy
msgid "At home"
-msgstr "ਮੇਰੇ ਬਾਰੇ"
+msgstr "ਘਰੇ"
-#, fuzzy
msgid "At work"
-msgstr "ਨੈੱਟਵਰਕ"
+msgstr "ਕੰਮ ਉੱਤੇ"
-#, fuzzy
msgid "At lunch"
-msgstr "ਦੁਪੈਹਰ ਦੇ ਖਾਣੇ ਲਈ ਬਾਹਰ"
+msgstr "ਦੁਪੈਹਰ ਦੇ ਖਾਣੇ ਲਈ"
msgid "IP Address"
msgstr "IP ਐਡਰੈੱਸ"
@@ -7704,9 +7604,8 @@ msgstr "ਤੁਹਾਡਾ IM ਭੇਜਿਆ ਨਹੀਂ ਸੀ ਗਿਆ।
msgid "iTunes Music Store Link"
msgstr "iTunes ਸੰਗੀਤ ਸਟੋਰ ਲਿੰਕ"
-#, fuzzy
msgid "Lunch"
-msgstr "ਫਿੰਚ"
+msgstr "ਦੁਪਹਿਰ ਦਾ ਖਾਣਾ"
#, c-format
msgid "Buddy Comment for %s"
@@ -7740,9 +7639,8 @@ msgstr "AIM ਜਾਣਕਾਰੀ ਲਵੋ"
msgid "Edit Buddy Comment"
msgstr "ਬੱਡੀ ਟਿੱਪਣੀ ਸੋਧ"
-#, fuzzy
msgid "Get X-Status Msg"
-msgstr "ਸਥਿਤੀ ਸੁਨੇਹਾ ਲਵੋ"
+msgstr "X-ਹਾਲਤ ਸੁਨੇਹਾ ਲਵੋ"
msgid "End Direct IM Session"
msgstr "ਸਿੱਧਾ IM ਸ਼ੈਸ਼ਨ ਬੰਦ ਕੀਤਾ"
@@ -7870,10 +7768,10 @@ msgid "Invalid SNAC"
msgstr "ਗਲਤ SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "ਸਰਵਰ ਰੇਟ ਲਿਮਟ ਵੱਧ ਗਈ"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "ਕਲਾਇਟ ਰੇਟ ਲਿਮਟ ਵੱਧ ਗਈ"
msgid "Service unavailable"
msgstr "ਸਰਵਿਸ ਉਪਲੱਬਧ ਨਹੀਂ"
@@ -8218,9 +8116,8 @@ msgid "Admin"
msgstr "ਐਡਮਿਨ"
#. XXX: Should this be "Topic"?
-#, fuzzy
msgid "Room Title"
-msgstr "ਰੂਮ ਲਿਸਟ"
+msgstr "ਰੂਮ ਟਾਈਟਲ"
msgid "Notice"
msgstr "ਨੋਟਿਸ"
@@ -10109,9 +10006,8 @@ msgstr "ਚੈਟ ਰੂਮ ਭਾਸ਼ਾ"
msgid "Ignore conference and chatroom invitations"
msgstr "ਕਨਫਰੰਸ ਅਤੇ ਚੈਟ-ਰੂਮ ਸੱਦੇ ਅਣਡਿੱਠੇ ਕਰੋ"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "SSL ਕੁਨੈਕਸ਼ਨਾਂ ਲਈ ਅਕਾਊਂਟ ਪਰਾਕਸੀ ਵਰਤੋਂ"
+msgstr "HTTP ਅਤੇ HTTPS ਕੁਨੈਕਸ਼ਨਾਂ ਲਈ ਅਕਾਊਂਟ ਪਰਾਕਸੀ ਵਰਤੋਂ"
msgid "Chat room list URL"
msgstr "ਗੱਲਬਾਤ ਰੂਮ ਲਿਸਟ Url"
@@ -10181,13 +10077,12 @@ msgstr ""
"ਅਕਾਊਂਟ ਲਾਕ ਹੋਇਆ: ਅਣਜਾਣ ਕਾਰਨ। Yahoo! ਵੈਬਸਾਇਟ ਉੱਤੇ ਲਾਗਇਨ ਕਰਨ ਨਾਲ ਸਮੱਸਿਆ ਹੱਲ ਹੋ ਸਕਦੀ ਹੈ।"
#. indicates a lock due to logging in too frequently
-#, fuzzy
msgid ""
"Account locked: You have been logging in too frequently. Wait a few minutes "
"before trying to connect again. Logging into the Yahoo! website may help."
msgstr ""
-"ਅਕਾਊਂਟ ਲਾਕ ਹੋਇਆ: ਬਹੁਤ ਸਾਰੀਆਂ ਲਾਗਇਨ ਕੋਸ਼ਿਸ਼ ਕਰਕੇ। Yahoo! ਵੈਬਸਾਇਟ ਉੱਤੇ ਲਾਗਇਨ ਕਰਨ ਨਾਲ "
-"ਸਮੱਸਿਆ ਹੱਲ ਹੋ ਸਕਦੀ ਹੈ।"
+"ਅਕਾਊਂਟ ਲਾਕ ਹੋਇਆ: ਬਹੁਤ ਸਾਰੀਆਂ ਲਾਗਇਨ ਕੋਸ਼ਿਸ਼ ਕਰਕੇ। ਮੁੜ ਕੁਨੈਕਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਕੁਝ ਮਿੰਟ ਉਡੀਕ ਲਵੋ "
+"ਜੀ। Yahoo! ਵੈਬਸਾਇਟ ਉੱਤੇ ਲਾਗਇਨ ਕਰਨ ਨਾਲ ਸਮੱਸਿਆ ਹੱਲ ਹੋ ਸਕਦੀ ਹੈ।"
#. username or password missing
msgid "Username or password missing"
@@ -10268,14 +10163,13 @@ msgstr "%s ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਟੁੱਟ ਗਿਆ ਹੈ: %s"
msgid "Unable to establish a connection with %s: %s"
msgstr "%s ਨਾਲ ਇੱਕ ਕੁਨੈਕਸ਼ਨ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: %s"
-#, fuzzy
msgid "Unable to connect: The server returned an empty response."
-msgstr "MXit ਸਰਵਰ ਨਾਲ ਕੁਨੈਕਟ ਹੋਣ ਲਈ ਅਸਮਰੱਥ ਹੈ। ਆਪਣੀ ਸਰਵਰ ਸੈਟਿੰਗ ਚੈੱਕ ਕਰੋ ਜੀ।"
+msgstr "ਕੁਨੈਕਟ ਕਰਨ ਲਈ ਅਸਮਰੱਥ: ਸਰਵਰ ਨੇ ਖਾਲੀ ਜਵਾਬ ਦਿੱਤਾ ਹੈ।"
msgid ""
"Unable to connect: The server's response did not contain the necessary "
"information"
-msgstr ""
+msgstr "ਕੁਨੈਕਟ ਕਰਨ ਲਈ ਅਸਮਰੱਥ: ਸਰਵਰ ਦਾ ਜਵਾਬ ਲੋੜੀਦੀ ਜਾਣਕਾਰੀ ਨਹੀਂ ਰੱਖਦਾ ਹੈ।"
msgid "Not at Home"
msgstr "ਘਰੇ ਨਹੀਂ"
@@ -10723,9 +10617,8 @@ msgstr "ਤੰਗ ਨਾ ਕਰੋ"
msgid "Extended away"
msgstr "ਪਹੁੰਚ ਤੋਂ ਦੂਰ"
-#, fuzzy
msgid "Feeling"
-msgstr "ਮਿਲਿਆ"
+msgstr "ਮਹਿਸੂਸ ਕਰ ਰਹੇ"
#, c-format
msgid "%s (%s) changed status from %s to %s"
@@ -11256,13 +11149,11 @@ msgstr "ਤੁਸੀਂ ਇਸ ਸਮੇਂ ਇੱਕ ਅਕਾਊਂਟ ਨਾ
msgid "Unknown node type"
msgstr "ਅਣਜਾਣ ਨੋਡ ਟਾਈਪ"
-#, fuzzy
msgid "Please select your mood from the list"
-msgstr "ਲਿਸਤ ਤੋਂ ਆਪਣਾ ਮੂਡ ਚੁਣੋ ਜੀ।"
+msgstr "ਲਿਸਟ 'ਚੋਂ ਆਪਣਾ ਮੂਡ ਚੁਣੋ"
-#, fuzzy
msgid "Message (optional)"
-msgstr "ਏਲੀਆਸ (ਚੋਣਵਾਂ)"
+msgstr "ਸੁਨੇਹਾ (ਚੋਣਵਾਂ)"
msgid "Edit User Mood"
msgstr "ਯੂਜ਼ਰ ਮੋਡ ਸੋਧ"
@@ -11345,9 +11236,8 @@ msgstr "/ਟੂਲ/ਮੇਰੀ ਪਸੰਦ(_e)"
msgid "/Tools/Pr_ivacy"
msgstr "/ਟੂਲ/ਪਰਾਈਵੇਸੀ(_i)"
-#, fuzzy
msgid "/Tools/Set _Mood"
-msgstr "/ਟੂਲ/ਸਿਸਟਮ ਲਾਗ ਵੇਖੋ(_L)"
+msgstr "/ਟੂਲ/ਮੂਡ ਸੈੱਟ ਕਰੋ(_M)"
msgid "/Tools/_File Transfers"
msgstr "/ਟੂਲ/ਫਾਇਲ ਟਰਾਂਸਫਰ(_F)"
@@ -11368,20 +11258,17 @@ msgstr "/ਮੱਦਦ(_H)"
msgid "/Help/Online _Help"
msgstr "/ਮੱਦਦ/ਆਨਲਾਈਨ ਮੱਦਦ(_H)"
-#, fuzzy
msgid "/Help/_Build Information"
-msgstr "ਬੱਡੀ ਜਾਣਕਾਰੀ"
+msgstr "/ਮੱਦਦ/ਬਿਲਡ ਜਾਣਕਾਰੀ(_B)"
msgid "/Help/_Debug Window"
msgstr "/ਮੱਦਦ/ਡੀਬੱਗ ਵਿੰਡੋ(_D)"
-#, fuzzy
msgid "/Help/De_veloper Information"
-msgstr "ਸਰਵਰ ਜਾਣਕਾਰੀ"
+msgstr "/ਮੱਦਦ/ਡਿਵੈਲਪਰ ਜਾਣਕਾਰੀ(_v)"
-#, fuzzy
msgid "/Help/_Translator Information"
-msgstr "ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ"
+msgstr "/ਮੱਦਦ/ਅਨੁਵਾਦਕ ਜਾਣਕਾਰੀ(_T)"
msgid "/Help/_About"
msgstr "/ਮੱਦਦ/ਇਸ ਬਾਰੇ(_A)"
@@ -11606,9 +11493,8 @@ msgstr "<PurpleMain>/ਅਕਾਊਂਟ/"
msgid "_Edit Account"
msgstr "ਅਕਾਊਂਟ ਸੋਧ(_E)"
-#, fuzzy
msgid "Set _Mood..."
-msgstr "ਮੂਡ ਸੈੱਟ ਕਰੋ..."
+msgstr "ਮੂਡ ਸੈੱਟ ਕਰੋ(_M)..."
msgid "No actions available"
msgstr "ਕੋਈ ਕਾਰਵਾਈ ਉਪਲੱਬਧ ਨਹੀਂ"
@@ -11728,9 +11614,8 @@ msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਆਡੀਓ\\/ਵੀਡਿਓ ਕ
msgid "/Conversation/Se_nd File..."
msgstr "/ਗੱਲਬਾਤ/ਫਾਇਲ ਭੇਜੋ(_n)..."
-#, fuzzy
msgid "/Conversation/Get _Attention"
-msgstr "/ਗੱਲਬਾਤ/ਜਾਣਕਾਰੀ ਲਵੋ"
+msgstr "/ਗੱਲਬਾਤ/ਧਿਆਨ ਮੰਗੋ(_A)"
msgid "/Conversation/Add Buddy _Pounce..."
msgstr "/ਗੱਲਬਾਤ/ਪਉਨਸ ਬੱਡੀ ਸ਼ਾਮਿਲ(_P)..."
@@ -11805,17 +11690,16 @@ msgid "/Conversation/Media/Audio Call"
msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਆਡੀਓ ਕਾਲ"
msgid "/Conversation/Media/Video Call"
-msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਵੀਡਿਓ ਕਾਲ"
+msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਵਿਡੀਓ ਕਾਲ"
msgid "/Conversation/Media/Audio\\/Video Call"
-msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਆਡੀਓ\\/ਵੀਡਿਓ ਕਾਲ"
+msgstr "/ਗੱਲਬਾਤ/ਮੀਡਿਆ/ਆਡੀਓ\\/ਵਿਡੀਓ ਕਾਲ"
msgid "/Conversation/Send File..."
msgstr "/ਗੱਲਬਾਤ/ਫਾਇਲ ਭੇਜੋ..."
-#, fuzzy
msgid "/Conversation/Get Attention"
-msgstr "/ਗੱਲਬਾਤ/ਜਾਣਕਾਰੀ ਲਵੋ"
+msgstr "/ਗੱਲਬਾਤ/ਧਿਆਨ ਲਵੋ"
msgid "/Conversation/Add Buddy Pounce..."
msgstr "/ਗੱਲਬਾਤ/ਪਉਨਸ ਬੱਡੀ ਸ਼ਾਮਿਲ..."
@@ -11881,13 +11765,11 @@ msgstr "ਭੇਜੋ(_S)"
msgid "0 people in room"
msgstr "ਰੂਮ ਵਿੱਚ 0 ਵਿਅਕਤੀ"
-#, fuzzy
msgid "Close Find bar"
-msgstr "ਇਹ ਟੈਬ ਬੰਦ ਕਰੋ"
+msgstr "ਖੋਜ ਪੱਟੀ ਬੰਦ ਕਰੋ"
-#, fuzzy
msgid "Find:"
-msgstr "ਖੋਜ"
+msgstr "ਖੋਜ:"
#, c-format
msgid "%d person in room"
@@ -12050,9 +11932,8 @@ msgstr "ਅਫ਼ਰੀਕੀ"
msgid "Arabic"
msgstr "ਅਰਬੀ"
-#, fuzzy
msgid "Assamese"
-msgstr "ਸ਼ਰਮਸ਼ਾਰ"
+msgstr "ਆਸਾਮੀ"
msgid "Belarusian Latin"
msgstr "ਬੇਲਾਰੂਸੀ ਲੈਟਿਨ"
@@ -12063,9 +11944,8 @@ msgstr "ਬੁਲਗਾਰੀਆਈ"
msgid "Bengali"
msgstr "ਬੰਗਾਲੀ"
-#, fuzzy
msgid "Bengali-India"
-msgstr "ਬੰਗਾਲੀ"
+msgstr "ਬੰਗਾਲੀ-ਭਾਰਤੀ"
msgid "Bosnian"
msgstr "ਬੋਸਨੀਆਈ"
@@ -12181,9 +12061,8 @@ msgstr "ਲਾਓ"
msgid "Macedonian"
msgstr "ਮੈਕਡੋਨੀਆਈ"
-#, fuzzy
msgid "Malayalam"
-msgstr "ਮਲਾਏ"
+msgstr "ਮਲਿਆਲਮ"
msgid "Mongolian"
msgstr "ਮੰਗੋਲੀਆਈ"
@@ -12209,9 +12088,8 @@ msgstr "ਨਾਰਵੇਗੀਅਨ ਨਯਨੋਰਸਕ"
msgid "Occitan"
msgstr "ਅੱਸੀਟਾਨ"
-#, fuzzy
msgid "Oriya"
-msgstr "Opera"
+msgstr "ਓੜੀਆ"
msgid "Punjabi"
msgstr "ਪੰਜਾਬੀ"
@@ -12294,7 +12172,7 @@ msgstr "ਅਮਹਾਰਿਕ"
msgid "Lithuanian"
msgstr "ਲੀਥੂਵਨੀਆਈ"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s is a messaging client based on libpurple which is capable of connecting "
"to multiple messaging services at once. %s is written in C using GTK+. %s "
@@ -12305,11 +12183,11 @@ msgid ""
msgstr ""
"%s libpurple ਉੱਤੇ ਅਧਾਰਿਤ ਇੱਕ ਗਰਾਫਿਕਲ ਮੋਡੂਲਰ ਮੈਸੰਜ਼ਿੰਗ ਕਲਾਇਟ ਹੈ, ਜੋ ਕਿ AIM, MSN, Yahoo!, "
"ICQ, IRC, SILC, SIP/SIMPLE, Novell GroupWise, Lotus Sametime, Bonjour, "
-"Zephyr, NySpaceIM, Gadu-Gadu ਅਤੇ QQ ਸਭ ਨਾਲ ਇੱਕੋ ਟਾਈਮ ਕੁਨੈਕਟ ਕਰਨ ਦੇ ਯੋਗ ਹੈ। ਇਸ ਨੂੰ GTK"
-"+ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਲਿਖਿਆ ਗਿਆ ਹੈ।<BR><BR>ਤੁਸੀਂ ਪਰੋਗਰਾਮ ਨੂੰ GPL (ਵਰਜਨ 2 ਜਾਂ ਨਵੇਂ) ਦੀਆਂ ਸ਼ਰਤਾਂ "
-"ਮੁਤਾਬਕ ਸੋਧ ਅਤੇ ਵੰਡ ਸਕਦੇ ਹੋ। GPL ਦੀ ਕਾਪੀ ਨੂੰ %s ਨਾਲ 'COPYING' ਫਾਇਲ ਵਿੱਚ ਦਿੱਤਾ ਗਿਆ ਹੈ। %s "
-"ਇਸ ਦੇ ਯੋਗਦਾਨੀਆਂ ਕੋਲ ਕਾਪੀ-ਰਾਈਟ ਹੈ। ਯੋਗਦਾਨੀਆਂ ਦੀ ਲਿਸਟ ਵੇਖਣ ਵਾਸਤੇ 'COPYRIGHT' ਫਾਇਲ ਵੇਖੋ। "
-"ਇਸ ਪਰੋਗਰਾਮ ਬਾਰੇ ਤੁਹਾਨੂੰ ਅਸੀਂ ਕੋਈ ਵਾਰੰਟੀ ਨਹੀਂ ਦਿੰਦੇ ਹਾਂ।<BR><BR>"
+"Zephyr, NySpaceIM, Gadu-Gadu ਅਤੇ QQ ਸਭ ਨਾਲ ਇੱਕੋ ਟਾਈਮ ਕੁਨੈਕਟ ਕਰਨ ਦੇ ਯੋਗ ਹੈ। %s ਨੂੰ GTK"
+"+ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਲਿਖਿਆ ਗਿਆ ਹੈ। ਤੁਸੀਂ %s ਨੂੰ GPL ਵਰਜਨ ੨ (ਜਾਂ ਨਵੇਂ) ਦੀਆਂ ਸ਼ਰਤਾਂ ਮੁਤਾਬਕ ਸੋਧ ਅਤੇ "
+"ਵੰਡ ਸਕਦੇ ਹੋ। GPL ਦੀ ਕਾਪੀ ਨੂੰ %s ਨਾਲ 'COPYING' ਫਾਇਲ ਵਿੱਚ ਦਿੱਤਾ ਗਿਆ ਹੈ। %s ਇਸ ਦੇ "
+"ਯੋਗਦਾਨੀਆਂ ਕੋਲ ਕਾਪੀ-ਰਾਈਟ ਹੈ, ਜਿਸ ਦੀ ਲਿਸਟ %s ਨਾਲ ਉਪਲੱਬਧ ਕਰਵਾਈ ਜਾ ਰਹੀ ਹੈ। %s ਬਾਰੇ ਤੁਹਾਨੂੰ "
+"ਅਸੀਂ ਕੋਈ ਵਾਰੰਟੀ ਨਹੀਂ ਦਿੰਦੇ ਹਾਂ।<BR><BR>"
#, c-format
msgid ""
@@ -12318,8 +12196,11 @@ msgid ""
"Channel: #pidgin on irc.freenode.net<BR>\tXMPP MUC: devel@conference.pidgin."
"im<BR><BR>"
msgstr ""
+"<FONT SIZE=\"4\"><B>ਮੱਦਦ ਲਈ ਸਰੋਤ</B></FONT><BR>\t<A HREF=\"%s\">ਵੈੱਬਸਾਈਟ</A><BR>"
+"\t<A HREF=\"%s\">ਅਕਸਰ ਪੁੱਛੇ ਜਾਂਦੇ ਸਵਾਲ</A><BR>\tIRC ਚੈਨਲ: #pidgin on irc.freenode."
+"net<BR>\tXMPP MUC: devel@conference.pidgin.im<BR><BR>"
-#, fuzzy, c-format
+#, c-format
msgid ""
"<font size=\"4\"><b>Help from other Pidgin users</b></font> is available by "
"e-mailing <a href=\"mailto:support@pidgin.im\">support@pidgin.im</a><br/"
@@ -12333,20 +12214,19 @@ msgstr ""
"im\">support@pidgin.im</a><br/>ਇਹ <b>ਪਬਲਿਕ</b> ਮੇਲਿੰਗ ਲਿਸਟ ਹੈ! (<a href="
"\"http://pidgin.im/pipermail/support/\">ਅਕਾਇਵ</a>) <br/>ਅਸੀਂ ਸੁਤੰਤਰ ਧਿਰ ਪਰੋਟੋਕਾਲ "
"ਜਾਂ ਪਲੱਗਇਨ ਲਈ ਮੱਦਦ ਨਹੀਂ ਕਰ ਸਕਦੇ!<br/>ਇਹ ਲਿਸਟ ਦੀ ਮੂਲ ਭਾਸ਼ਾ <b>ਅੰਗਰੇਜ਼ੀ</b> ਹੈ। ਤੁਸੀਂ ਹੋਰ "
-"ਭਾਸ਼ਾ ਵਿੱਚ ਪੋਸਟ ਕਰ ਤਾਂ ਸਕਦੇ ਹੋ, ਪਰ ਜਵਾਬ ਘੱਟ ਮਿਲਣ ਦੀ ਸੰਭਵਾਨਾ ਰਹੇਗੀ।<br/><br/>"
+"ਭਾਸ਼ਾ ਵਿੱਚ ਪੋਸਟ ਕਰ ਤਾਂ ਸਕਦੇ ਹੋ, ਪਰ ਜਵਾਬ ਘੱਟ ਮਿਲਣ ਦੀ ਸੰਭਵਾਨਾ ਰਹੇਗੀ।<br/>"
#, c-format
msgid "About %s"
msgstr "%s ਬਾਰੇ"
-#, fuzzy
msgid "Build Information"
-msgstr "ਬੱਡੀ ਜਾਣਕਾਰੀ"
+msgstr "ਬਿਲਡ ਜਾਣਕਾਰੀ"
#. End of not to be translated section
-#, fuzzy, c-format
+#, c-format
msgid "%s Build Information"
-msgstr "ਬੱਡੀ ਜਾਣਕਾਰੀ"
+msgstr "%s ਬਿਲਡ ਜਾਣਕਾਰੀ"
msgid "Current Developers"
msgstr "ਮੌਜੂਦਾ ਡੀਵੈਲਪਰ"
@@ -12360,9 +12240,9 @@ msgstr "ਪੁਰਾਣੇ ਖੋਜੀ"
msgid "Retired Crazy Patch Writers"
msgstr "ਰਿਟਾਇਰ ਹੋਏ ਪੈਂਚ ਲੇਖਕ"
-#, fuzzy, c-format
+#, c-format
msgid "%s Developer Information"
-msgstr "ਸਰਵਰ ਜਾਣਕਾਰੀ"
+msgstr "%s ਡਿਵੈਲਪਰ ਜਾਣਕਾਰੀ"
msgid "Current Translators"
msgstr "ਮੌਜੂਦਾ ਅਨੁਵਾਦਕ"
@@ -12370,9 +12250,9 @@ msgstr "ਮੌਜੂਦਾ ਅਨੁਵਾਦਕ"
msgid "Past Translators"
msgstr "ਪੁਰਾਣੀ ਅਨੁਵਾਦਕ"
-#, fuzzy, c-format
+#, c-format
msgid "%s Translator Information"
-msgstr "ਹੋਰ ਜਾਣਕਾਰੀ"
+msgstr "%s ਅਨੁਵਾਦ ਜਾਣਕਾਰੀ"
msgid "_Name"
msgstr "ਨਾਂ(_N)"
@@ -12771,9 +12651,8 @@ msgstr "IM ਚਿੱਤਰ ਸ਼ਾਮਿਲ"
msgid "Insert Smiley"
msgstr "ਸਮਾਇਲੀ ਸ਼ਾਮਲ ਕਰੋ"
-#, fuzzy
msgid "Send Attention"
-msgstr "ਭੇਜੋ ਬਟਨ"
+msgstr "ਧਿਆਨ ਮੰਗੋ"
msgid "<b>_Bold</b>"
msgstr "<b>ਗੂੜਾ(_B)</b>"
@@ -12821,7 +12700,7 @@ msgid "_Smile!"
msgstr "ਸਮਾਇਲ(_S)!"
msgid "_Attention!"
-msgstr ""
+msgstr "ਧਿਆਨ ਦਿਓ(_A)!"
msgid "Log Deletion Failed"
msgstr "ਲਾਗਇਨ ਹਟਾਉਣ ਲਈ ਫੇਲ੍ਹ"
@@ -12948,13 +12827,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ, ਕਿਉਂਕਿ ਇੱਕ ਹੋਰ libpurple ਕਲਾਇਟ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n"
-#, fuzzy
msgid "_Media"
-msgstr "/ਮੀਡਿਆ(_M)"
+msgstr "ਮੀਡਿਆ(_M)"
-#, fuzzy
msgid "_Hangup"
-msgstr "ਹੈਂਡ ਅੱਪ"
+msgstr "ਹੈਂਗ ਅੱਪ(_H)"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -13900,9 +13777,8 @@ msgstr "ਸਾਊਂਡ ਚਲਾਓ(_P)"
msgid "_Save File"
msgstr "ਫਾਇਲ ਸੰਭਾਲੋ(_S)"
-#, fuzzy
msgid "Do you really want to clear?"
-msgstr "ਕੀ ਤੁਸੀਂ %s ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?"
+msgstr "ਕੀ ਤੁਸੀਂ ਸਾਫ਼ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"
msgid "Select color"
msgstr "ਰੰਗ ਚੁਣੋ"
@@ -14869,21 +14745,18 @@ msgstr "ਹਰੇਕ N ਮਿੰਟ ਬਾਅਦ iChat-ਸਟਾਇਲ ਮੁਤ
msgid "Timestamp Format Options"
msgstr "ਟਾਈਮ-ਸਟੈਂਪ ਫਾਰਮੈਟ ਚੋਣ"
-#, fuzzy, c-format
+#, c-format
msgid "_Force timestamp format:"
-msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)"
+msgstr "ਸਮਾਂ-ਮੋਹਰ ਫਾਰਮੈਟ ਲਈ ਮਜ਼ਬੂਰ(_F):"
-#, fuzzy
msgid "Use system default"
-msgstr "ਵੇਹੜਾ (ਡੈਸਕਟਾਪ) ਡਿਫਾਲਟ"
+msgstr "ਸਿਸਟਮ ਡਿਫਾਲਟ ਵਰਤੋਂ"
-#, fuzzy
msgid "12 hour time format"
-msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)"
+msgstr "੧੨ ਘੰਟਾ ਸਮਾਂ ਫਾਰਮੈਟ"
-#, fuzzy
msgid "24 hour time format"
-msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)"
+msgstr "੨੪ ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ"
msgid "Show dates in..."
msgstr "ਮਿਤੀ ਵੇਖੋ..."
@@ -15078,7 +14951,6 @@ msgid "Send and receive raw XMPP stanzas."
msgstr "ਰਾਅ XMPP ਪ੍ਹੈਰਾ ਭੇਜੋ ਅਤੇ ਲਵੋ"
#. * description
-#, fuzzy
msgid "This plugin is useful for debugging XMPP servers or clients."
msgstr "ਇਹ ਪਲੱਗਇਨ XMPP ਸਰਵਰ ਜਾਂ ਕਲਾਇਟ ਡੀਬੱਗ ਲਈ ਫਾਇਦੇਮੰਦ ਹੈ।"
@@ -15087,36 +14959,37 @@ msgid ""
"$(^Name) is released under the GNU General Public License (GPL). The license "
"is provided here for information purposes only. $_CLICK"
msgstr ""
+"$(^Name) ਨੂੰ ਗਨੂ ਜਰਨਲ ਪਬਲਿਕ ਲਾਈਸੈਂਸ (GPL) ਹੇਠ ਜਾਰੀ ਕੀਤਾ ਗਿਆ ਹੈ। ਲਾਈਸੈਂਸ ਇੱਥੇ ਕੇਵਲ "
+"ਜਾਣਕਾਰੀ ਦੇਣ ਦੇ ਮਕਸਦ ਨਾਲ ਹੀ ਦਿੱਤਾ ਜਾ ਰਿਹਾ ਹੈ। $_CLICK"
#. Installer Subsection Detailed Description
msgid "A multi-platform GUI toolkit, used by Pidgin"
-msgstr ""
+msgstr "ਮਲਟੀ-ਪਲੇਟਫਾਰਮ GUI ਟੂਲਕਿੱਟ, ਪਿਡਗਿਨ ਵਲੋਂ ਵਰਤੀ ਜਾਂਦੀ ਹੈ"
msgid ""
"An instance of Pidgin is currently running. Please exit Pidgin and try "
"again."
-msgstr ""
+msgstr "ਪਿਡਗਿਨ ਇਸ ਸਮੇਂ ਚੱਲ ਰਿਹਾ ਹੈ। ਪਿਡਗਿਨ ਬੰਦ ਕਰਕੇ ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
#. Installer Subsection Detailed Description
msgid "Core Pidgin files and dlls"
-msgstr ""
+msgstr "ਕੋਰ ਪਿਡਗਿਨ ਫਾਇਲਾਂ ਤੇ dll "
#. Installer Subsection Detailed Description
msgid "Create a Start Menu entry for Pidgin"
-msgstr ""
+msgstr "ਪਿਡਗਿਨ ਲਈ ਸਟਾਰਟ ਮੇਨੂ ਐਂਟਰੀ ਬਣਾਓ"
#. Installer Subsection Detailed Description
msgid "Create a shortcut to Pidgin on the Desktop"
-msgstr ""
+msgstr "ਪਿਡਗਿਨ ਲਈ ਡੈਸਕਟਾਪ ਉੱਤੇ ਸ਼ਾਰਟਕੱਟ ਬਣਾਓ"
#. Installer Subsection Text
msgid "Debug Symbols (for reporting crashes)"
-msgstr ""
+msgstr "ਡੀਬੱਗ ਸਿੰਬਲ (ਕਰੈਸ਼ ਰਿਪੋਰਟ ਕਰਨ ਲਈ)"
#. Installer Subsection Text
-#, fuzzy
msgid "Desktop"
-msgstr "ਵੇਹੜਾ (ਡੈਸਕਟਾਪ) ਡਿਫਾਲਟ"
+msgstr "ਡੈਸਕਟਾਪ"
#. $R2 will display the URL that the GTK+ Runtime failed to download from
msgid ""
@@ -15124,12 +14997,17 @@ msgid ""
"function; if retrying fails, you may need to use the 'Offline Installer' "
"from http://pidgin.im/download/windows/ ."
msgstr ""
+"GTK+ Runtime ($R2) ਡਾਊਨਲੋਡ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ ਹੈ।$\\rਇਹ ਪਿਡਗਿਨ ਦੇ ਕੰਮ ਕਰਨ ਲਈ ਲਾਜ਼ਮੀ ਹੈ। "
+"ਜੇ ਵਾਰ ਵਾਰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਫੇਲ੍ਹ ਹੋਵੇ ਤਾਂ ਤੁਸੀਂ http://pidgin.im/download/windows/ "
+"'ਆਫਲਾਈਨ ਇੰਸਟਾਲਰ' ਵਰਤਣ ਬਾਰੇ ਸੋਚੋ।"
#. $R2 will display the URL that the Debug Symbols failed to download from
msgid ""
"Error Installing Debug Symbols ($R2).$\\rIf retrying fails, you may need to "
"use the 'Offline Installer' from http://pidgin.im/download/windows/ ."
msgstr ""
+"ਡੀਬੱਗ ਸਿੰਬਲ ($R2) ਇੰਸਟਾਲ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ।$\\rਜੇ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ ਤਾਂ ਤੁਹਾਨੂੰ "
+"http://pidgin.im/download/windows/ ਤੋਂ 'ਆਫਲਾਈਨ ਇੰਸਟਾਲਰ' ਵਰਤਣਾ ਪੈ ਸਕਦਾ ਹੈ।"
#. $R3 will display the URL that the Dictionary failed to download from
#, no-c-format
@@ -15138,80 +15016,85 @@ msgid ""
"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
"%20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
+"ਸਪੈਲਚੈੱਕ ($R3) ਇੰਸਟਾਲ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ। $\\rਜੇ ਲੈਣ ਲਈ ਫੇਲ੍ਹ ਹੋਵੇ ਤਾਂ ਖੁਦ ਇੰਸਟਾਲ ਕਰਨ ਲਈ "
+"ਹਦਾਇਤਾਂ ਵੇਖੋ: http://developer.pidgin.im/wiki/Installing"
+"%20Pidgin#manual_win32_spellcheck_installation"
#. Installer Subsection Text
-#, fuzzy
msgid "GTK+ Runtime (required if not present)"
-msgstr "GTK+ Runtime ਵਰਜਨ"
+msgstr "GTK+ Runtime (ਜੇ ਮੌਜੂਦ ਨਾ ਹੋਵੇ ਤਾਂ ਚਾਹੀਦਾ ਹੈ)"
#. Installer Subsection Text
-#, fuzzy
msgid "Localizations"
-msgstr "ਸਥਿਤੀ"
+msgstr "ਅਨੁਵਾਦ"
#. "Next >" appears on a button on the License Page of the Installer
msgid "Next >"
-msgstr ""
+msgstr "ਅੱਗੇ >"
#. Installer Subsection Text
-#, fuzzy
msgid "Pidgin Instant Messaging Client (required)"
-msgstr "ਪਿਡਗਿਨ ਇੰਟਰਨੈਟ ਮੈਸੰਜ਼ਰ"
+msgstr "ਪਿਡਗਿਨ ਤੁਰੰਤ ਇੰਟਰਨੈਟ ਮੈਸੰਜ਼ਰ (ਲਾਜ਼ਮੀ)"
msgid ""
"Pidgin requires a compatible GTK+ Runtime (which doesn't appear to be "
"already present).$\\rAre you sure you want to skip installing the GTK+ "
"Runtime?"
msgstr ""
+"ਪਿਡਗਿਨ ਲਈ ਅਨੁਕੂਲ GTK+ ਰਨਟਾਈਮ ਚਾਹੀਦਾ ਹੈ (ਜੋ ਕਿ ਹਾਲੇ ਮੌਜੂਦ ਨਹੀਂ ਜਾਪਦਾ ਹੈ।)$\\rਕੀ ਤੁਸੀਂ GTK"
+"+ ਰਨਟਾਈਮ ਨੂੰ ਇੰਸਟਾਲ ਕਰਨ ਨੂੰ ਛੱਡਣਾ ਚਾਹੁੰਦੇ ਹੋ?"
#. Installer Subsection Text
-#, fuzzy
msgid "Shortcuts"
msgstr "ਸ਼ਾਰਟਕੱਟ"
#. Installer Subsection Detailed Description
msgid "Shortcuts for starting Pidgin"
-msgstr ""
+msgstr "ਪਿਡਗਿਨ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਸ਼ਾਰਟਕੱਟ"
#. Installer Subsection Text
msgid "Spellchecking Support"
-msgstr ""
+msgstr "ਸਪੈਲ ਚੈੱਕ ਸਹਿਯੋਗ"
#. Installer Subsection Text
-#, fuzzy
msgid "Start Menu"
-msgstr "ਸ਼ੁਰੂਆਤ"
+msgstr "ਸਟਾਰਟ ਮੇਨੂ"
#. Installer Subsection Detailed Description
msgid ""
"Support for Spellchecking. (Internet connection required for installation)"
-msgstr ""
+msgstr "ਸਪੈਲ ਚੈੱਕ ਕਰਨ ਲਈ ਸਹਿਯੋਗ। (ਇੰਸਟਾਲੇਸ਼ਨ ਲਈ ਇੰਟਰਨੈੱਟ ਕੁਨੈਕਸ਼ਨ ਚਾਹੀਦਾ ਹੈ)"
-#, fuzzy
msgid "The installer is already running."
-msgstr "\"%s\" ਨਾਂ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ 'ਚ ਹੈ|"
+msgstr "ਇੰਸਟਾਲਰ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।"
msgid ""
"The uninstaller could not find registry entries for Pidgin.$\\rIt is likely "
"that another user installed this application."
msgstr ""
+"ਅਣ-ਇੰਸਟਾਲਰ ਪਿਡਗਿਨ ਲਈ ਰਿਜਸਟਰੀ ਐਂਟਰੀਆਂ ਨਹੀਂ ਲੱਭ ਸਕਿਆ।$\\rਇੰਝ ਜਾਪਦਾ ਹੈ ਕਿ ਹੋਰ ਯੂਜ਼ਰ ਨੇ ਇਹ "
+"ਐਪਲੀਕੇਸ਼ਨ ਇੰਸਟਾਲ ਕੀਤੀ ਹੈ।"
#. Installer Subsection Text
-#, fuzzy
msgid "URI Handlers"
-msgstr "myim URL ਹੈਂਡਲਰ"
+msgstr "URI ਹੈੱਡਲਰ"
msgid ""
"Unable to uninstall the currently installed version of Pidgin. The new "
"version will be installed without removing the currently installed version."
msgstr ""
+"ਪਿਡਗਿਨ ਦੇ ਮੌਜੂਦਾ ਇੰਸਟਾਲ ਵਰਜਨ ਨੂੰ ਹਟਾਉਣ ਲਈ ਅਸਮਰੱਥ ਹੈ। ਨਵਾਂ ਵਰਜਨ ਮੌਜੂਦਾ ਇੰਸਟਾਲ ਵਰਜਨ ਨੂੰ ਬਿਨਾਂ "
+"ਹਟਾਏ ਹੀ ਇੰਸਟਾਲ ਕੀਤਾ ਜਾਵੇਗਾ।"
#. Text displayed on Installer Finish Page
msgid "Visit the Pidgin Web Page"
-msgstr ""
+msgstr "ਪਿਡਗਿਨ ਵੈੱਬ ਪੇਜ਼ ਉੱਤੇ ਜਾਓ"
msgid "You do not have permission to uninstall this application."
-msgstr ""
+msgstr "ਤੁਹਾਨੂੰ ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਇੰਸਟਾਲ ਕਰਨ ਲਈ ਅਧਿਕਾਰ ਨਹੀਂ ਹਨ।"
+
+#~ msgid "The name you entered is invalid."
+#~ msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ ਨਾਂ ਗਲਤ ਹੈ।"
#~ msgid "The certificate is not valid yet."
#~ msgstr "ਸਰਟੀਫਿਕੇਟ ਢੁੱਕਵਾਂ ਨਹੀਂ ਹੈ।"
@@ -16008,7 +15891,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s ਨੂੰ ਲਿਖਣ ਲਈ ਖੋਲਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "ਫਾਇਲ ਸੰਚਾਰ ਅਸਫਲ ਹੈ; ਦੂਜੇ ਪਾਸੇ ਤੋਂ ਰੱਦ ਕੀਤਾ ਗਿਆ ਹੈ।"
#~ msgid "Could not connect for transfer."
diff --git a/po/pl.po b/po/pl.po
index 1acb4f04bd..b257114d4d 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -13,8 +13,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin Polish translation\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:18-0400\n"
-"PO-Revision-Date: 2010-05-24 14:19+0200\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-08-06 20:24+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <pl@li.org>\n"
"Language: pl\n"
@@ -68,9 +68,8 @@ msgstr ""
msgid "Error"
msgstr "Błąd"
-#, fuzzy
msgid "Account was not modified"
-msgstr "Nie dodano konta"
+msgstr "Nie zmodyfikowano konta"
msgid "Account was not added"
msgstr "Nie dodano konta"
@@ -81,10 +80,13 @@ msgstr "Nazwa użytkownika konta nie może być pusta."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"Protokół konta nie może być zmieniany, kiedy jest połączone z serwerem."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"Nazwa użytkownika konta nie może być zmieniana, kiedy jest połączone z "
+"serwerem."
msgid "New mail notifications"
msgstr "Powiadomienia o nowej poczcie"
@@ -816,7 +818,7 @@ msgstr "Zatrzymaj"
msgid "Waiting for transfer to begin"
msgstr "Oczekiwanie na rozpoczęcie przesyłu"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Anulowano"
msgid "Failed"
@@ -1707,6 +1709,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"Certyfikat nie jest jeszcze prawidłowy. Proszę sprawdzić, czy data i czas "
+"komputera są dokładne."
msgid "The certificate has expired and should not be considered valid."
msgstr "Certyfikat wygasł i nie powinien już być uważany za prawidłowy."
@@ -3392,7 +3396,7 @@ msgid "_Password:"
msgstr "_Hasło:"
msgid "IRC nick and server may not contain whitespace"
-msgstr "Pseudonimy IRC nie mogą zawierać spacji"
+msgstr "Pseudonimy i serwery IRC nie mogą zawierać spacji"
msgid "SSL support unavailable"
msgstr "Obsługa SSL jest niedostępna"
@@ -3872,19 +3876,18 @@ msgstr "Nieprawidłowe wyzwanie od serwera"
msgid "Server thinks authentication is complete, but client does not"
msgstr "Serwer uważa, że uwierzytelnienie zostało ukończone, a klient nie"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
msgstr ""
-"Serwer wymaga uwierzytelnienia w zwykłym tekście za pośrednictwem "
-"niezaszyfrowanego strumienia"
+"Serwer może wymagać uwierzytelnienia w zwykłym tekście przez niezaszyfrowany "
+"strumień"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s wymaga uwierzytelnienia w zwykłym tekście za pośrednictwem "
-"niezaszyfrowanego strumienia. Pozwolić i kontynuować uwierzytelnianie?"
+"%s może wymagać uwierzytelnienia w zwykłym tekście przez niezaszyfrowany "
+"strumień. Pozwolić i kontynuować uwierzytelnianie?"
msgid "SASL authentication failed"
msgstr "Uwierzytelnienie SASL się nie powiodło"
@@ -5974,8 +5977,8 @@ msgstr "Kod PIN jest nieprawidłowy. Powinien składać się tylko z cyfr [0-9].
msgid "The two PINs you entered do not match."
msgstr "Oba podane kody PIN nie zgadzają się."
-msgid "The name you entered is invalid."
-msgstr "Podana nazwa jest nieprawidłowa."
+msgid "The Display Name you entered is invalid."
+msgstr "Podana wyświetlana nazwa jest nieprawidłowa."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5995,9 +5998,8 @@ msgid "Your profile information is not yet retrieved. Please try again later."
msgstr ""
"Nie pobrano jeszcze informacji o profilu. Proszę spróbować ponownie później."
-#, fuzzy
msgid "Your UID"
-msgstr "MXitId użytkownika"
+msgstr "UID użytkownika"
#. pin
#. pin (required)
@@ -6068,16 +6070,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Łączenie..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Podana nazwa jest nieprawidłowa."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Podany kod PIN ma nieprawidłową długość [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "Identyfikator MXit"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6108,14 +6106,13 @@ msgstr "Sesja wygasła. Proszę spróbować ponownie później."
msgid "Invalid country selected. Please try again."
msgstr "Wybrano nieprawidłowy kraj. Proszę spróbować ponownie."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
msgstr ""
-"Nie zarejestrowano nazwy użytkownika. Proszę najpierw się zarejestrować."
+"Podany identyfikator MXit nie jest zarejestrowany. Proszę najpierw się "
+"zarejestrować."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Nazwa użytkownika jest już zarejestrowana. Proszę wybrać inną nazwę."
+msgstr "Identyfikator MXit jest już zarejestrowany. Proszę wybrać inny."
msgid "Internal error. Please try again later."
msgstr "Wewnętrzny błąd. Proszę spróbować ponownie później."
@@ -6159,9 +6156,8 @@ msgstr "Wiadomość odrzucenia"
msgid "Hidden Number"
msgstr "Ukryty numer"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "MXitId użytkownika"
+msgstr "Identyfikator MXit użytkownika..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6175,26 +6171,21 @@ msgid "Enable splash-screen popup"
msgstr "Włączenie wyskakującego ekranu powitalnego"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Użytkownik został wyrzucony: (%s)"
+msgstr "Użytkownik został wyrzucony z tego MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "Błędny bilet"
+msgstr "został wyrzucony"
-#, fuzzy
msgid "_Room Name:"
-msgstr "_Pokój:"
+msgstr "_Nazwa pokoju:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Nowa wiadomość."
+msgstr "Zaproszono"
-#, fuzzy
msgid "Last Online"
-msgstr "Online"
+msgstr "Ostatnio online"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7987,85 +7978,74 @@ msgstr ""
"niezbędne dla obrazów komunikatora. Ponieważ adres IP zostanie ujawniony, "
"może się to wiązać z zagrożeniem prywatności."
-#, fuzzy
msgid "Invalid SNAC"
-msgstr "Nieprawidłowy identyfikator"
+msgstr "Nieprawidłowe SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "Przekroczono ograniczenie prędkości serwera"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "Przekroczono ograniczenie prędkości klienta"
-#, fuzzy
msgid "Service unavailable"
msgstr "Usługa jest niedostępna"
-#, fuzzy
msgid "Service not defined"
-msgstr "Nie odnaleziono konferencji"
+msgstr "Nie określono usługi"
msgid "Obsolete SNAC"
-msgstr ""
+msgstr "Przestarzałe SNAC"
-#, fuzzy
msgid "Not supported by host"
-msgstr "Nieobsługiwane"
+msgstr "Nieobsługiwane przez serwer"
-#, fuzzy
msgid "Not supported by client"
-msgstr "Nieobsługiwane"
+msgstr "Nieobsługiwane przez klienta"
msgid "Refused by client"
-msgstr ""
+msgstr "Odmowa klienta"
msgid "Reply too big"
-msgstr ""
+msgstr "Odpowiedź jest za duża"
-#, fuzzy
msgid "Responses lost"
-msgstr "Prawdopodobieństwo odpowiedzi:"
+msgstr "Utracono odpowiedzi"
-#, fuzzy
msgid "Request denied"
-msgstr "Wysyłanie prośby"
+msgstr "Odrzucono prośby"
msgid "Busted SNAC payload"
-msgstr ""
+msgstr "Uszkodzone dane SNAC"
msgid "Insufficient rights"
-msgstr ""
+msgstr "Niewystarczające uprawnienia"
msgid "In local permit/deny"
-msgstr ""
+msgstr "W lokalnym pozwoleniu/odmowie"
msgid "Warning level too high (sender)"
-msgstr ""
+msgstr "Poziom ostrzeżenia jest za wysoki (nadawca)"
msgid "Warning level too high (receiver)"
-msgstr ""
+msgstr "Poziom ostrzeżenia jest za wysoki (odbiorca)"
-#, fuzzy
msgid "User temporarily unavailable"
-msgstr "Usługa jest tymczasowo niedostępna"
+msgstr "Użytkownik jest tymczasowo niedostępny"
-#, fuzzy
msgid "No match"
msgstr "Brak wyników"
-#, fuzzy
msgid "List overflow"
msgstr "Lista jest pełna"
-#, fuzzy
msgid "Request ambiguous"
-msgstr "Wysyłanie prośby"
+msgstr "Niejednoznaczna prośba"
msgid "Queue full"
-msgstr ""
+msgstr "Kolejka jest pełna"
msgid "Not while on AOL"
-msgstr ""
+msgstr "Nie podczas używania AOL"
msgid "Aquarius"
msgstr "Wodnik"
@@ -10270,9 +10250,8 @@ msgstr "Lokalizacja pokoju konferencji"
msgid "Ignore conference and chatroom invitations"
msgstr "Ignorowanie zaproszeń do konferencji"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Użycie pośrednika konta dla połączeń SSL"
+msgstr "Użycie pośrednika konta dla połączeń HTTP i HTTPS"
msgid "Chat room list URL"
msgstr "Adres URL listy pokoi konferencji"
@@ -13147,13 +13126,11 @@ msgstr ""
"Kończenie pracy, ponieważ inny klient biblioteki libpurple jest już "
"uruchomiony.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Multimedia"
+msgstr "_Multimedia"
-#, fuzzy
msgid "_Hangup"
-msgstr "Rozłącz się"
+msgstr "_Rozłącz się"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15459,29 +15436,3 @@ msgstr "Odwiedź stronę WWW programu Pidgin"
msgid "You do not have permission to uninstall this application."
msgstr "Brak uprawnień do odinstalowania tego programu."
-
-#~ msgid "The certificate is not valid yet."
-#~ msgstr "Certyfikat nie jest jeszcze prawidłowy."
-
-#~ msgid "The nick name you entered is invalid."
-#~ msgstr "Podany pseudonim jest nieprawidłowy."
-
-#~ msgid "MXit Login Name"
-#~ msgstr "Login MXit"
-
-#~ msgid "Nick Name"
-#~ msgstr "Pseudonim"
-
-#~ msgid "Your Mobile Number..."
-#~ msgstr "Numer telefonu komórkowego..."
-
-#, fuzzy
-#~ msgid "Rate to host"
-#~ msgstr "Zaproś do konferencji"
-
-#, fuzzy
-#~ msgid "Rate to client"
-#~ msgstr "Ostatni znany klient"
-
-#~ msgid "/Media/_Hangup"
-#~ msgstr "/Multimedia/_Rozłącz się"
diff --git a/po/ps.po b/po/ps.po
index 52267c57cf..a7384ab427 100644
--- a/po/ps.po
+++ b/po/ps.po
@@ -779,7 +779,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr "فسخ شوه"
msgid "Failed"
diff --git a/po/pt.po b/po/pt.po
index 0c907eb2e1..bc376470d0 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -843,7 +843,7 @@ msgstr "Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Esperando que a transferência comece"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelado"
msgid "Failed"
@@ -17029,7 +17029,7 @@ msgstr "Não tem permissão para desinstalar este programa."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Não foi possível abrir %s para escrita!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Tranferência de ficheiro falhou; o outro lado provavelmente cancelou-a."
diff --git a/po/pt_BR.po b/po/pt_BR.po
index c9c71a3ceb..f5720dbdbc 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -804,7 +804,7 @@ msgstr "Parar"
msgid "Waiting for transfer to begin"
msgstr "Esperando o começo da transferência"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Cancelada"
msgid "Failed"
@@ -16432,7 +16432,7 @@ msgstr "Você não tem permissão para desinstalar essa aplicação."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Não foi possível abrir %s para escrita!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Transferência de arquivo falhou; o outro lado provavelmente cancelou-a."
diff --git a/po/ro.po b/po/ro.po
index 7ad45ab0a3..e7fa1863db 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -807,7 +807,7 @@ msgstr "Stop"
msgid "Waiting for transfer to begin"
msgstr "Se așteaptă începerea transferului"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Oprit"
msgid "Failed"
diff --git a/po/ru.po b/po/ru.po
index e65d34098c..90f4eb49b1 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -807,7 +807,7 @@ msgstr "Остановить"
msgid "Waiting for transfer to begin"
msgstr "Ожидание начала передачи"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Отменено"
msgid "Failed"
@@ -15600,7 +15600,7 @@ msgid ""
"The uninstaller could not find registry entries for Pidgin.$\\rIt is likely "
"that another user installed this application."
msgstr ""
-"Программа удаления не может найти данные Pidgin в реестре.$\\Похоже, это "
+"Программа удаления не может найти данные Pidgin в реестре.$\\rПохоже, это "
"приложение установил другой пользователь."
#. Installer Subsection Text
@@ -16446,7 +16446,7 @@ msgstr "У Вас нет прав на удаление этого прилож
#~ msgid "Could not open %s for writing!"
#~ msgstr "Не удалось открыть %s для записи!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Не удалось произвести передачу файлов; вероятно, отменили на той стороне."
diff --git a/po/si.po b/po/si.po
index 95707ee2d3..bad54e72aa 100644
--- a/po/si.po
+++ b/po/si.po
@@ -757,7 +757,7 @@ msgstr "නවතන්න"
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr "අහෝසි කරන්න"
msgid "Failed"
diff --git a/po/sk.po b/po/sk.po
index 08f995da43..fbc84e3f45 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -803,7 +803,7 @@ msgstr "Zastaviť"
msgid "Waiting for transfer to begin"
msgstr "Čaká sa na začiatok prenosu"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Zrušené"
msgid "Failed"
@@ -16124,7 +16124,7 @@ msgstr "Nemáte oprávnenie na odinštaláciu tejto aplikácie."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Nepodarilo sa otvoriť %s pre zápis!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Prenos súboru zlyhal; druhá strana ho asi zrušila."
#~ msgid "Could not connect for transfer."
diff --git a/po/sl.po b/po/sl.po
index c03d6c11c0..55d8417e36 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -6,10 +6,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Pidgin 2.7.1\n"
+"Project-Id-Version: Pidgin 2.7.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:18-0400\n"
-"PO-Revision-Date: 2010-05-22 11:26+0100\n"
+"POT-Creation-Date: 2010-08-07 13:11-0400\n"
+"PO-Revision-Date: 2010-07-30 14:57+0100\n"
"Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n"
"Language-Team: Martin Srebotnjak <miles@filmsi.net>\n"
"Language: \n"
@@ -65,9 +65,8 @@ msgstr ""
msgid "Error"
msgstr "Napaka"
-#, fuzzy
msgid "Account was not modified"
-msgstr "Račun ni bil dodan"
+msgstr "Račun ni bil spremenjen"
msgid "Account was not added"
msgstr "Račun ni bil dodan"
@@ -78,10 +77,13 @@ msgstr "Uporabniško ime računa ne sme biti prazno."
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"Protokola računa ni mogoče spremeniti, medtem ko je povezan s strežnikom."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"Uporabniškega imena računa ni mogoče spremeniti, medtem ko je povezan s "
+"strežnikom."
msgid "New mail notifications"
msgstr "Obveščanje o prispeli pošti"
@@ -810,7 +812,7 @@ msgstr "Ustavi"
msgid "Waiting for transfer to begin"
msgstr "Čakanje na začetek prenosa"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Preklicano"
msgid "Failed"
@@ -1698,6 +1700,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"Potrdilo še ni veljavno. Preverite, da sta datum in čas vašega sistema "
+"pravilno nastavljena."
msgid "The certificate has expired and should not be considered valid."
msgstr ""
@@ -3870,18 +3874,18 @@ msgstr "Neveljaven izziv strežnika"
msgid "Server thinks authentication is complete, but client does not"
msgstr "Strežnik meni, da je overovitev dokončana, odjemalec pa ne"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
msgstr ""
-"Strežnik zahteva overovitev z navadnim besedilom preko nešifriranega toka"
+"Strežnik lahko zahteva overovitev z navadnim besedilom preko nešifriranega "
+"toka"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s zahteva overovitev z navadnim besedilom preko nešifrirane povezave. Se "
-"strinjate s tem in želite nadaljevati z overovitvijo?"
+"%s lahko zahteva overovitev z navadnim besedilom preko nešifrirane povezave. "
+"Se strinjate s tem in želite nadaljevati z overovitvijo?"
msgid "SASL authentication failed"
msgstr "Overovitev SASL ni uspela"
@@ -5961,8 +5965,8 @@ msgstr "PIN ni veljaven. Sestavljen mora biti iz števk [0-9]."
msgid "The two PINs you entered do not match."
msgstr "Vnesena PIN-a se ne ujemata."
-msgid "The name you entered is invalid."
-msgstr "Vneseno ime ni veljavno."
+msgid "The Display Name you entered is invalid."
+msgstr "Vneseno pojavno ime ni veljavno."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5980,9 +5984,8 @@ msgstr "Profil"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "Podatki o vašem profilu še niso pridobljen. Poskusite znova kasneje."
-#, fuzzy
msgid "Your UID"
-msgstr "Vaš MXitId"
+msgstr "Vaš UID"
#. pin
#. pin (required)
@@ -6054,16 +6057,12 @@ msgstr ""
msgid "Connecting..."
msgstr "Povezovanje ..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Vneseno ime ni veljavno."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Vneseni PIN ni veljavne dolžine [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6092,13 +6091,12 @@ msgstr "Vaša seja je potekla. Poskusite znova kasneje."
msgid "Invalid country selected. Please try again."
msgstr "Izbrana neveljavna država. Poskusite znova kasneje."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "Uporabniško ime ni registrirano. Najprej se registrirajte."
+msgstr ""
+"ID za MXit, ki ste ga vnesli, ni registriran. Najprej se registrirajte."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Uporabniško ime je že registrirano. Izberite drugo ime."
+msgstr "ID za MXit, ki ste ga vnesli, je že registriran. Izberite drugo ime."
msgid "Internal error. Please try again later."
msgstr "Notranja napaka. Poskusite znova pozneje."
@@ -6142,9 +6140,8 @@ msgstr "Sporočilo zavrnitve"
msgid "Hidden Number"
msgstr "Skrita številka"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Vaš MXitId"
+msgstr "Vaš MXit ID ..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6158,26 +6155,21 @@ msgid "Enable splash-screen popup"
msgstr "Omogoči pozdravno okno ob zagonu"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Brcnjeni ste bili: (%s)"
+msgstr "Brcnjeni ste bili s tega MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "Napačna vstopnica"
+msgstr "je bil brcnjen"
-#, fuzzy
msgid "_Room Name:"
-msgstr "_Soba:"
+msgstr "_Ime sobe:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Dobili ste pošto!"
+msgstr "Povabili ste uporabnika"
-#, fuzzy
msgid "Last Online"
-msgstr "Prisoten"
+msgstr "Nazadnje povezan"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7970,85 +7962,74 @@ msgstr ""
"za sporočanje s slikami. Ker bo razkrit naslov IP, sodi ta povezava med "
"tveganja zasebnosti."
-#, fuzzy
msgid "Invalid SNAC"
-msgstr "Neveljaven ID"
+msgstr "Neveljaven SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "Prekoračena omejitev hitrosti strežnika"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "Prekoračena omejitev hitrosti odjemalca"
-#, fuzzy
msgid "Service unavailable"
msgstr "Storitev ni dostopna"
-#, fuzzy
msgid "Service not defined"
-msgstr "Konference ni mogoče najti"
+msgstr "Storitev ni definirana"
msgid "Obsolete SNAC"
-msgstr ""
+msgstr "Zastarel SNAC"
-#, fuzzy
msgid "Not supported by host"
-msgstr "Ni podprto"
+msgstr "Ni podprto s strani gostitelja"
-#, fuzzy
msgid "Not supported by client"
-msgstr "Ni podprto"
+msgstr "Ni podprto s strani odjemalca"
msgid "Refused by client"
-msgstr ""
+msgstr "Zavrnjeno s strani odjemalca"
msgid "Reply too big"
-msgstr ""
+msgstr "Odgovor preobsežen"
-#, fuzzy
msgid "Responses lost"
-msgstr "Verjetnost odgovora:"
+msgstr "Odgovori izgubljeni"
-#, fuzzy
msgid "Request denied"
-msgstr "Zahteva v teku"
+msgstr "Zahteva zavrnjena"
msgid "Busted SNAC payload"
-msgstr ""
+msgstr "Razkrinkana obremenitev SNAC"
msgid "Insufficient rights"
-msgstr ""
+msgstr "Nezadostne pravice"
msgid "In local permit/deny"
-msgstr ""
+msgstr "V krajevnem dovoli/prepovej"
msgid "Warning level too high (sender)"
-msgstr ""
+msgstr "Raven opozoril previsoka (oddajnik)"
msgid "Warning level too high (receiver)"
-msgstr ""
+msgstr "Raven opozoril previsoka (sprejemnik)"
-#, fuzzy
msgid "User temporarily unavailable"
-msgstr "Storitev trenutno ni na voljo"
+msgstr "Uporabnik trenutno ni na voljo"
-#, fuzzy
msgid "No match"
msgstr "Ni zadetkov"
-#, fuzzy
msgid "List overflow"
msgstr "Seznam poln"
-#, fuzzy
msgid "Request ambiguous"
-msgstr "Zahteva v teku"
+msgstr "Zahteva je dvoumna"
msgid "Queue full"
-msgstr ""
+msgstr "Vrsta polna"
msgid "Not while on AOL"
-msgstr ""
+msgstr "Ne medtem ko na AOL"
msgid "Aquarius"
msgstr "Vodnar"
@@ -10241,9 +10222,8 @@ msgstr "Razpored tipk sobe pomenkov"
msgid "Ignore conference and chatroom invitations"
msgstr "Prezri povabila na konference in v klepetalnice"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Pri povezavah SSL uporabi posredovalni strežnik za račune"
+msgstr "Pri povezavah HTTP in HTTPS uporabi posredovalni strežnik za račune"
msgid "Chat room list URL"
msgstr "URL seznama sob pomenkov"
@@ -13126,13 +13106,11 @@ msgstr ""
msgid "Exiting because another libpurple client is already running.\n"
msgstr "Program se bo zaprl, ker je že zagnan drug odjemalec libpurple.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Mediji"
+msgstr "_Mediji"
-#, fuzzy
msgid "_Hangup"
-msgstr "Odloži"
+msgstr "Odlo_ži"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15300,7 +15278,7 @@ msgstr ""
#. Installer Subsection Detailed Description
msgid "A multi-platform GUI toolkit, used by Pidgin"
-msgstr ""
+msgstr "Več-platformsko orodje za vmesnike, ki ga uporablja Pidgin"
msgid ""
"An instance of Pidgin is currently running. Please exit Pidgin and try "
@@ -15433,6 +15411,9 @@ msgstr "Obiščite spletno stran Pidgin"
msgid "You do not have permission to uninstall this application."
msgstr "Za odstranitev programa nimate ustreznih pravic."
+#~ msgid "The name you entered is invalid."
+#~ msgstr "Vneseno ime ni veljavno."
+
#~ msgid "The certificate is not valid yet."
#~ msgstr "Digitalno potrdilo še ni veljavno."
diff --git a/po/sq.po b/po/sq.po
index 28f9e6d597..c151213c18 100644
--- a/po/sq.po
+++ b/po/sq.po
@@ -814,7 +814,7 @@ msgstr "Ndal"
msgid "Waiting for transfer to begin"
msgstr "Po pritet të fillojë shpërngulja"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Anuluar"
msgid "Failed"
diff --git a/po/sr.po b/po/sr.po
index 12a3ff643b..474cfc09f1 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -791,7 +791,7 @@ msgstr "Заустави"
msgid "Waiting for transfer to begin"
msgstr "Чекам да пренос почне"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Откажи"
msgid "Failed"
@@ -16453,7 +16453,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Не могу да отворим %s за упис!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Неуспешан пренос датотеке; друга страна је вероватно отказала."
#~ msgid "Could not connect for transfer."
diff --git a/po/sr@latin.po b/po/sr@latin.po
index 074b5798e5..22d8547ed2 100644
--- a/po/sr@latin.po
+++ b/po/sr@latin.po
@@ -792,7 +792,7 @@ msgstr "Zaustavi"
msgid "Waiting for transfer to begin"
msgstr "Čekam da prenos počne"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Otkaži"
msgid "Failed"
@@ -16471,7 +16471,7 @@ msgstr "Nemate ovlašćenja za deinstalaciju ove aplikacije."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Ne mogu da otvorim %s za upis!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "Neuspešan prenos datoteke; druga strana je verovatno otkazala."
#~ msgid "Could not connect for transfer."
diff --git a/po/sv.po b/po/sv.po
index 0d9ed8399a..d287a4b414 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -797,7 +797,7 @@ msgstr "Stoppa"
msgid "Waiting for transfer to begin"
msgstr "Väntar på att överföringen ska inledas"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Avbruten"
msgid "Failed"
@@ -16135,7 +16135,7 @@ msgstr "Du har inte rättigheter att avinstallera den här applikationen."
#~ msgid "Could not open %s for writing!"
#~ msgstr "Kunde inte öppna %s för läsning!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Filöverföringen misslyckades, antagligen eftersom andra sidan avbröt."
diff --git a/po/sw.po b/po/sw.po
index f0cea0874d..219cc08ecc 100644
--- a/po/sw.po
+++ b/po/sw.po
@@ -784,7 +784,7 @@ msgstr "&Simama"
msgid "Waiting for transfer to begin"
msgstr ""
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Imeghairishwa"
msgid "Failed"
diff --git a/po/ta.po b/po/ta.po
index 4acc978dfa..eb702e0dd3 100644
--- a/po/ta.po
+++ b/po/ta.po
@@ -795,7 +795,7 @@ msgstr "நிறுத்து"
msgid "Waiting for transfer to begin"
msgstr "பரிமாற்றம் ஆரம்பமாவதற்காக காத்திருக்கிறது"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "தவிர்க்கப்பட்டது"
msgid "Failed"
@@ -16101,7 +16101,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s யை எழுதுவதற்காக திறக்கமுடியவில்லை!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "கோப்பு அனுப்புதலில் பிழை; ஒருவேளை மறுபக்கத்தில் தவிர்த்திருக்கலாம்."
#~ msgid "Could not connect for transfer."
diff --git a/po/te.po b/po/te.po
index 289290c29e..86d490be5d 100644
--- a/po/te.po
+++ b/po/te.po
@@ -787,7 +787,7 @@ msgstr "ఆపుము"
msgid "Waiting for transfer to begin"
msgstr "ప్రారంభించడానికి బదిలీ కోసం నిరీక్షణ "
-msgid "Canceled"
+msgid "Cancelled"
msgstr "రద్దుచేయి"
msgid "Failed"
diff --git a/po/th.po b/po/th.po
index 94e2da1d8c..3e3ab401db 100644
--- a/po/th.po
+++ b/po/th.po
@@ -804,7 +804,7 @@ msgstr ""
msgid "Waiting for transfer to begin"
msgstr "กำลังรอการรับส่งแฟ้ม"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "ยกเลิก"
msgid "Failed"
diff --git a/po/tr.po b/po/tr.po
index bab99e178b..8318f1819d 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -805,7 +805,7 @@ msgstr "Dur"
msgid "Waiting for transfer to begin"
msgstr "Aktarımın başlaması bekleniyor"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "İptal Edildi"
msgid "Failed"
@@ -16367,7 +16367,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "%s yazma için açılamıyor!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Dosya transferi gerçekleştirilemedi; karşı taraf iptal etmiş olabilir."
diff --git a/po/uk.po b/po/uk.po
index 5d6091ec19..1445939661 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -9,16 +9,16 @@ msgid ""
msgstr ""
"Project-Id-Version: Pidgin\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-07-27 01:18-0400\n"
-"PO-Revision-Date: 2010-05-24 22:50+0300\n"
+"POT-Creation-Date: 2010-08-09 21:57-0700\n"
+"PO-Revision-Date: 2010-08-09 00:28+0300\n"
"Last-Translator: Oleksandr Kovalenko <alx.kovalenko@gmail.com>\n"
"Language-Team: Ukrainian <uk@li.org>\n"
-"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Language: uk\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. Translators may want to transliterate the name.
#. It is not to be translated.
@@ -63,9 +63,8 @@ msgstr ""
msgid "Error"
msgstr "Помилка"
-#, fuzzy
msgid "Account was not modified"
-msgstr "Обліковий запис не був доданий"
+msgstr "Обліковий запис не був змінений"
msgid "Account was not added"
msgstr "Обліковий запис не був доданий"
@@ -76,10 +75,14 @@ msgstr "Ім'я користувача облікового запису не м
msgid ""
"The account's protocol cannot be changed while it is connected to the server."
msgstr ""
+"Протокол облікового запису не може бути змінений коли він підключений до "
+"сервера."
msgid ""
"The account's username cannot be changed while it is connected to the server."
msgstr ""
+"Ім'я користувача облікового запису не може бути змінене коли він підключений "
+"до сервера."
msgid "New mail notifications"
msgstr "Сповіщення про нову пошту"
@@ -91,7 +94,7 @@ msgid "There are no protocol plugins installed."
msgstr "Не встановлений жодний з додатків протоколів."
msgid "(You probably forgot to 'make install'.)"
-msgstr "(Можливо, ви забули виконати 'make install'.)"
+msgstr "(Можливо, ви забули виконати \"make install\".)"
msgid "Modify Account"
msgstr "Змінити обліковий запис"
@@ -442,13 +445,13 @@ msgid "By Status"
msgstr "За станом"
msgid "Alphabetically"
-msgstr "За алфавітом"
+msgstr "За абеткою"
msgid "By Log Size"
msgstr "За розміром журналу"
msgid "Buddy"
-msgstr "Приятель"
+msgstr "Контакт"
msgid "Chat"
msgstr "Балачка"
@@ -460,10 +463,10 @@ msgid "Certificate Import"
msgstr "Імпорт сертифікату"
msgid "Specify a hostname"
-msgstr "Визначити назву вузла"
+msgstr "Вказати назву вузла"
msgid "Type the host name this certificate is for."
-msgstr "Напишіть назву вузла, кому належить цей сертифікат."
+msgstr "Напишіть назву вузла, якому належить цей сертифікат."
#, c-format
msgid ""
@@ -477,7 +480,7 @@ msgid "Certificate Import Error"
msgstr "Помилка імпортування сертифікату"
msgid "X.509 certificate import failed"
-msgstr "Помилка імпорту сертифікату X.509"
+msgstr "Помилка імпортування сертифікату X.509"
msgid "Select a PEM certificate"
msgstr "Вибрати сертифікат PEM"
@@ -497,7 +500,7 @@ msgid "X.509 certificate export failed"
msgstr "Помилка експорту сертифікату X.509"
msgid "PEM X.509 Certificate Export"
-msgstr "Експорт сертифікату PEM X.509"
+msgstr "Експортування сертифікату PEM X.509"
#, c-format
msgid "Certificate for %s"
@@ -806,7 +809,7 @@ msgstr "Зупинити"
msgid "Waiting for transfer to begin"
msgstr "Очікування початку передачі"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Скасовано"
msgid "Failed"
@@ -1694,6 +1697,8 @@ msgid ""
"The certificate is not valid yet. Check that your computer's date and time "
"are accurate."
msgstr ""
+"Сертифікат ще не дійсний. Перевірте, чи дата та час вашого комп'ютера "
+"правильні."
msgid "The certificate has expired and should not be considered valid."
msgstr "Термін дії сертифікату закінчився і його не слід вважати дійсним."
@@ -3851,18 +3856,18 @@ msgstr "Неправильний запит з серверу"
msgid "Server thinks authentication is complete, but client does not"
msgstr "Сервер вважає, що автентифікація завершена, але клієнт ні"
-#, fuzzy
msgid "Server may require plaintext authentication over an unencrypted stream"
msgstr ""
-"Сервер вимагає автентифікацію звичайним текстом через нешифрований потік"
+"Сервер може потребувати автентифікацію звичайним текстом через нешифрований "
+"потік"
-#, fuzzy, c-format
+#, c-format
msgid ""
"%s may require plaintext authentication over an unencrypted connection. "
"Allow this and continue authentication?"
msgstr ""
-"%s потребує автентифікації відкритим текстом через нешифроване з'єднання. "
-"Дозволити це та продовжити автентифікацію?"
+"%s може потребувати автентифікації відкритим текстом через нешифроване "
+"з'єднання. Дозволити це та продовжити автентифікацію?"
msgid "SASL authentication failed"
msgstr "Помилка автентифікації SASL"
@@ -5937,8 +5942,8 @@ msgstr "PIN неправильний. Він може складатися ті
msgid "The two PINs you entered do not match."
msgstr "Введені два PIN'и не збігаються."
-msgid "The name you entered is invalid."
-msgstr "Введене ім'я неправильне."
+msgid "The Display Name you entered is invalid."
+msgstr "Введене відображуване ім'я неправильне."
msgid ""
"The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'."
@@ -5957,9 +5962,8 @@ msgstr "Профіль"
msgid "Your profile information is not yet retrieved. Please try again later."
msgstr "Відомості про профіль ще не отримані. Будь ласка, спробуйте пізніше."
-#, fuzzy
msgid "Your UID"
-msgstr "Ваш MXitId"
+msgstr "Ваш UID"
#. pin
#. pin (required)
@@ -6031,16 +6035,12 @@ msgstr ""
msgid "Connecting..."
msgstr "З'єднання..."
-#, fuzzy
-msgid "The Display Name you entered is invalid."
-msgstr "Введене ім'я неправильне."
-
msgid "The PIN you entered has an invalid length [7-10]."
msgstr "Введений PIN має неправильну довжину [7-10]."
#. mxit login name
msgid "MXit ID"
-msgstr ""
+msgstr "MXit ID"
#. show the form to the user to complete
msgid "Register New MXit Account"
@@ -6068,13 +6068,11 @@ msgstr "Термін дії сеансу добіг кінця. Будь лас
msgid "Invalid country selected. Please try again."
msgstr "Вибрана неправильна країна. Будь ласка, спробуйте ще раз."
-#, fuzzy
msgid "The MXit ID you entered is not registered. Please register first."
-msgstr "Ім'я користувача не зареєстроване. Будь ласка, спершу зареєструйтеся."
+msgstr "Введений MXit ID не зареєстрований. Будь ласка, спершу зареєструйтеся."
-#, fuzzy
msgid "The MXit ID you entered is already registered. Please choose another."
-msgstr "Ім'я користувача вже зареєстроване. Будь ласка, виберіть інше."
+msgstr "Введений MXit ID вже зареєстроване. Будь ласка, виберіть інший."
msgid "Internal error. Please try again later."
msgstr "Внутрішня помилка. Будь ласка, спробуйте пізніше."
@@ -6118,9 +6116,8 @@ msgstr "Повідомлення відмови"
msgid "Hidden Number"
msgstr "Схований номер"
-#, fuzzy
msgid "Your MXit ID..."
-msgstr "Ваш MXitId"
+msgstr "Ваш MXit ID..."
#. Configuration options
#. WAP server (reference: "libpurple/accountopt.h")
@@ -6134,26 +6131,21 @@ msgid "Enable splash-screen popup"
msgstr "Увімкнути виринаючу екранну заставку"
#. you were kicked
-#, fuzzy
msgid "You have been kicked from this MultiMX."
-msgstr "Вас викинули: (%s)"
+msgstr "Вас викинули з цього MultiMX."
-#, fuzzy
msgid "was kicked"
-msgstr "Неправильний білет"
+msgstr "був викинутий"
-#, fuzzy
msgid "_Room Name:"
-msgstr "_Кімната:"
+msgstr "_Назва кімнати:"
#. Display system message in chat window
-#, fuzzy
msgid "You have invited"
-msgstr "Ви маєте лист!"
+msgstr "Вас запросили"
-#, fuzzy
msgid "Last Online"
-msgstr "У мережі"
+msgstr "Востаннє в мережі"
#. we must have lost the connection, so terminate it so that we can reconnect
msgid "We have lost the connection to MXit. Please reconnect."
@@ -7948,85 +7940,74 @@ msgstr ""
"та є необхідним для передавання зображень. Так як ваша ІР адреса буде "
"розкрита, це може вважатись загрозою безпеці."
-#, fuzzy
msgid "Invalid SNAC"
-msgstr "Неправильний ID"
+msgstr "Неправильний SNAC"
msgid "Server rate limit exceeded"
-msgstr ""
+msgstr "Досягнуто обмеження швидкості сервера"
msgid "Client rate limit exceeded"
-msgstr ""
+msgstr "Досягнуто обмеження швидкості клієнта"
-#, fuzzy
msgid "Service unavailable"
-msgstr "Служба недоступна"
+msgstr "Послуга недоступна"
-#, fuzzy
msgid "Service not defined"
-msgstr "Конференція не знайдена"
+msgstr "Послуга не визначена"
msgid "Obsolete SNAC"
-msgstr ""
+msgstr "Застарілий SNAC"
-#, fuzzy
msgid "Not supported by host"
-msgstr "Не підтримується"
+msgstr "Не підтримується вузлом"
-#, fuzzy
msgid "Not supported by client"
-msgstr "Не підтримується"
+msgstr "Не підтримується клієнтом"
msgid "Refused by client"
-msgstr ""
+msgstr "Відкинута клієнтом"
msgid "Reply too big"
-msgstr ""
+msgstr "Відповідь завелика"
-#, fuzzy
msgid "Responses lost"
-msgstr "Можливість відповіді:"
+msgstr "Відповіді втрачені"
-#, fuzzy
msgid "Request denied"
-msgstr "Запитується"
+msgstr "Запит відхилений"
msgid "Busted SNAC payload"
-msgstr ""
+msgstr "Зіпсовані дані SNAC"
msgid "Insufficient rights"
-msgstr ""
+msgstr "Недостатньо прав"
msgid "In local permit/deny"
-msgstr ""
+msgstr "В місцевому переліку дозволених/заборонених"
msgid "Warning level too high (sender)"
-msgstr ""
+msgstr "Рівень попередження дуже високий (відправник)"
msgid "Warning level too high (receiver)"
-msgstr ""
+msgstr "Рівень попередження дуже високий (отримувач)"
-#, fuzzy
msgid "User temporarily unavailable"
-msgstr "Послуга тимчасово недоступна"
+msgstr "Користувач тимчасово недоступний"
-#, fuzzy
msgid "No match"
msgstr "Немає збігів"
-#, fuzzy
msgid "List overflow"
msgstr "Перелік переповнений"
-#, fuzzy
msgid "Request ambiguous"
-msgstr "Запитується"
+msgstr "Запит незрозумілий"
msgid "Queue full"
-msgstr ""
+msgstr "Черга переповнена"
msgid "Not while on AOL"
-msgstr ""
+msgstr "Не тоді, коли у AOL"
msgid "Aquarius"
msgstr "Водолій"
@@ -8883,8 +8864,8 @@ msgid ""
"No host or IP address has been configured for the Meanwhile account %s. "
"Please enter one below to continue logging in."
msgstr ""
-"Ні вузол, ні адреса IP не були налаштовані для облікового запису Meanwhile "
-"%s. Будь ласка, введіть якійсь, щоб налаштувати вхід."
+"Ні вузол, ні адреса IP не були налаштовані для облікового запису Meanwhile %"
+"s. Будь ласка, введіть якійсь, щоб налаштувати вхід."
msgid "Meanwhile Connection Setup"
msgstr "Встановлення з'єднання Meanwhile"
@@ -10236,9 +10217,8 @@ msgstr "Локаль кімнати балачки"
msgid "Ignore conference and chatroom invitations"
msgstr "Нехтувати запрошеннями у конференції та кімнати балачок"
-#, fuzzy
msgid "Use account proxy for HTTP and HTTPS connections"
-msgstr "Використовувати проксі облікового запису для з'єднань SSL"
+msgstr "Використовувати проксі облікового запису для з'єднань HTTP та HTTPS"
msgid "Chat room list URL"
msgstr "URL переліку балачок"
@@ -10278,8 +10258,8 @@ msgid ""
"%s has (retroactively) denied your request to add them to your list for the "
"following reason: %s."
msgstr ""
-"%s (повторно) заборонив вам додати себе у ваш перелік з наступної причини: "
-"%s."
+"%s (повторно) заборонив вам додати себе у ваш перелік з наступної причини: %"
+"s."
#, c-format
msgid "%s has (retroactively) denied your request to add them to your list."
@@ -12450,12 +12430,12 @@ msgid ""
"to multiple messaging services at once. %s is written in C using GTK+. %s "
"is released, and may be modified and redistributed, under the terms of the "
"GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s. There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s. There is no warranty for %s.<BR><BR>"
msgstr ""
"%s - це клієнт обміну миттєвими повідомленнями, який оснований на libpurple, "
-"що здатна з'єднуватись з багатьма послугами миттєвих повідомлень одночасно. "
-"%s написаний на C, застосовуючи GTK+. %s виданий та може змінюватися і "
+"що здатна з'єднуватись з багатьма послугами миттєвих повідомлень одночасно. %"
+"s написаний на C, застосовуючи GTK+. %s виданий та може змінюватися і "
"розповсюджуватися у відповідності з ліцензією GPL версії 2 (або новіша). "
"Копія GPL постачається з %s. Авторське право на %s належить його "
"розробникам, перелік яких теж постачається з %s. Будь-які гарантії на %s не "
@@ -12998,15 +12978,15 @@ msgstr ""
#, c-format
msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
msgstr ""
"Ви дійсно хочете назавжди видалити журнал розмов у %s, що розпочалися о %s?"
#, c-format
msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
msgstr ""
"Чи дійсно хочете назавжди видалити системний журнал, що розпочатий о %s?"
@@ -13112,13 +13092,11 @@ msgid "Exiting because another libpurple client is already running.\n"
msgstr ""
"Вихід, тому що вже запущений інший клієнт, який використовує libpurple.\n"
-#, fuzzy
msgid "_Media"
-msgstr "/_Медіа"
+msgstr "_Медіа"
-#, fuzzy
msgid "_Hangup"
-msgstr "Завершити"
+msgstr "_Завершити"
#, c-format
msgid "%s wishes to start an audio/video session with you."
@@ -15291,7 +15269,7 @@ msgstr "Основні файли Pidgin та dll"
#. Installer Subsection Detailed Description
msgid "Create a Start Menu entry for Pidgin"
-msgstr "Створити запис у меню 'Пуск' для Pidgin"
+msgstr "Створити запис у меню \"Пуск\" для Pidgin"
#. Installer Subsection Detailed Description
msgid "Create a shortcut to Pidgin on the Desktop"
@@ -15328,8 +15306,8 @@ msgstr ""
#, no-c-format
msgid ""
"Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
msgstr ""
"Помилка встановлення перевірки правопису ($R3).$\\rЯкщо спроби будуть "
"марними, дивіться довідку по ручному встановленню на http://developer.pidgin."
@@ -15409,29 +15387,3 @@ msgstr "Відвідати сторінку тенет Pidgin"
msgid "You do not have permission to uninstall this application."
msgstr "Ви не маєте права на видалення цієї програми."
-
-#~ msgid "The certificate is not valid yet."
-#~ msgstr "Сертифікат ще не дійсний."
-
-#~ msgid "The nick name you entered is invalid."
-#~ msgstr "Введене прізвисько неправильне."
-
-#~ msgid "MXit Login Name"
-#~ msgstr "Ім'я входу MXit"
-
-#~ msgid "Nick Name"
-#~ msgstr "Прізвисько"
-
-#~ msgid "Your Mobile Number..."
-#~ msgstr "Номер мобільного телефону..."
-
-#, fuzzy
-#~ msgid "Rate to host"
-#~ msgstr "Запросити до балачки"
-
-#, fuzzy
-#~ msgid "Rate to client"
-#~ msgstr "Останній відомий клієнт"
-
-#~ msgid "/Media/_Hangup"
-#~ msgstr "/Медіа/_Завершити"
diff --git a/po/ur.po b/po/ur.po
index 3b1630b7fa..97835c9de8 100644
--- a/po/ur.po
+++ b/po/ur.po
@@ -815,7 +815,7 @@ msgstr "سیٹ اپ "
msgid "Waiting for transfer to begin"
msgstr "ٹرانسفر ہونے کے لئے انتظار کررہا ہے"
-msgid "Canceled"
+msgid "Cancelled"
msgstr " منسوخ کیا گیا"
msgid "Failed"
@@ -16800,7 +16800,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "لکھنے کے لئے %s کھول نہیں سکا!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "فائل ٹرانسفر ناکام ہوا؛یا ممکن ہے دوسری حانب منسوخ ہوا ہے۔"
#~ msgid "Could not connect for transfer."
diff --git a/po/vi.po b/po/vi.po
index 1ec3774c9b..a3a230032b 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -805,7 +805,7 @@ msgstr "Dừng"
msgid "Waiting for transfer to begin"
msgstr "Đợi bắt đầu truyền"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "Bị thôi"
msgid "Failed"
diff --git a/po/xh.po b/po/xh.po
index a8f37e884a..aa4c2e45e2 100644
--- a/po/xh.po
+++ b/po/xh.po
@@ -843,7 +843,7 @@ msgstr "I-Hiptop"
msgid "Waiting for transfer to begin"
msgstr "Ulindele ukuba ukudlulisa kuqalise"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "IRhoxisiwe"
msgid "Failed"
@@ -17192,7 +17192,7 @@ msgstr ""
#~ msgid "Could not open %s for writing!"
#~ msgstr "Akukwazekanga ukuvula i-%s malunga nokubhala!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr ""
#~ "Ukudluliswa kwefayili akuphumelelanga; mhlawumbi elinye icala licinyiwe."
diff --git a/po/zh_CN.po b/po/zh_CN.po
index a2c96a4c7d..c268909fec 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -777,7 +777,7 @@ msgstr "停止"
msgid "Waiting for transfer to begin"
msgstr "正在等待传送开始"
-msgid "Canceled"
+msgid "Cancelled"
msgstr "已取消"
msgid "Failed"
@@ -15530,7 +15530,7 @@ msgstr "您没有权限卸载此程序。"
#~ msgid "Could not open %s for writing!"
#~ msgstr "无法打开 %s 写入!"
-#~ msgid "File transfer failed; other side probably canceled."
+#~ msgid "File transfer failed; other side probably cancelled."
#~ msgstr "文件传送失败;可能其中一端取消了传送。"
#~ msgid "Could not connect for transfer."
diff --git a/po/zh_HK.po b/po/zh_HK.po
index 68318630f1..e4fd979bd8 100644
--- a/po/zh_HK.po
+++ b/po/zh_HK.po
@@ -868,7 +868,7 @@ msgstr "中止"
msgid "Waiting for transfer to begin"
msgstr "等待開始傳輸檔案中..."
-msgid "Canceled"
+msgid "Cancelled"
msgstr "已取消"
msgid "Failed"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index e7686db070..8fd8a0b9d8 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -866,7 +866,7 @@ msgstr "中止"
msgid "Waiting for transfer to begin"
msgstr "等待開始傳輸檔案中..."
-msgid "Canceled"
+msgid "Cancelled"
msgstr "已取消"
msgid "Failed"
diff --git a/share/ca-certs/Makefile.am b/share/ca-certs/Makefile.am
index 4ec9d6ab76..13097a340c 100644
--- a/share/ca-certs/Makefile.am
+++ b/share/ca-certs/Makefile.am
@@ -9,6 +9,7 @@ CERTIFICATES = \
StartCom_Certification_Authority.pem \
StartCom_Free_SSL_CA.pem \
Thawte_Premium_Server_CA.pem \
+ ValiCert_Class_2_VA.pem \
Verisign_RSA_Secure_Server_CA.pem \
Verisign_Class3_Primary_CA.pem \
VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem \
diff --git a/share/ca-certs/ValiCert_Class_2_VA.pem b/share/ca-certs/ValiCert_Class_2_VA.pem
new file mode 100644
index 0000000000..52e095208a
--- /dev/null
+++ b/share/ca-certs/ValiCert_Class_2_VA.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD
+ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
+Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRp
+b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv
+bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy
+NjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x
+NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
+QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x
+IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3
+DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc
+65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQ
+b7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcn
+wbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4
+OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZ
+oDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
+-----END CERTIFICATE-----