Mercurial > pidgin
changeset 30876:6469c68fa093
propagate from branch 'im.pidgin.pidgin' (head fabc09bf724818b9b50e1c41d4afd6549f298c05)
to branch 'im.pidgin.cpw.qulogic.msnp16' (head d8e8a3b3ec17b199432993002327e4ecf156d12b)
author | masca@cpw.pidgin.im |
---|---|
date | Sat, 11 Sep 2010 19:03:25 +0000 |
parents | c49697f075cf (current diff) 9af193ee13b7 (diff) |
children | 23be655cc688 |
files | libpurple/protocols/jabber/google.c libpurple/protocols/jabber/google.h libpurple/protocols/msn/dialog.c libpurple/protocols/msn/dialog.h libpurple/protocols/msn/msn.c libpurple/protocols/msn/msnutils.c libpurple/protocols/msn/notification.c libpurple/protocols/msn/session.c libpurple/protocols/msn/slp.c libpurple/protocols/msn/slplink.c libpurple/protocols/msn/switchboard.c libpurple/protocols/msn/sync.c libpurple/protocols/msn/sync.h libpurple/protocols/oscar/family_advert.c libpurple/protocols/oscar/family_invite.c libpurple/protocols/oscar/family_odir.c libpurple/protocols/oscar/family_translate.c pidgin/pixmaps/emotes/small/16/cool.png pidgin/pixmaps/emotes/small/16/grin.png pidgin/win32/IdleTracker/Makefile.mingw pidgin/win32/IdleTracker/idletrack.c pidgin/win32/IdleTracker/idletrack.h |
diffstat | 298 files changed, 6752 insertions(+), 10333 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Sun Aug 01 00:08:26 2010 +0000 +++ b/COPYRIGHT Sat Sep 11 19:03:25 2010 +0000 @@ -18,6 +18,7 @@ Copyright (C) 1998-2009 by the following: Saleem Abdulrasool +Jakub Adam Dave Ahlswede Manuel Amador Matt Amato
--- a/ChangeLog Sun Aug 01 00:08:26 2010 +0000 +++ b/ChangeLog Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ * 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.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
--- a/ChangeLog.API Sun Aug 01 00:08:26 2010 +0000 +++ b/ChangeLog.API Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- a/NEWS Sun Aug 01 00:08:26 2010 +0000 +++ b/NEWS Sat Sep 11 19:03:25 2010 +0000 @@ -2,6 +2,16 @@ 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
--- a/configure.ac Sun Aug 01 00:08:26 2010 +0000 +++ b/configure.ac Sat Sep 11 19:03:25 2010 +0000 @@ -46,7 +46,7 @@ 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([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 @@ TKCONFIG=no TKCONFIGDIRS="/usr/lib \ /usr/lib64 \ + /usr/lib/tk8.5 \ /usr/lib/tk8.4 \ /usr/lib/tk8.3 \ /usr/lib/tk8.2 \
--- a/finch/gntaccount.c Sun Aug 01 00:08:26 2010 +0000 +++ b/finch/gntaccount.c Sat Sep 11 19:03:25 2010 +0000 @@ -236,7 +236,8 @@ } 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 @@ 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 {
--- a/finch/gntft.c Sun Aug 01 00:08:26 2010 +0000 +++ b/finch/gntft.c Sat Sep 11 19:03:25 2010 +0000 @@ -383,12 +383,10 @@ return; } - data = FINCHXFER(xfer); - update_title_progress(); if (purple_xfer_is_canceled(xfer)) - status = _("Canceled"); + status = _("Cancelled"); else status = _("Failed"); @@ -402,7 +400,7 @@ 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 @@ 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);
--- a/finch/gntft.h Sun Aug 01 00:08:26 2010 +0000 +++ b/finch/gntft.h Sat Sep 11 19:03:25 2010 +0000 @@ -72,9 +72,9 @@ 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);
--- a/finch/libgnt/gntentry.c Sun Aug 01 00:08:26 2010 +0000 +++ b/finch/libgnt/gntentry.c Sat Sep 11 19:03:25 2010 +0000 @@ -480,8 +480,7 @@ { 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 @@ 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; }
--- a/finch/libgnt/gnttextview.c Sun Aug 01 00:08:26 2010 +0000 +++ b/finch/libgnt/gnttextview.c Sat Sep 11 19:03:25 2010 +0000 @@ -711,7 +711,7 @@ 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;
--- a/libpurple/account.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/account.c Sat Sep 11 19:03:25 2010 +0000 @@ -513,6 +513,25 @@ } 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 @@ /* 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 @@ 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); }
--- a/libpurple/conversation.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/conversation.c Sat Sep 11 19:03:25 2010 +0000 @@ -1124,7 +1124,6 @@ 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_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 @@ 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 @@ 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))
--- a/libpurple/debug.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/debug.h Sat Sep 11 19:03:25 2010 +0000 @@ -176,20 +176,24 @@ 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 */
--- a/libpurple/desktopitem.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/desktopitem.c Sat Sep 11 19:03:25 2010 +0000 @@ -330,7 +330,7 @@ if (c == EOF && pos == 0) return NULL; - buf[pos++] = '\0'; + buf[pos] = '\0'; return buf; }
--- a/libpurple/ft.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/ft.c Sat Sep 11 19:03:25 2010 +0000 @@ -752,6 +752,7 @@ return xfer->status; } +/* FIXME: Rename with cancelled for 3.0.0. */ gboolean purple_xfer_is_canceled(const PurpleXfer *xfer) {
--- a/libpurple/ft.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/ft.h Sat Sep 11 19:03:25 2010 +0000 @@ -58,8 +58,8 @@ 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 @@ 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);
--- a/libpurple/log.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/log.c Sat Sep 11 19:03:25 2010 +0000 @@ -1681,7 +1681,6 @@ 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 @@ } 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];
--- a/libpurple/media.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/media.c Sat Sep 11 19:03:25 2010 +0000 @@ -515,7 +515,8 @@ 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); }
--- a/libpurple/media/backend-fs2.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/media/backend-fs2.c Sat Sep 11 19:03:25 2010 +0000 @@ -208,11 +208,7 @@ } 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ ++_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 @@ 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 @@ 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 @@ 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);
--- a/libpurple/media/codec.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/media/codec.c Sat Sep 11 19:03:25 2010 +0000 @@ -83,9 +83,11 @@ 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 @@ 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 *
--- a/libpurple/media/codec.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/media/codec.h Sat Sep 11 19:03:25 2010 +0000 @@ -121,7 +121,8 @@ * * @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 */
--- a/libpurple/network.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/network.c Sat Sep 11 19:03:25 2010 +0000 @@ -98,6 +98,7 @@ PurpleNetworkListenCallback cb; gpointer cb_data; UPnPMappingAddRemove *mapping_data; + int timer; }; #ifdef HAVE_NETWORKMANAGER @@ -373,6 +374,7 @@ 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_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_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 @@ 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 @@ 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); } } }
--- a/libpurple/network.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/network.h Sat Sep 11 19:03:25 2010 +0000 @@ -239,7 +239,7 @@ * 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);
--- a/libpurple/plugins/idle.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/idle.c Sat Sep 11 19:03:25 2010 +0000 @@ -110,9 +110,6 @@ 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));
--- a/libpurple/plugins/perl/common/BuddyList.xs Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/perl/common/BuddyList.xs Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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);
--- a/libpurple/plugins/perl/common/Server.xs Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/perl/common/Server.xs Sat Sep 11 19:03:25 2010 +0000 @@ -144,6 +144,7 @@ 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)
--- a/libpurple/plugins/signals-test.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/signals-test.c Sat Sep 11 19:03:25 2010 +0000 @@ -592,12 +592,12 @@ 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
--- a/libpurple/plugins/tcl/tcl_cmd.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/tcl/tcl_cmd.c Sat Sep 11 19:03:25 2010 +0000 @@ -125,7 +125,7 @@ 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 @@ } 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 @@ 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",
--- a/libpurple/plugins/tcl/tcl_signals.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/plugins/tcl/tcl_signals.c Sat Sep 11 19:03:25 2010 +0000 @@ -160,7 +160,7 @@ { 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 @@ } /* 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 @@ 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;
--- a/libpurple/prefs.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/prefs.c Sat Sep 11 19:03:25 2010 +0000 @@ -506,7 +506,6 @@ 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, '/');
--- a/libpurple/protocols/bonjour/bonjour.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Sat Sep 11 19:03:25 2010 +0000 @@ -206,18 +206,12 @@ { 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");
--- a/libpurple/protocols/bonjour/jabber.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Sat Sep 11 19:03:25 2010 +0000 @@ -1273,7 +1273,6 @@ static void xep_iq_parse(xmlnode *packet, PurpleBuddy *pb) { - xmlnode *child; PurpleAccount *account; PurpleConnection *gc; @@ -1283,7 +1282,7 @@ 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);
--- a/libpurple/protocols/bonjour/mdns_avahi.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/bonjour/mdns_avahi.c Sat Sep 11 19:03:25 2010 +0000 @@ -115,7 +115,6 @@ 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 @@ /* 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
--- a/libpurple/protocols/jabber/Makefile.am Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/Makefile.am Sat Sep 11 19:03:25 2010 +0000 @@ -26,8 +26,20 @@ 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 @@ 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 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(IDN_CFLAGS) \ - $(LIBXML_CFLAGS) + $(LIBXML_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ + $(GSTREAMER_CFLAGS) \ + $(GSTINTERFACES_CFLAGS)
--- a/libpurple/protocols/jabber/Makefile.mingw Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/Makefile.mingw Sat Sep 11 19:03:25 2010 +0000 @@ -55,7 +55,13 @@ 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 \
--- a/libpurple/protocols/jabber/auth.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/auth.c Sat Sep 11 19:03:25 2010 +0000 @@ -123,7 +123,7 @@ 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 @@ 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 @@ 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 @@ * 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."));
--- a/libpurple/protocols/jabber/auth_cyrus.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/auth_cyrus.c Sat Sep 11 19:03:25 2010 +0000 @@ -94,7 +94,6 @@ 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 @@ 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 @@ 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); }
--- a/libpurple/protocols/jabber/bosh.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/bosh.c Sat Sep 11 19:03:25 2010 +0000 @@ -711,11 +711,10 @@ /* 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.
--- a/libpurple/protocols/jabber/buddy.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/buddy.c Sat Sep 11 19:03:25 2010 +0000 @@ -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;
--- a/libpurple/protocols/jabber/chat.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/chat.c Sat Sep 11 19:03:25 2010 +0000 @@ -173,8 +173,10 @@ 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 @@ * * 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"); }
--- a/libpurple/protocols/jabber/disco.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/disco.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ /* 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);
--- a/libpurple/protocols/jabber/google.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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); -}
--- a/libpurple/protocols/jabber/google.h Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +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 - */ - -#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" - -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 - * if this roster item should continue to be processed - */ -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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/gmail.c Sat Sep 11 19:03:25 2010 +0000 @@ -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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/gmail.h Sat Sep 11 19:03:25 2010 +0000 @@ -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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google.c Sat Sep 11 19:03:25 2010 +0000 @@ -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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google.h Sat Sep 11 19:03:25 2010 +0000 @@ -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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_presence.c Sat Sep 11 19:03:25 2010 +0000 @@ -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(""); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_presence.h Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_roster.c Sat Sep 11 19:03:25 2010 +0000 @@ -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"); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_roster.h Sat Sep 11 19:03:25 2010 +0000 @@ -0,0 +1,37 @@ +/** + * 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_roster_outgoing(JabberStream *js, xmlnode *query, xmlnode *item); + +/* Returns FALSE if this should short-circuit processing of this roster item, or TRUE + * if this roster item should continue to be processed + */ +gboolean jabber_google_roster_incoming(JabberStream *js, xmlnode *item); + +void jabber_google_roster_add_deny(JabberStream *js, const char *who); +void jabber_google_roster_rem_deny(JabberStream *js, const char *who); + + +#endif /* PURPLE_JABBER_GOOGLE_ROSTER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_session.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/google_session.h Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/jingleinfo.c Sat Sep 11 19:03:25 2010 +0000 @@ -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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/jingleinfo.h Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/relay.c Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/google/relay.h Sat Sep 11 19:03:25 2010 +0000 @@ -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 */
--- a/libpurple/protocols/jabber/iq.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/iq.c Sat Sep 11 19:03:25 2010 +0000 @@ -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"
--- a/libpurple/protocols/jabber/jabber.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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);
--- a/libpurple/protocols/jabber/jabber.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.h Sat Sep 11 19:03:25 2010 +0000 @@ -80,7 +80,7 @@ #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 @@ #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 @@ 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);
--- a/libpurple/protocols/jabber/jingle/jingle.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.c Sat Sep 11 19:03:25 2010 +0000 @@ -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_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(¶ms[0].value, G_TYPE_STRING); - g_value_set_string(¶ms[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(¶ms[1].value, G_TYPE_UINT); - g_value_set_uint(¶ms[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(¶ms[next_index].value, G_TYPE_STRING); + g_value_set_string(¶ms[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(¶ms[next_index].value, G_TYPE_UINT); + g_value_set_uint(¶ms[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(¶ms[next_index].value, G_TYPE_VALUE_ARRAY); + g_value_set_boxed(¶ms[next_index].value, relay_info); + g_value_array_free(relay_info); + } } *num = num_params; return params; } +#endif +
--- a/libpurple/protocols/jabber/jingle/jingle.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.h Sat Sep 11 19:03:25 2010 +0000 @@ -78,9 +78,13 @@ 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 }
--- a/libpurple/protocols/jabber/jingle/rtp.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Sat Sep 11 19:03:25 2010 +0000 @@ -611,7 +611,8 @@ : 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"))
--- a/libpurple/protocols/jabber/jingle/transport.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/transport.c Sat Sep 11 19:03:25 2010 +0000 @@ -111,8 +111,6 @@ 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 @@ { JingleTransport *transport; g_return_if_fail(JINGLE_IS_TRANSPORT(object)); - - transport = JINGLE_TRANSPORT(object); switch (prop_id) { default:
--- a/libpurple/protocols/jabber/libxmpp.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ { 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 @@ 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); \ +} - option = purple_account_option_bool_new(_("Force old (port 5223) SSL"), "old_ssl", FALSE); + 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_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"),
--- a/libpurple/protocols/jabber/message.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/message.c Sat Sep 11 19:03:25 2010 +0000 @@ -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_buzz(JabberMessage *jm) { - PurpleBuddy *buddy; PurpleAccount *account; /* Delayed buzz MUST NOT be accepted */ @@ -309,7 +308,7 @@ 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 @@ 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)) {
--- a/libpurple/protocols/jabber/oob.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/oob.c Sat Sep 11 19:03:25 2010 +0000 @@ -185,7 +185,7 @@ 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 @@ 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);
--- a/libpurple/protocols/jabber/parser.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/parser.c Sat Sep 11 19:03:25 2010 +0000 @@ -93,10 +93,25 @@ } } - 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)
--- a/libpurple/protocols/jabber/presence.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/presence.c Sat Sep 11 19:03:25 2010 +0000 @@ -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"
--- a/libpurple/protocols/jabber/roster.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/roster.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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");
--- a/libpurple/protocols/jabber/si.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/jabber/si.c Sat Sep 11 19:03:25 2010 +0000 @@ -1666,12 +1666,8 @@ 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 @@ /* 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);
--- a/libpurple/protocols/msn/contact.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/contact.c Sat Sep 11 19:03:25 2010 +0000 @@ -527,16 +527,20 @@ 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 @@ xmlnode *annotation; MsnUser *user; + g_free(passport); + g_free(Name); + 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; - g_free(passport); - g_free(Name); - g_free(alias); - g_free(uid); - g_free(type); - g_free(mobile_number); - passport = Name = uid = type = mobile_number = alias = NULL; - mobile = FALSE; - uid = xmlnode_get_data(contactId); type = xmlnode_get_data(contactType); @@ -836,6 +840,7 @@ g_free(uid); g_free(type); g_free(mobile_number); + g_free(alias); } static gboolean @@ -885,7 +890,7 @@ 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 @@ 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 @@ 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);
--- a/libpurple/protocols/msn/directconn.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/directconn.h Sat Sep 11 19:03:25 2010 +0000 @@ -131,7 +131,7 @@ * 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
--- a/libpurple/protocols/msn/httpconn.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/httpconn.c Sat Sep 11 19:03:25 2010 +0000 @@ -239,6 +239,9 @@ } 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 @@ 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);
--- a/libpurple/protocols/msn/msn.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/msn.c Sat Sep 11 19:03:25 2010 +0000 @@ -728,7 +728,6 @@ { PurpleBuddy *buddy; PurpleConnection *gc; - MsnSession *session; MsnMobileData *data; PurpleAccount *account; const char *name; @@ -740,8 +739,6 @@ 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 @@ 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);
--- a/libpurple/protocols/msn/msnutils.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/msnutils.c Sat Sep 11 19:03:25 2010 +0000 @@ -539,7 +539,7 @@ 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]);
--- a/libpurple/protocols/msn/notification.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/notification.c Sat Sep 11 19:03:25 2010 +0000 @@ -93,7 +93,6 @@ MsnCmdProc *cmdproc; MsnSession *session; MsnTransaction *trans; - PurpleAccount *account; GString *vers; const char *ver_str; int i; @@ -102,7 +101,6 @@ cmdproc = servconn->cmdproc; session = servconn->session; - account = session->account; vers = g_string_new(""); @@ -188,10 +186,8 @@ 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 @@ { MsnSession *session; PurpleAccount *account; - PurpleConnection *gc; MsnUser *user; MsnObject *msnobj = NULL; unsigned long clientid, extcaps; @@ -1031,7 +1026,6 @@ session = cmdproc->session; account = session->account; - gc = purple_account_get_connection(account); state = cmd->params[1]; passport = cmd->params[2]; @@ -1245,7 +1239,6 @@ { MsnSession *session; PurpleAccount *account; - PurpleConnection *gc; MsnUser *user; MsnObject *msnobj; unsigned long clientid, extcaps; @@ -1255,7 +1248,6 @@ session = cmdproc->session; account = session->account; - gc = purple_account_get_connection(account); state = cmd->params[0]; passport = cmd->params[1]; @@ -1439,11 +1431,13 @@ 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 @@ 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 @@ 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 @@ { MsnSession *session; const char *value; +#ifdef MSN_PARTIAL_LISTS const char *clLastChange; +#endif session = cmdproc->session; @@ -1989,9 +1983,9 @@ 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 @@ 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)
--- a/libpurple/protocols/msn/session.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/session.c Sat Sep 11 19:03:25 2010 +0000 @@ -283,7 +283,7 @@ 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);
--- a/libpurple/protocols/msn/slp.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/slp.c Sat Sep 11 19:03:25 2010 +0000 @@ -941,7 +941,8 @@ 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 @@ if (userlist->buddy_icon_window > 0) { GQueue *queue; - PurpleAccount *account; - const char *username; queue = userlist->buddy_icon_requests; @@ -1275,9 +1274,6 @@ 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 @@ 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); - - userlist = slpcall->slplink->session->userlist; - account = slpcall->slplink->session->account; - - purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user, - g_memdup(data, size), size, info); + purple_debug_info("msn", "Got User Display: %s\n", slplink->remote_user); -#if 0 - /* Free one window slot */ - userlist->buddy_icon_window++; + account = slplink->session->account; - purple_debug_info("msn", "got_user_display(): buddy_icon_window++ yields =%d\n", - userlist->buddy_icon_window); - - msn_release_buddy_icon_request(userlist); -#endif + purple_buddy_icons_set_for_user(account, slplink->remote_user, + g_memdup(data, size), size, info); } static void
--- a/libpurple/protocols/msn/slplink.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/slplink.c Sat Sep 11 19:03:25 2010 +0000 @@ -632,7 +632,7 @@ 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; }
--- a/libpurple/protocols/msn/soap.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/soap.c Sat Sep 11 19:03:25 2010 +0000 @@ -68,7 +68,6 @@ GQueue *queue; MsnSoapRequest *current_request; - gboolean unsafe_debug; } MsnSoapConnection; static gboolean msn_soap_connection_run(gpointer data); @@ -80,7 +79,6 @@ 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 @@ 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 @@ 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);
--- a/libpurple/protocols/msn/switchboard.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/msn/switchboard.c Sat Sep 11 19:03:25 2010 +0000 @@ -767,12 +767,8 @@ 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 @@ 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);
--- a/libpurple/protocols/oscar/Makefile.am Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/Makefile.am Sat Sep 11 19:03:25 2010 +0000 @@ -6,10 +6,11 @@ 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 @@ 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 @@ snac.c \ snactypes.h \ tlv.c \ - util.c + userinfo.c \ + util.c \ + visibility.c AM_CFLAGS = $(st)
--- a/libpurple/protocols/oscar/Makefile.mingw Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/Makefile.mingw Sat Sep 11 19:03:25 2010 +0000 @@ -41,10 +41,11 @@ ## 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 @@ 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_oservice.c \ family_popup.c \ - family_oservice.c \ - family_feedbag.c \ family_stats.c \ - family_translate.c \ family_userlookup.c \ flap_connection.c \ misc.c \ @@ -75,7 +73,9 @@ rxhandlers.c \ snac.c \ tlv.c \ - util.c + userinfo.c \ + util.c \ + visibility.c OBJECTS = $(C_SRC:%.c=%.o)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/authorization.c Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- a/libpurple/protocols/oscar/bstream.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/bstream.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/encoding.c Sat Sep 11 19:03:25 2010 +0000 @@ -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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/encoding.h Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- a/libpurple/protocols/oscar/family_admin.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_admin.c Sat Sep 11 19:03:25 2010 +0000 @@ -47,7 +47,7 @@ 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 @@ 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_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_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_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); }
--- a/libpurple/protocols/oscar/family_advert.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; -}
--- a/libpurple/protocols/oscar/family_alert.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_alert.c Sat Sep 11 19:03:25 2010 +0000 @@ -73,7 +73,7 @@ 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 @@ 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);
--- a/libpurple/protocols/oscar/family_auth.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_auth.c Sat Sep 11 19:03:25 2010 +0000 @@ -56,17 +56,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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);
--- a/libpurple/protocols/oscar/family_bart.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_bart.c Sat Sep 11 19:03:25 2010 +0000 @@ -56,7 +56,7 @@ 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 @@ 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);
--- a/libpurple/protocols/oscar/family_bos.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_bos.c Sat Sep 11 19:03:25 2010 +0000 @@ -68,98 +68,6 @@ 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) {
--- a/libpurple/protocols/oscar/family_buddy.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Sat Sep 11 19:03:25 2010 +0000 @@ -88,117 +88,6 @@ } /* - * 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
--- a/libpurple/protocols/oscar/family_chat.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_chat.c Sat Sep 11 19:03:25 2010 +0000 @@ -47,74 +47,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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. */
--- a/libpurple/protocols/oscar/family_chatnav.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_chatnav.c Sat Sep 11 19:03:25 2010 +0000 @@ -139,7 +139,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ else exchanges[curexchange-1].lang2 = NULL; -#if 0 - /* - * Type 0x00da: Unknown - */ - if (aim_tlv_gettlv(innerlist, 0x00da, 1)) { - /* Unhandled */ - } -#endif - aim_tlvlist_free(innerlist); }
--- a/libpurple/protocols/oscar/family_feedbag.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Sat Sep 11 19:03:25 2010 +0000 @@ -660,10 +660,8 @@ 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 @@ 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); + aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, list_type, NULL); - /* Add that bad boy */ - aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, 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); + if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, list_type))) + return -EINVAL; - /* Add that bad boy */ - aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); - - /* 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 @@ } /** - * 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 @@ * 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 @@ /* 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 @@ } /* - * 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ } /* - * 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 @@ 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 @@ 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 @@ 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) {
--- a/libpurple/protocols/oscar/family_icbm.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ } /* - * 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 @@ 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 @@ * * 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 ߪ 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 @@ 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 @@ 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 @@ /* 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)); - } + byte_stream_put16(&data, args->featureslen); + byte_stream_putraw(&data, args->features, args->featureslen); - if (args->flags & AIM_IMFLAGS_MULTIPART) { - aim_mpmsg_section_t *sec; + /* Insert message text in a TLV (type 0x0101) */ + byte_stream_put16(&data, 0x0101); - /* 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 { + /* Message block length */ + byte_stream_put16(&data, args->msglen + 0x04); - /* Insert message text in a TLV (type 0x0101) */ - byte_stream_put16(&data, 0x0101); - - /* 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 @@ /* 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 @@ } /* - * 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 @@ 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 @@ 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_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 @@ 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_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_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_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_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_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_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); } -/** - * 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) +static void +incomingim_ch1_parsemsg(OscarData *od, aim_userinfo_t *userinfo, ByteStream *message, struct aim_incomingim_ch1_args *args) { - 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); - + PurpleAccount *account = purple_connection_get_account(od->gc); /* - * TLV t(0005) - * - * ICQ data (the UIN and the message). + * We're interested in the inner TLV 0x101, which contains precious, precious 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); - - byte_stream_destroy(&bs); - - 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 */ -/* - * 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; + msg = byte_stream_getstr(message, msglen); + args->msg = oscar_decode_im(account, userinfo->bn, charset, msg, msglen); + } else { + byte_stream_advance(message, length); + } } - - 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) +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) { - 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) -{ - /* 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 */ - - /* - * 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. - * - */ - 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; - } - } - - /* 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) -{ - 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 @@ 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 @@ */ 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 @@ 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 @@ * ... * ... */ - while (byte_stream_empty(servdata)) + while (byte_stream_bytes_left(servdata)) { guint16 gnlen, numb; int i; @@ -1963,7 +1119,7 @@ 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 @@ 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; + guint16 hdrlen, msglen; + + args->destructor = (void *)incomingim_ch2_icqserverrelay_free; - if (byte_stream_empty(servdata) < 24) - /* Someone sent us a short server relay ICBM. Weird. (Maybe?) */ - return; - - hdrlen = byte_stream_getle16(servdata); - byte_stream_advance(servdata, hdrlen); - - 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 @@ /* * 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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; + ByteStream bs; + aim_snacid_t snacid; + guint32 header_size, data_size; + guint16 cookie2 = (guint16)g_random_int(); - 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; - } + purple_debug_misc("oscar", "Sending message ack to %s\n", bn); - 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; - } + 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); - 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 */ + /* The message header. */ + aim_im_puticbm(&bs, cookie, 0x0002, bn); + byte_stream_put16(&bs, 0x0003); /* reason */ - 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 */ + /* 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 */ - 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); - - 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); - - 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); - - presence = purple_buddy_get_presence(buddy); - status = purple_presence_get_active_status(presence); - - purple_prpl_got_user_status(account, bn, - purple_status_get_id(status), - "message", status_note, NULL); - - 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 @@ } /* - * 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 @@ 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 @@ */ 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 @@ 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 @@ 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 @@ 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)
--- a/libpurple/protocols/oscar/family_icq.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_icq.c Sat Sep 11 19:03:25 2010 +0000 @@ -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; +#define AIM_ICQ_INFO_REQUEST 0x04b2 +#define AIM_ICQ_ALIAS_REQUEST 0x04ba - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICQ))) - return -EINVAL; +static +int compare_icq_infos(gconstpointer a, gconstpointer b) +{ + const struct aim_icq_info* aa = a; + const guint16* bb = b; + return aa->reqid - *bb; +} - purple_debug_info("oscar", "Requesting offline messages\n"); - - bslen = 2 + 4 + 2 + 2; - - byte_stream_new(&bs, 4 + bslen); +static void aim_icq_freeinfo(struct aim_icq_info *info) { + int i; - 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, 0x003c); /* 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); - - 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); + 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; - 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); + 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; + } - 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); - - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,89 +301,13 @@ 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; + 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; } -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); - - return 0; -} -#endif - /* * Send an SMS message. This is the non-US way. The US-way is to IM * their cell phone number (+19195551234). @@ -446,7 +398,7 @@ 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 @@ return 0; } -static void aim_icq_freeinfo(struct aim_icq_info *info) { - int i; +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) - 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); + 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 @@ 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 @@ 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 @@ 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); + gotalias(od, 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; - } 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 @@ 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
--- a/libpurple/protocols/oscar/family_invite.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; -}
--- a/libpurple/protocols/oscar/family_locate.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Sat Sep 11 19:03:25 2010 +0000 @@ -245,6 +245,10 @@ {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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_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_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 @@ 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 @@ 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 @@ 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 @@ 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) {
--- a/libpurple/protocols/oscar/family_odir.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; -}
--- a/libpurple/protocols/oscar/family_oservice.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_oservice.c Sat Sep 11 19:03:25 2010 +0000 @@ -73,7 +73,7 @@ } 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 @@ { 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_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_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 @@ } 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 @@ 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 @@ 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 @@ } /* - * 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 @@ } 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 @@ 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_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_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 @@ } 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);
--- a/libpurple/protocols/oscar/family_translate.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +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 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. - * - */ - -#include "oscar.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; - - return 0; -}
--- a/libpurple/protocols/oscar/family_userlookup.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/family_userlookup.c Sat Sep 11 19:03:25 2010 +0000 @@ -75,7 +75,7 @@ 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);
--- a/libpurple/protocols/oscar/flap_connection.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Sat Sep 11 19:03:25 2010 +0000 @@ -212,7 +212,7 @@ * 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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;
--- a/libpurple/protocols/oscar/libaim.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/libaim.c Sat Sep 11 19:03:25 2010 +0000 @@ -25,6 +25,7 @@ */ #include "oscarcommon.h" +#include "oscar.h" static PurplePluginProtocolInfo prpl_info = { @@ -57,7 +58,7 @@ 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 */
--- a/libpurple/protocols/oscar/libicq.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/libicq.c Sat Sep 11 19:03:25 2010 +0000 @@ -63,11 +63,11 @@ 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 */
--- a/libpurple/protocols/oscar/misc.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/misc.c Sat Sep 11 19:03:25 2010 +0000 @@ -41,7 +41,7 @@ { 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 @@ 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 @@ 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 @@ 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)))
--- a/libpurple/protocols/oscar/msgcookie.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/msgcookie.c Sat Sep 11 19:03:25 2010 +0000 @@ -177,18 +177,3 @@ 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; - } -}
--- a/libpurple/protocols/oscar/odc.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/odc.c Sat Sep 11 19:03:25 2010 +0000 @@ -19,6 +19,7 @@ */ /* From the oscar PRPL */ +#include "encoding.h" #include "oscar.h" #include "peer.h" @@ -89,7 +90,7 @@ 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 @@ 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 @@ /* 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 @@ 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)
--- a/libpurple/protocols/oscar/oft.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/oft.c Sat Sep 11 19:03:25 2010 +0000 @@ -240,7 +240,7 @@ 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) &&
--- a/libpurple/protocols/oscar/oscar.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ | 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 @@ 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_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_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_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 @@ 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 @@ } #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 @@ 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_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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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_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 @@ 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_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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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_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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ return 1; } - oscar_set_status_icq(purple_connection_get_account(gc)); - return 1; } @@ -5192,12 +3764,14 @@ 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 @@ 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; - - purple_debug_info("oscar", - "ssi: syncing local list and server list\n"); + od->getblisttimer = 0; + } + + 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 { + /*** Begin code for pruning buddies from local list if they're not in server list ***/ + + /* 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 (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 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); - } - - while (cur != NULL) { - b = cur->data; - cur = g_slist_remove(cur, b); - purple_blist_remove_buddy(b); - } - - /* 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); - } + "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; - - 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 */ - - /* Add from server list to local list */ + } + + /* 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; + + 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 code for pruning buddies from local list ***/ + + /*** Begin code for adding 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ } } 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 @@ } /* 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 @@ 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 @@ 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_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 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ static GList * oscar_buddy_menu(PurpleBuddy *buddy) { - PurpleConnection *gc; OscarData *od; GList *menu; @@ -6528,6 +5030,7 @@ 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 @@ } 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 @@ 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 @@ 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 @@ { 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 @@ 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_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;
--- a/libpurple/protocols/oscar/oscar.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.h Sat Sep 11 19:03:25 2010 +0000 @@ -103,16 +103,6 @@ #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 @@ 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 @@ "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 @@ #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 @@ struct _ByteStream { guint8 *data; - guint32 len; - guint32 offset; + size_t len; + size_t offset; }; struct _QueuedSnac @@ -526,7 +369,7 @@ */ 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 @@ #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_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_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 @@ */ #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 @@ #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 @@ #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 @@ */ 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 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 @@ /* 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 @@ /* 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 @@ #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 @@ #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 @@ /* 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 @@ /* 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 @@ 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 @@ 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 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 @@ 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 @@ 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_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_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
--- a/libpurple/protocols/oscar/oscar_data.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/oscar_data.c Sat Sep 11 19:03:25 2010 +0000 @@ -53,17 +53,13 @@ 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);
--- a/libpurple/protocols/oscar/oscarcommon.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/oscarcommon.h Sat Sep 11 19:03:25 2010 +0000 @@ -77,7 +77,6 @@ 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);
--- a/libpurple/protocols/oscar/peer_proxy.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/peer_proxy.c Sat Sep 11 19:03:25 2010 +0000 @@ -32,8 +32,8 @@ 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 @@ 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 @@ } 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;
--- a/libpurple/protocols/oscar/rxhandlers.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/rxhandlers.c Sat Sep 11 19:03:25 2010 +0000 @@ -95,194 +95,3 @@ 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
--- a/libpurple/protocols/oscar/snac.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/snac.c Sat Sep 11 19:03:25 2010 +0000 @@ -151,12 +151,12 @@ 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;
--- a/libpurple/protocols/oscar/tlv.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/tlv.c Sat Sep 11 19:03:25 2010 +0000 @@ -49,27 +49,7 @@ 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 *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 *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 *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 @@ 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_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 @@ /* 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/userinfo.c Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- a/libpurple/protocols/oscar/util.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/oscar/util.c Sat Sep 11 19:03:25 2010 +0000 @@ -107,91 +107,6 @@ 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 @@ 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); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/visibility.c Sat Sep 11 19:03:25 2010 +0000 @@ -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); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/oscar/visibility.h Sat Sep 11 19:03:25 2010 +0000 @@ -0,0 +1,32 @@ +/* + * 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 _VISIBILITY_H_ +#define _VISIBILITY_H_ + +#include "oscar.h" +#include "plugin.h" +#include "util.h" + +PurpleMenuAction * create_visibility_menu_item(OscarData *od, const char *bname); +void oscar_show_visible_list(PurplePluginAction *action); +void oscar_show_invisible_list(PurplePluginAction *action); + +#endif \ No newline at end of file
--- a/libpurple/protocols/qq/ChangeLog Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/ChangeLog Sat Sep 11 19:03:25 2010 +0000 @@ -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.
--- a/libpurple/protocols/qq/buddy_info.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/buddy_info.c Sat Sep 11 19:03:25 2010 +0000 @@ -224,12 +224,10 @@ 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_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 @@ 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 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 @@ 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 @@ 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);
--- a/libpurple/protocols/qq/buddy_list.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/buddy_list.c Sat Sep 11 19:03:25 2010 +0000 @@ -55,11 +55,9 @@ /* 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 @@ 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 @@ 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 @@ 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_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_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;
--- a/libpurple/protocols/qq/buddy_opt.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/buddy_opt.c Sat Sep 11 19:03:25 2010 +0000 @@ -262,7 +262,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 @@ 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;
--- a/libpurple/protocols/qq/char_conv.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/char_conv.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ */ 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 @@ *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 @@ 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 @@ /* 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); }
--- a/libpurple/protocols/qq/file_trans.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/file_trans.c Sat Sep 11 19:03:25 2010 +0000 @@ -238,12 +238,9 @@ 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 @@ { gint bytes; guint8 tag; - qq_data *qd; - - qd = (qq_data *) gc->proto_data; bytes = 0; bytes += qq_get8(&tag, data + bytes);
--- a/libpurple/protocols/qq/group.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/group.c Sat Sep 11 19:03:25 2010 +0000 @@ -119,13 +119,11 @@ /* 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); }
--- a/libpurple/protocols/qq/group_im.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/group_im.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ /* 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 @@ /* 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 @@ 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 @@ /* 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 @@ 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; }
--- a/libpurple/protocols/qq/group_join.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/group_join.c Sat Sep 11 19:03:25 2010 +0000 @@ -178,12 +178,10 @@ /* 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 @@ { 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 @@ /* 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 @@ 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);
--- a/libpurple/protocols/qq/group_opt.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/group_opt.c Sat Sep 11 19:03:25 2010 +0000 @@ -134,12 +134,10 @@ { 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;
--- a/libpurple/protocols/qq/im.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/im.c Sat Sep 11 19:03:25 2010 +0000 @@ -725,7 +725,6 @@ /* 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 @@ 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 @@ /* 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 @@ 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 @@ { 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 @@ 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) {
--- a/libpurple/protocols/qq/qq.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/qq.c Sat Sep 11 19:03:25 2010 +0000 @@ -89,15 +89,12 @@ { 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 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_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"));
--- a/libpurple/protocols/qq/qq_base.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/qq_base.c Sat Sep 11 19:03:25 2010 +0000 @@ -386,7 +386,6 @@ /* 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 @@ 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");
--- a/libpurple/protocols/qq/qq_network.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/qq_network.c Sat Sep 11 19:03:25 2010 +0000 @@ -482,13 +482,11 @@ 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 @@ { 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;
--- a/libpurple/protocols/qq/qq_process.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/qq_process.c Sat Sep 11 19:03:25 2010 +0000 @@ -58,15 +58,12 @@ /* 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 @@ /* 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 @@ /* 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 @@ 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_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 @@ 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) {
--- a/libpurple/protocols/qq/qq_trans.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/qq_trans.c Sat Sep 11 19:03:25 2010 +0000 @@ -109,11 +109,9 @@ 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 @@ /* 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
--- a/libpurple/protocols/qq/send_file.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/qq/send_file.c Sat Sep 11 19:03:25 2010 +0000 @@ -637,10 +637,8 @@ { 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 @@ { 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 @@ 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 @@ 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);
--- a/libpurple/protocols/sametime/sametime.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/sametime/sametime.c Sat Sep 11 19:03:25 2010 +0000 @@ -2133,7 +2133,7 @@ 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); }
--- a/libpurple/protocols/silc/chat.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc/chat.c Sat Sep 11 19:03:25 2010 +0000 @@ -1395,7 +1395,7 @@ 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 @@ if (sg->roomlist == list) { purple_roomlist_unref(sg->roomlist); sg->roomlist = NULL; - sg->roomlist_canceled = TRUE; + sg->roomlist_cancelled = TRUE; } }
--- a/libpurple/protocols/silc/ops.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc/ops.c Sat Sep 11 19:03:25 2010 +0000 @@ -1455,7 +1455,7 @@ int usercount; PurpleRoomlistRoom *room; - if (sg->roomlist_canceled) + if (sg->roomlist_cancelled) break; if (error != SILC_STATUS_OK) {
--- a/libpurple/protocols/silc/silcpurple.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc/silcpurple.h Sat Sep 11 19:03:25 2010 +0000 @@ -85,7 +85,7 @@ 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;
--- a/libpurple/protocols/silc10/chat.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc10/chat.c Sat Sep 11 19:03:25 2010 +0000 @@ -1417,7 +1417,7 @@ 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 @@ if (sg->roomlist == list) { purple_roomlist_unref(sg->roomlist); sg->roomlist = NULL; - sg->roomlist_canceled = TRUE; + sg->roomlist_cancelled = TRUE; } }
--- a/libpurple/protocols/silc10/ops.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc10/ops.c Sat Sep 11 19:03:25 2010 +0000 @@ -1444,7 +1444,7 @@ int usercount; PurpleRoomlistRoom *room; - if (sg->roomlist_canceled) + if (sg->roomlist_cancelled) break; if (!success) {
--- a/libpurple/protocols/silc10/silcpurple.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/silc10/silcpurple.h Sat Sep 11 19:03:25 2010 +0000 @@ -80,7 +80,7 @@ #endif unsigned int detaching : 1; unsigned int resuming : 1; - unsigned int roomlist_canceled : 1; + unsigned int roomlist_cancelled : 1; unsigned int chpk : 1; } *SilcPurple;
--- a/libpurple/protocols/yahoo/libymsg.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/libymsg.c Sat Sep 11 19:03:25 2010 +0000 @@ -502,8 +502,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ PurpleBuddy *buddy; PurpleConnection *gc; - YahooData *yd; const char *game; char *game2; char *t; @@ -3916,7 +3916,6 @@ 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 @@ 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 @@ 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 @@ { 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);
--- a/libpurple/protocols/yahoo/util.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/util.c Sat Sep 11 19:03:25 2010 +0000 @@ -43,7 +43,7 @@ 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);
--- a/libpurple/protocols/yahoo/yahoo_aliases.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/yahoo_aliases.c Sat Sep 11 19:03:25 2010 +0000 @@ -145,7 +145,7 @@ 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);
--- a/libpurple/protocols/yahoo/yahoo_doodle.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/yahoo_doodle.c Sat Sep 11 19:03:25 2010 +0000 @@ -372,7 +372,7 @@ /* 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 @@ /* 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);
--- a/libpurple/protocols/yahoo/yahoo_doodle.h Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/yahoo_doodle.h Sat Sep 11 19:03:25 2010 +0000 @@ -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
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Sat Sep 11 19:03:25 2010 +0000 @@ -1235,14 +1235,14 @@ 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 @@ 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)
--- a/libpurple/protocols/yahoo/yahoochat.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/yahoo/yahoochat.c Sat Sep 11 19:03:25 2010 +0000 @@ -121,7 +121,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ { YahooData *yd = gc->proto_data; struct yahoo_packet *pkt; - PurpleConversation *c; char *eroom; gboolean utf8 = 1; @@ -905,7 +899,7 @@ 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)
--- a/libpurple/protocols/zephyr/ZVariables.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/protocols/zephyr/ZVariables.c Sat Sep 11 19:03:25 2010 +0000 @@ -30,10 +30,10 @@ 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");
--- a/libpurple/proxy.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/proxy.c Sat Sep 11 19:03:25 2010 +0000 @@ -1023,7 +1023,7 @@ 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;
--- a/libpurple/request.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/request.c Sat Sep 11 19:03:25 2010 +0000 @@ -1399,6 +1399,11 @@ 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;
--- a/libpurple/stun.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/stun.c Sat Sep 11 19:03:25 2010 +0000 @@ -105,11 +105,11 @@ } 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 @@ 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 @@ 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 @@ } 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;
--- a/libpurple/util.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/util.c Sat Sep 11 19:03:25 2010 +0000 @@ -3115,7 +3115,7 @@ if (text[i] != thechar) text[j++] = text[i]; - text[j++] = '\0'; + text[j] = '\0'; } void
--- a/libpurple/win32/global.mak Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/win32/global.mak Sat Sep 11 19:03:25 2010 +0000 @@ -37,7 +37,6 @@ 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 @@ 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
--- a/libpurple/win32/targets.mak Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/win32/targets.mak Sat Sep 11 19:03:25 2010 +0000 @@ -36,9 +36,6 @@ $(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
--- a/libpurple/win32/win32dep.c Sun Aug 01 00:08:26 2010 +0000 +++ b/libpurple/win32/win32dep.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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);
--- a/pidgin.spec.in Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin.spec.in Sat Sep 11 19:03:25 2010 +0000 @@ -46,12 +46,14 @@ %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 @@ --mandir=%{_mandir} \ --sysconfdir=%{_sysconfdir} \ --disable-schemas-install \ + %{sslopts} \ %{!?_with_vv:--disable-vv} \ %{!?_with_dbus:--disable-dbus} \ %{!?_with_avahi:--disable-avahi} \ @@ -471,6 +474,9 @@ %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)
--- a/pidgin/Makefile.am Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/Makefile.am Sat Sep 11 19:03:25 2010 +0000 @@ -5,9 +5,6 @@ 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 \
--- a/pidgin/Makefile.mingw Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/Makefile.mingw Sat Sep 11 19:03:25 2010 +0000 @@ -33,7 +33,6 @@ 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 @@ 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 @@ -lgthread-2.0 \ -lpurple \ -lz \ - -lidletrack \ -lgtk-win32-2.0 \ -latk-1.0 \ -lpango-1.0 \ @@ -151,7 +148,6 @@ 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 @@ $(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 @@ ## 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)
--- a/pidgin/gtkaccount.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkaccount.c Sat Sep 11 19:03:25 2010 +0000 @@ -2418,35 +2418,38 @@ 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 @@ 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);
--- a/pidgin/gtkblist.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkblist.c Sat Sep 11 19:03:25 2010 +0000 @@ -3168,7 +3168,6 @@ } 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 @@ ***************************************************/ 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 @@ { 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 @@ tmp); g_free(tmp); } - count = 0; count = purple_blist_get_group_size(group, FALSE); if (count != 0) { @@ -3977,7 +3978,6 @@ 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 @@ { 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 @@ 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 @@ 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 @@ if(buddy || chat) { PurpleAccount *account; PurplePlugin *prpl; - PurplePluginProtocolInfo *prpl_info; if(buddy) account = buddy->account; @@ -4169,12 +4164,6 @@ 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) {
--- a/pidgin/gtkconv.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkconv.c Sat Sep 11 19:03:25 2010 +0000 @@ -750,9 +750,9 @@ do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info) { const char *buddy, *message; - PidginConversation *gtkconv; - - gtkconv = PIDGIN_CONVERSATION(info->conv); + PurpleConversation *conv; + + conv = info->conv; if (resp == GTK_RESPONSE_OK) { buddy = gtk_entry_get_text(GTK_ENTRY(info->entry)); @@ -761,8 +761,8 @@ 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 @@ InviteBuddyInfo *info = NULL; if (invite_dialog == NULL) { - PurpleConnection *gc; PidginWindow *gtkwin; GtkWidget *label; GtkWidget *vbox, *hbox; @@ -869,7 +868,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ PidginConversation *gtkconv = (PidginConversation *)data; PurpleConversation *conv = gtkconv->active_conv; PurpleAccount *account; - PurplePluginProtocolInfo *prpl_info = NULL; GdkPixbuf *buf; GdkPixbuf *scale; @@ -2628,9 +2616,7 @@ 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 @@ GList *children; GtkWidget *event; PurpleConversation *conv = gtkconv->active_conv; - PidginWindow *gtkwin; g_return_if_fail(conv != NULL); @@ -2730,8 +2715,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ pidgin_conv_chat_update_user(PurpleConversation *conv, const char *user) { PurpleConvChat *chat; - PurpleConvChatBuddyFlags flags; PurpleConvChatBuddy *cbuddy; PidginConversation *gtkconv; PidginChatPane *gtkchat; @@ -6306,8 +6280,6 @@ 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 @@ 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 @@ 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 @@ int size = 0; PurpleAccount *account; - PurplePluginProtocolInfo *prpl_info = NULL; PurpleBuddyIcon *icon; @@ -6981,8 +6950,6 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) {
--- a/pidgin/gtkdialogs.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkdialogs.c Sat Sep 11 19:03:25 2010 +0000 @@ -1288,7 +1288,7 @@ 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);
--- a/pidgin/gtkft.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkft.c Sat Sep 11 19:03:25 2010 +0000 @@ -112,13 +112,10 @@ 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 @@ *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 @@ GTK_ICON_SIZE_MENU, NULL); if (purple_xfer_is_canceled(xfer)) - status = _("Canceled"); + status = _("Cancelled"); else status = _("Failed"); @@ -1015,7 +1012,6 @@ { PidginXferUiData *data; char *size_str, *remaining_str; - GtkTreeSelection *selection; time_t current_time; GtkTreeIter iter; gboolean valid; @@ -1066,8 +1062,6 @@ 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);
--- a/pidgin/gtkft.h Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkft.h Sat Sep 11 19:03:25 2010 +0000 @@ -88,10 +88,10 @@ 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);
--- a/pidgin/gtkidle.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkidle.c Sat Sep 11 19:03:25 2010 +0000 @@ -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>
--- a/pidgin/gtkimhtml.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkimhtml.c Sat Sep 11 19:03:25 2010 +0000 @@ -1476,10 +1476,8 @@ 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",
--- a/pidgin/gtkimhtmltoolbar.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Sat Sep 11 19:03:25 2010 +0000 @@ -1205,9 +1205,7 @@ /* 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;
--- a/pidgin/gtkplugin.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkplugin.c Sat Sep 11 19:03:25 2010 +0000 @@ -800,5 +800,8 @@ 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); }
--- a/pidgin/gtkpounce.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkpounce.c Sat Sep 11 19:03:25 2010 +0000 @@ -194,7 +194,6 @@ { GtkTreeIter iter; PurpleAccount *account; - PurplePounceEvent events; gboolean recurring; const char *pouncer; const char *pouncee; @@ -202,8 +201,6 @@ 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);
--- a/pidgin/gtkprefs.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkprefs.c Sat Sep 11 19:03:25 2010 +0000 @@ -1042,11 +1042,40 @@ } 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 *label; GtkWidget *ret, *vbox; - GtkWidget *label; - GtkWidget *themesel_hbox; 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 @@ 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 @@ 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:"),
--- a/pidgin/gtkroomlist.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkroomlist.c Sat Sep 11 19:03:25 2010 +0000 @@ -362,8 +362,6 @@ 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;
--- a/pidgin/gtksession.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtksession.c Sat Sep 11 19:03:25 2010 +0000 @@ -166,7 +166,7 @@ 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; }
--- a/pidgin/gtksmiley.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtksmiley.c Sat Sep 11 19:03:25 2010 +0000 @@ -520,9 +520,6 @@ GtkTreeIter *iter, gpointer data) { PurpleSmiley *smiley = NULL; - SmileyManager *dialog; - - dialog = (SmileyManager*)data; gtk_tree_model_get(model, iter, SMILEY, &smiley,
--- a/pidgin/gtksourceundomanager.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtksourceundomanager.c Sat Sep 11 19:03:25 2010 +0000 @@ -963,7 +963,7 @@ * 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,
--- a/pidgin/gtkstatusbox.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkstatusbox.c Sat Sep 11 19:03:25 2010 +0000 @@ -657,7 +657,6 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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);
--- a/pidgin/gtkutils.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkutils.c Sat Sep 11 19:03:25 2010 +0000 @@ -680,7 +680,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } -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 @@ 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 @@ 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_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf) { - int width, height, rowstride, i; - unsigned char *pixels; - unsigned char *row; - - 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); - - 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; - } - } - - row = pixels + ((height-1) * rowstride); - for (i = 3; i < rowstride; i+=4) { - if (row[i] < 0xfe) - return FALSE; - } - - return TRUE; + int height, rowstride, i; + unsigned char *pixels; + unsigned char *row; + + if (!gdk_pixbuf_get_has_alpha(pixbuf)) + return TRUE; + + 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; + } + + 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; + } + + 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) {
--- a/pidgin/gtkutils.h Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/gtkutils.h Sat Sep 11 19:03:25 2010 +0000 @@ -718,6 +718,17 @@ 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,
--- a/pidgin/minidialog.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/minidialog.c Sat Sep 11 19:03:25 2010 +0000 @@ -75,6 +75,7 @@ PROP_TITLE = 1, PROP_DESCRIPTION, PROP_ICON_NAME, + PROP_CUSTOM_ICON, LAST_PROPERTY } HazeConnectionProperties; @@ -93,17 +94,32 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 */
--- a/pidgin/minidialog.h Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/minidialog.h Sat Sep 11 19:03:25 2010 +0000 @@ -73,6 +73,8 @@ * <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 @@ /** 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_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.
--- a/pidgin/pidginstock.h Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/pidginstock.h Sat Sep 11 19:03:25 2010 +0000 @@ -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"
--- a/pidgin/pixmaps/emotes/default/24/default.theme.in Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/pixmaps/emotes/default/24/default.theme.in Sat Sep 11 19:03:25 2010 +0000 @@ -419,6 +419,98 @@ 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 @@ glasses-nerdy.png B) bulgy-eyes.png %) freaked-out.png :E -smile.png :) :-) +happy.png :) :-) amorous.png :X laugh.png :)) mohawk.png -:
--- a/pidgin/pixmaps/emotes/small/16/Makefile.am Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/Makefile.am Sat Sep 11 19:03:25 2010 +0000 @@ -34,7 +34,6 @@ confused.png \ console.png \ cold.png \ - cool.png \ cross.png \ crying.png \ devil.png \ @@ -44,7 +43,6 @@ excruciating.png \ eyeroll.png \ girl.png \ - grin.png \ happy.png \ hug-left.png \ hug-right.png \ @@ -77,6 +75,7 @@ star.png \ stressed.png \ thinking.png \ + thunder.png \ tongue.png \ tv.png \ uhm-yeah.png \
--- a/pidgin/pixmaps/emotes/small/16/small.theme.in Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/pixmaps/emotes/small/16/small.theme.in Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ # 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 @@ 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 @@ 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 @@ 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 @@ 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 :-[ :[
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/gevolution/add_buddy_dialog.c Sat Sep 11 19:03:25 2010 +0000 @@ -54,8 +54,7 @@ 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 @@ { 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ 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"); } } }
--- a/pidgin/plugins/gevolution/gevo-util.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/gevolution/gevo-util.c Sat Sep 11 19:03:25 2010 +0000 @@ -111,6 +111,8 @@ 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; }
--- a/pidgin/plugins/gevolution/gevolution.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/gevolution/gevolution.c Sat Sep 11 19:03:25 2010 +0000 @@ -125,6 +125,7 @@ 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
--- a/pidgin/plugins/gevolution/new_person_dialog.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/gevolution/new_person_dialog.c Sat Sep 11 19:03:25 2010 +0000 @@ -153,6 +153,8 @@ 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 @@ 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); }
--- a/pidgin/plugins/notify.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/notify.c Sat Sep 11 19:03:25 2010 +0000 @@ -303,7 +303,6 @@ attach_signals(PurpleConversation *conv) { PidginConversation *gtkconv = NULL; - PidginWindow *gtkwin = NULL; GSList *imhtml_ids = NULL, *entry_ids = NULL; guint id; @@ -313,8 +312,6 @@ 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 @@ 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 @@ apply_method() { GList *convs; - PidginWindow *purplewin = NULL; for (convs = purple_get_conversations(); convs != NULL; convs = convs->next) { @@ -659,7 +653,6 @@ /* 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);
--- a/pidgin/plugins/vvconfig.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/vvconfig.c Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 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 */ + 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 */ + "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 */ + "settings for voice/video calls."), /**< description */ + "Mike Ruprecht <cmaiku@gmail.com>", /**< author */ + PURPLE_WEBSITE, /**< homepage */ - plugin_load, /**< load */ - plugin_unload, /**< unload */ - NULL, /**< destroy */ + plugin_load, /**< load */ + plugin_unload, /**< unload */ + NULL, /**< destroy */ - &ui_info, /**< ui_info */ - NULL, /**< extra_info */ - NULL, /**< prefs_info */ - NULL, /**< actions */ + &ui_info, /**< ui_info */ + NULL, /**< extra_info */ + NULL, /**< prefs_info */ + actions, /**< actions */ /* padding */ NULL,
--- a/pidgin/plugins/xmppconsole.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/plugins/xmppconsole.c Sat Sep 11 19:03:25 2010 +0000 @@ -183,7 +183,7 @@ { GtkTextIter start, end; PurplePluginProtocolInfo *prpl_info = NULL; - PurpleConnection *gc = console->gc; + PurpleConnection *gc; GtkTextBuffer *buffer; char *text;
--- a/pidgin/win32/IdleTracker/Makefile.mingw Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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)
--- a/pidgin/win32/IdleTracker/idletrack.c Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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; -}
--- a/pidgin/win32/IdleTracker/idletrack.h Sun Aug 01 00:08:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 */
--- a/pidgin/win32/gtkwin32dep.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/gtkwin32dep.c Sat Sep 11 19:03:25 2010 +0000 @@ -43,7 +43,6 @@ #include "network.h" #include "resource.h" -#include "idletrack.h" #include "zlib.h" #include "untar.h" @@ -377,15 +376,19 @@ 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 @@ 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 @@ if(messagewin_hwnd) DestroyWindow(messagewin_hwnd); - /* Idle tracker cleanup */ - winpidgin_remove_idlehooks(); - } /* DLL initializer */ @@ -535,5 +531,18 @@ (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; +} +
--- a/pidgin/win32/gtkwin32dep.h Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/gtkwin32dep.h Sat Sep 11 19:03:25 2010 +0000 @@ -39,6 +39,7 @@ 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);
--- a/pidgin/win32/nsis/nsis_translations.desktop.in Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/nsis/nsis_translations.desktop.in Sat Sep 11 19:03:25 2010 +0000 @@ -6,7 +6,7 @@ # "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
--- a/pidgin/win32/nsis/pidgin-installer.nsi Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Sat Sep 11 19:03:25 2010 +0000 @@ -268,7 +268,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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"
--- a/pidgin/win32/winpidgin.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/winpidgin.c Sat Sep 11 19:03:25 2010 +0000 @@ -605,9 +605,9 @@ 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 @@ 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 @@ 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 @@ } - 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 @@ 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);
--- a/pidgin/win32/wspell.c Sun Aug 01 00:08:26 2010 +0000 +++ b/pidgin/win32/wspell.c Sat Sep 11 19:03:25 2010 +0000 @@ -73,25 +73,29 @@ 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); }
--- a/po/ChangeLog Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ChangeLog Sat Sep 11 19:03:25 2010 +0000 @@ -3,10 +3,16 @@ 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
--- a/po/af.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/af.po Sat Sep 11 19:03:25 2010 +0000 @@ -802,7 +802,7 @@ 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 @@ #~ "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 @@ #~ 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."
--- a/po/am.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/am.po Sat Sep 11 19:03:25 2010 +0000 @@ -812,7 +812,7 @@ msgstr "" #, fuzzy -msgid "Canceled" +msgid "Cancelled" msgstr "ተወው" #, fuzzy
--- a/po/ar.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ar.po Sat Sep 11 19:03:25 2010 +0000 @@ -791,7 +791,7 @@ msgid "Waiting for transfer to begin" msgstr "في انتظار بدء النقل" -msgid "Canceled" +msgid "Cancelled" msgstr "أُلغِيَ" msgid "Failed" @@ -16584,7 +16584,7 @@ #~ 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."
--- a/po/as.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/as.po Sat Sep 11 19:03:25 2010 +0000 @@ -789,7 +789,7 @@ msgid "Waiting for transfer to begin" msgstr "বিনিময়ৰ আৰম্ভত অপেক্ষা কৰা হৈছে" -msgid "Canceled" +msgid "Cancelled" msgstr "বাতিল কৰা হৈছে" msgid "Failed"
--- a/po/az.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/az.po Sat Sep 11 19:03:25 2010 +0000 @@ -809,7 +809,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "" msgid "Failed" @@ -16008,7 +16008,7 @@ #~ 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."
--- a/po/be@latin.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/be@latin.po Sat Sep 11 19:03:25 2010 +0000 @@ -801,7 +801,7 @@ 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 @@ #~ 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."
--- a/po/bg.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/bg.po Sat Sep 11 19:03:25 2010 +0000 @@ -820,7 +820,7 @@ msgid "Waiting for transfer to begin" msgstr "Изчакване пренасянето да започне" -msgid "Canceled" +msgid "Cancelled" msgstr "Отказан" msgid "Failed" @@ -16574,7 +16574,7 @@ #~ 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 "" #~ "Неуспешен пренос на файла. Получателят вероятно е отказал получаването."
--- a/po/bn.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/bn.po Sat Sep 11 19:03:25 2010 +0000 @@ -843,7 +843,7 @@ msgid "Waiting for transfer to begin" msgstr "স্থানান্তর শুরু করার জন্য অপেক্ষা করা হচ্ছে" -msgid "Canceled" +msgid "Cancelled" msgstr "বাতিল করা হয়েছে" # mark6
--- a/po/bn_IN.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/bn_IN.po Sat Sep 11 19:03:25 2010 +0000 @@ -795,7 +795,7 @@ msgid "Waiting for transfer to begin" msgstr "পরিবহণ আরম্ভে অপেক্ষা চলছে" -msgid "Canceled" +msgid "Cancelled" msgstr "বাতিল করা হয়েছে" msgid "Failed"
--- a/po/bs.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/bs.po Sat Sep 11 19:03:25 2010 +0000 @@ -822,7 +822,7 @@ msgid "Waiting for transfer to begin" msgstr "Cekanje na pocetak transfera" -msgid "Canceled" +msgid "Cancelled" msgstr "Otkazano" msgid "Failed" @@ -17049,7 +17049,7 @@ #~ 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."
--- a/po/ca.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ca.po Sat Sep 11 19:03:25 2010 +0000 @@ -33,8 +33,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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" - -#, fuzzy, c-format +msgstr "" +"Podria ser que el servidor requerís autenticació de text sobre un flux no " +"xifrat" + +#, 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 @@ 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 @@ 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 @@ # 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 @@ 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 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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." - -#, fuzzy +msgstr "" +"L'identificador MXit que heu entrat no està registrat, cal que primer el " +"registreu." + 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 @@ 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 @@ msgstr "Nom de la _Sala:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Teniu correu!" - -#, fuzzy +msgstr "Heu convidat" + 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 @@ 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 @@ "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 @@ 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 @@ 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 @@ #, 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ "navegador:" msgid "Yahoo! ID" -msgstr "ID de Yahoo!" +msgstr "Identificador de Yahoo!" msgid "Hobbies" msgstr "Aficions" @@ -13180,13 +13176,11 @@ "Ara se sortirà atès que ja hi ha un altre client del libpurple executant-" "se.\n" -#, fuzzy msgid "_Media" -msgstr "/_Medi" - -#, fuzzy +msgstr "_Medi" + msgid "_Hangup" -msgstr "Penja" +msgstr "_Penja" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -15512,6 +15506,9 @@ 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 @@ #~ 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."
--- a/po/ca@valencia.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ca@valencia.po Sat Sep 11 19:03:25 2010 +0000 @@ -33,14 +33,14 @@ 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 @@ 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 @@ 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 @@ "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 @@ 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 @@ "de les diferents classes de missatge en les finestres de conversa.<br> " "<classe>: receive (rep), send (envia), highlight (ressalta), action " "(acció), timestamp (marca de temps)<br> <primer pla/fons>: 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 @@ 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 @@ 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 @@ "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 @@ "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 @@ 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 @@ "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 @@ 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 @@ "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 @@ "must be a channel operator to do this." msgstr "" "devoice <sobrenom1> [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 <nick> [room]: Invite someone to join you in the specified " @@ -3876,17 +3883,18 @@ 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" - -#, fuzzy, c-format +msgstr "" +"Podria ser que el servidor requerís autenticació de text sobre un flux no " +"xifrat" + +#, 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 @@ 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 @@ 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 @@ # 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 @@ 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 @@ 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 @@ #, 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 @@ 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 @@ "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 @@ 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 @@ 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." - -#, fuzzy +msgstr "" +"L'identificador MXit que heu entrat no està registrat, cal que primer el " +"registreu." + 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 @@ 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 @@ 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)" - -#, fuzzy +msgstr "Vos han fet fora d'este MultiMX." + msgid "was kicked" -msgstr "bufetejat" - -#, fuzzy +msgstr "ha estat fet fora" + msgid "_Room Name:" -msgstr "_Sala:" +msgstr "Nom de la _Sala:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Teniu correu!" - -#, fuzzy +msgstr "Heu convidat" + 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 @@ 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 @@ "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 @@ #, 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 @@ #, 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 @@ #, 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 @@ 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 @@ "%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 @@ "(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 @@ "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 @@ "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 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #, 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 @@ 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 @@ #, 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 @@ 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 @@ msgstr "topic [<tema nou>]: mostra o canvia el tema" msgid "join <channel> [<password>]: Join a chat on this network" -msgstr "join <canal> [<contrasenya>]: entra en un xat d'esta xarxa" +msgstr "" +"join <canal> [<contrasenya>]: 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 @@ 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 @@ 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 @@ #, 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 @@ "%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 @@ 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 @@ "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 @@ "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 @@ "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 @@ msgid "inst <instance>: Set the instance to be used on this class" msgstr "" -"inst <instància>: especifica la instància a fer servir en esta classe" +"inst <instància>: especifica la instància a fer servir en esta " +"classe" msgid "topic <instance>: Set the instance to be used on this class" msgstr "" -"topic <instància>: especifica la instància a fer servir en esta classe" +"topic <instància>: especifica la instància a fer servir en esta " +"classe" msgid "sub <class> <instance> <recipient>: Join a new chat" msgstr "" @@ -11198,8 +11199,8 @@ "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 @@ "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 @@ "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 @@ "<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 @@ "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 @@ #, 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 @@ #, 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" - -#, fuzzy +"Ara s'eixirà atès que ja hi ha un altre client del libpurple executant-" +"se.\n" + msgid "_Media" -msgstr "/_Medi" - -#, fuzzy +msgstr "_Medi" + msgid "_Hangup" -msgstr "Penja" +msgstr "_Penja" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -13962,8 +13962,7 @@ 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 @@ "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 @@ "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 @@ 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 @@ "\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 @@ #, 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 @@ 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 @@ #~ 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 @@ #~ "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"
--- a/po/cs.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/cs.po Sat Sep 11 19:03:25 2010 +0000 @@ -9,8 +9,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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" - -#, fuzzy, c-format +msgstr "Server může vyžadovat textovou autentizaci v nešifrovaném proudu" + +#, 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 @@ 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 @@ 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 @@ 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 @@ 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." - -#, fuzzy +msgstr "MXit ID není registrováno. Nejdřív se registrujte." + 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 @@ 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 @@ msgstr "Povolit zobrazení spouštěcí obrazovky" #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "Byl jste vykopnut: (%s)" - -#, fuzzy +msgstr "Byl jste vykopnut z MultiMX." + msgid "was kicked" -msgstr "Špatný lístek" - -#, fuzzy +msgstr "byl vykopnut" + 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!" - -#, fuzzy +msgstr "Přišlo vám pozvání" + 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 @@ 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 @@ 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 @@ " %s" msgid "Smile!" -msgstr "Úsměv!" +msgstr "Smajlík!" msgid "_Manage custom smileys" msgstr "_Spravovat uživatelské smajlíky" @@ -12845,7 +12829,7 @@ 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 @@ 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" - -#, fuzzy +msgstr "_Média" + 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 @@ 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 @@ 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 @@ #~ 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."
--- a/po/da.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/da.po Sat Sep 11 19:03:25 2010 +0000 @@ -812,7 +812,7 @@ 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 @@ #~ 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."
--- a/po/de.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/de.po Sat Sep 11 19:03:25 2010 +0000 @@ -11,14 +11,14 @@ 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 @@ 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 @@ msgid "Domain" msgstr "Domain" -msgid "Require SSL/TLS" -msgstr "SSL/TLS voraussetzen" - -msgid "Force old (port 5223) SSL" -msgstr "Erzwinge altes SSL (Port 5223)" +msgid "Require encryption" +msgstr "Verschlüsselung fordern" + +msgid "Use encryption if available" +msgstr "Verschlüsselung benutzen, wenn verfügbar" + +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 @@ 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 @@ "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 @@ 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 @@ 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." - -#, fuzzy +"Die von Ihnen eingegebene MXit-ID ist nicht registriert. Bitte registrieren " +"Sie Sich zuerst." + 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 @@ 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 @@ msgstr "_Raumname:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Sie haben Post!" - -#, fuzzy +msgstr "Sie haben eingeladen" + 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 @@ #, 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 @@ #, 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 @@ 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 @@ 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 @@ 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 @@ "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[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 @@ 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 @@ 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 @@ 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 @@ #, 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 @@ msgid "Computer" msgstr "Computer" +msgid "Mobile Phone" +msgstr "Handynummer" + msgid "PDA" msgstr "PDA" @@ -10589,6 +10432,9 @@ msgid "Write Error" msgstr "Schreibfehler" +msgid "IP Address" +msgstr "IP-Adresse" + msgid "Yahoo! Japan Profile" msgstr "Yahoo!-Japan-Profil" @@ -10630,6 +10476,9 @@ msgid "Cool Link 3" msgstr "Cooler Link 3" +msgid "Member Since" +msgstr "Mitglied seit" + msgid "Last Update" msgstr "Letzte Aktualisierung" @@ -11256,6 +11105,11 @@ "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 @@ 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 @@ "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 @@ #, 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 @@ 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" - -#, fuzzy +msgstr "_Medien" + msgid "_Hangup" -msgstr "Auflegen" +msgstr "_Auflegen" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -13659,6 +13513,9 @@ msgid "_TURN server:" msgstr "_TURN-Server:" +msgid "_UDP Port:" +msgstr "_UDP-Port:" + msgid "Use_rname:" msgstr "_Benutzername:" @@ -14154,6 +14011,10 @@ "<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 @@ 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 @@ msgid "Half Operator" msgstr "Half-Operator" +msgid "Voice" +msgstr "Stimme" + msgid "Authorization dialog" msgstr "Autorisierungsdialog" @@ -15279,6 +15143,9 @@ 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 @@ 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 @@ #, 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 @@ #. 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."
--- a/po/dz.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/dz.po Sat Sep 11 19:03:25 2010 +0000 @@ -818,7 +818,7 @@ msgid "Waiting for transfer to begin" msgstr "གནས་སོར་འགོ་བཙུགས་ནིའི་དོན་ལུ་བསྒུག་དོ།" -msgid "Canceled" +msgid "Cancelled" msgstr "ཆ་མེད་བཏང་ཡི།" msgid "Failed" @@ -16889,7 +16889,7 @@ #~ 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."
--- a/po/el.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/el.po Sat Sep 11 19:03:25 2010 +0000 @@ -804,7 +804,7 @@ msgid "Waiting for transfer to begin" msgstr "Αναμονή έναρξης μεταφοράς" -msgid "Canceled" +msgid "Cancelled" msgstr "Ακυρώθηκε" msgid "Failed" @@ -16284,7 +16284,7 @@ #~ 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 "" #~ "Αποτυχία μεταφοράς αρχείου. Πιθανώς να ακυρώθηκε από την άλλη πλευρά."
--- a/po/en_AU.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/en_AU.po Sat Sep 11 19:03:25 2010 +0000 @@ -834,8 +834,8 @@ 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 @@ #, 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 @@ #, 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 @@ #, fuzzy msgid "Place Closed" -msgstr "Canceled" +msgstr "Cancelled" msgid "Microphone" msgstr "" @@ -17062,8 +17062,8 @@ #~ 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."
--- a/po/en_CA.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/en_CA.po Sat Sep 11 19:03:25 2010 +0000 @@ -834,7 +834,7 @@ msgid "Waiting for transfer to begin" msgstr "Waiting for transfer to begin" -msgid "Canceled" +msgid "Cancelled" msgstr "Cancelled" msgid "Failed" @@ -17050,7 +17050,7 @@ #~ 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."
--- a/po/en_GB.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/en_GB.po Sat Sep 11 19:03:25 2010 +0000 @@ -793,7 +793,7 @@ msgid "Waiting for transfer to begin" msgstr "Waiting for transfer to begin" -msgid "Canceled" +msgid "Cancelled" msgstr "Cancelled" msgid "Failed"
--- a/po/eo.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/eo.po Sat Sep 11 19:03:25 2010 +0000 @@ -766,7 +766,7 @@ msgid "Waiting for transfer to begin" msgstr "Atendante la alŝutoeko" -msgid "Canceled" +msgid "Cancelled" msgstr "Rezignita" msgid "Failed"
--- a/po/es.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/es.po Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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" - -#, fuzzy +msgstr "_Media" + msgid "_Hangup" -msgstr "Colgar" +msgstr "_Colgar" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -15571,6 +15566,9 @@ 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"
--- a/po/et.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/et.po Sat Sep 11 19:03:25 2010 +0000 @@ -795,7 +795,7 @@ msgid "Waiting for transfer to begin" msgstr "Oodatakse ülekande algust" -msgid "Canceled" +msgid "Cancelled" msgstr "Tühistatud" msgid "Failed" @@ -16081,7 +16081,7 @@ #~ 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."
--- a/po/eu.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/eu.po Sat Sep 11 19:03:25 2010 +0000 @@ -801,7 +801,7 @@ 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 @@ #~ 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."
--- a/po/fa.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/fa.po Sat Sep 11 19:03:25 2010 +0000 @@ -808,7 +808,7 @@ msgid "Waiting for transfer to begin" msgstr "در حال انتظار برای آغاز انتقال" -msgid "Canceled" +msgid "Cancelled" msgstr "صرف نظر شد" msgid "Failed" @@ -16683,7 +16683,7 @@ #~ 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."
--- a/po/fi.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/fi.po Sat Sep 11 19:03:25 2010 +0000 @@ -802,7 +802,7 @@ msgid "Waiting for transfer to begin" msgstr "Odotetaan lähetyksen alkamista" -msgid "Canceled" +msgid "Cancelled" msgstr "Peruutettu" msgid "Failed" @@ -16262,7 +16262,7 @@ #~ 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 @@ #~ 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..."
--- a/po/fr.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/fr.po Sat Sep 11 19:03:25 2010 +0000 @@ -21,14 +21,14 @@ 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 @@ 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 @@ 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 @@ 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 @@ "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 @@ "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 @@ 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 @@ 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é." - -#, fuzzy, c-format +"Le serveur peut demander une authentification en texte non chiffré au " +"travers d'un flux non crypté." + +#, 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 @@ 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 @@ "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 @@ 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 @@ 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." - -#, fuzzy +"L'identifiant MXit saisi n'est pas enregistré. Veuillez l'enregistrer " +"d'abord." + 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 @@ 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 @@ 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)" - -#, fuzzy +msgstr "Vous avez été expulsé de ce MultiMX." + msgid "was kicked" -msgstr "Mauvais ticket" - -#, fuzzy +msgstr "a été expulsé" + msgid "_Room Name:" msgstr "_Salon :" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Vous avez du courrier !" - -#, fuzzy +msgstr "Vous avez été invité" + 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 @@ "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 @@ 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 @@ 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 @@ "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 @@ #, 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 @@ 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" - -#, fuzzy +msgstr "_Média" + msgid "_Hangup" -msgstr "Raccrocher" +msgstr "_Raccrocher" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -14852,8 +14840,8 @@ "'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 @@ #, 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 @@ 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 @@ #~ 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."
--- a/po/ga.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ga.po Sat Sep 11 19:03:25 2010 +0000 @@ -750,7 +750,7 @@ msgstr "" #, fuzzy -msgid "Canceled" +msgid "Cancelled" msgstr "Cealaithe" #, fuzzy
--- a/po/gl.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/gl.po Sat Sep 11 19:03:25 2010 +0000 @@ -807,7 +807,7 @@ msgid "Waiting for transfer to begin" msgstr "Agardando o comezo da transferencia" -msgid "Canceled" +msgid "Cancelled" msgstr "Cancelado" msgid "Failed"
--- a/po/gu.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/gu.po Sat Sep 11 19:03:25 2010 +0000 @@ -789,7 +789,7 @@ msgid "Waiting for transfer to begin" msgstr "પરિવહન શરૂ થવા માટે રાહ જોઈ રહ્યા છીએ" -msgid "Canceled" +msgid "Cancelled" msgstr "રદ થયેલ" msgid "Failed"
--- a/po/he.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/he.po Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ msgid "Error" msgstr "שגיאה" -#, fuzzy msgid "Account was not modified" -msgstr "החשבון לא נוסף" +msgstr "החשבון לא עודכן" msgid "Account was not added" msgstr "החשבון לא נוסף" @@ -72,11 +71,11 @@ 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 @@ msgid "Waiting for transfer to begin" msgstr "ממתין להעברה להתחיל" -msgid "Canceled" +msgid "Cancelled" msgstr "בוטל" msgid "Failed" @@ -1652,7 +1651,7 @@ 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 @@ 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 +msgstr "ייתכן והשרת דורש אימות לא מוצפן מעל תקשורת לא מוצפנת" + +#, 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 @@ 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 @@ 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 @@ 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 @@ msgid "Invalid country selected. Please try again." msgstr "נבחרה ארץ לא-חוקית. יש לנסות שנית." -#, fuzzy msgid "The MXit ID you entered is not registered. Please register first." -msgstr "שם המשתמש אינו רשום. חובה להירשם קודם." - -#, fuzzy +msgstr "מזהה ה- Mxit שהוזן אינו רשום. חובה להירשם קודם." + 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 @@ 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 @@ msgstr "אפשר פתיחת חלון-הקדמה" #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "נבעטת: (%s)" - -#, fuzzy +msgstr "נבעטת מתוך MultiMX זה." + msgid "was kicked" -msgstr "כרטיס לא תקין" - -#, fuzzy +msgstr "נבעט/ה" + msgid "_Room Name:" -msgstr "_חדר:" +msgstr "שם _חדר:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "יש לך דואר!" - -#, fuzzy +msgstr "הוזמנת" + 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 @@ msgstr "SNAC לא תקף" msgid "Server rate limit exceeded" -msgstr "" +msgstr "הפרזת מעבר למגבלת השרת" msgid "Client rate limit exceeded" -msgstr "" +msgstr "הפרזת מעבר למגבלת הלקוח" msgid "Service unavailable" msgstr "השירות אינו זמין" @@ -9945,9 +9932,8 @@ 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 @@ msgid "Exiting because another libpurple client is already running.\n" msgstr "מסיים מכיוון שכבר רצה תוכנה אחרת שהמשתמש בספריית libpurple.\n" -#, fuzzy msgid "_Media" -msgstr "/_מדיה" - -#, fuzzy +msgstr "_מדיה" + msgid "_Hangup" -msgstr "התנתק" +msgstr "הת_נתק" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -15008,6 +14992,9 @@ 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 "התעודה עדיין אינה תקפה."
--- a/po/hi.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/hi.po Sat Sep 11 19:03:25 2010 +0000 @@ -780,7 +780,7 @@ msgid "Waiting for transfer to begin" msgstr "हस्तांतरण के शुरु होने की प्रतीक्षा करता है." -msgid "Canceled" +msgid "Cancelled" msgstr "रद्द" msgid "Failed"
--- a/po/hu.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/hu.po Sat Sep 11 19:03:25 2010 +0000 @@ -9,14 +9,14 @@ 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 @@ 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 @@ 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 @@ msgid "me <action>: Send an IRC style action to a buddy or chat." msgstr "" -"me <művelet>: IRC stílusú művelet küldése egy partnernak vagy " +"me <művelet>: IRC stílusú művelet küldése egy partnernek vagy " "csevegésnek." msgid "" @@ -802,7 +804,7 @@ 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 @@ "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 @@ "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 @@ 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" - -#, fuzzy, c-format +"A kiszolgáló egyszerű szöveges hitelesítést követel meg egy nem titkosított " +"csatornán" + +#, 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 @@ 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 @@ 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 @@ 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 @@ 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." - -#, fuzzy +msgstr "A megadott MXit azonosító nincs regisztrálva. Először regisztráljon." + 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 @@ 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 @@ 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)" - -#, fuzzy +msgstr "Kirúgták ebből a MultiMX-ből." + msgid "was kicked" -msgstr "Rossz jegy" - -#, fuzzy +msgstr "kirúgva" + msgid "_Room Name:" -msgstr "Sz_oba:" +msgstr "Sz_obanév:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Levele érkezett!" - -#, fuzzy +msgstr "Meghívták" + 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 @@ #, 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 @@ "%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 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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 @@ 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 @@ "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 "" - -#, fuzzy +msgstr "A kliens sebességkorlátja túllépve" + 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 "" - -#, fuzzy +msgstr "Elavult SNAC" + msgid "Not supported by host" -msgstr "Nem támogatott" - -#, fuzzy +msgstr "A kiszolgáló nem támogatja" + 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 "" - -#, fuzzy +msgstr "A válasz túl nagy" + msgid "Responses lost" -msgstr "Válasz valószínűsége:" - -#, fuzzy +msgstr "A válaszok elvesztek" + 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 "" - -#, fuzzy +msgstr "A figyelmeztetési szint túl magas (fogadó)" + msgid "User temporarily unavailable" -msgstr "A szolgáltatás átmenetileg nem érhető el" - -#, fuzzy +msgstr "A felhasználó átmenetileg nem érhető el" + msgid "No match" msgstr "Nincs találat" -#, fuzzy msgid "List overflow" -msgstr "A lista megtelt" - -#, fuzzy +msgstr "A lista túlcsordult" + 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 @@ msgid "Computer" msgstr "Számítógép" +msgid "Mobile Phone" +msgstr "Mobiltelefon" + msgid "PDA" msgstr "PDA" @@ -10232,9 +10062,8 @@ 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 @@ 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 @@ 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 @@ #, 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 @@ "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 @@ "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 @@ "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 @@ #, 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 @@ 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" - -#, fuzzy +msgstr "Méd_ia" + 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 @@ "<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 @@ msgid "Half Operator" msgstr "Féloperátor" +msgid "Voice" +msgstr "Hang" + msgid "Authorization dialog" msgstr "Hitelesítési ablak" @@ -15266,7 +15110,7 @@ "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 @@ #, 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 @@ 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"
--- a/po/hy.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/hy.po Sat Sep 11 19:03:25 2010 +0000 @@ -755,7 +755,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "" msgid "Failed"
--- a/po/id.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/id.po Sat Sep 11 19:03:25 2010 +0000 @@ -815,7 +815,7 @@ msgid "Waiting for transfer to begin" msgstr "Menunggu transfer untuk mulai" -msgid "Canceled" +msgid "Cancelled" msgstr "Dibatalkan" msgid "Failed" @@ -16769,7 +16769,7 @@ #~ 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."
--- a/po/it.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/it.po Sat Sep 11 19:03:25 2010 +0000 @@ -808,7 +808,7 @@ msgid "Waiting for transfer to begin" msgstr "In attesa dell'inizio del trasferimento" -msgid "Canceled" +msgid "Cancelled" msgstr "Annullato" msgid "Failed"
--- a/po/ja.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ja.po Sat Sep 11 19:03:25 2010 +0000 @@ -808,7 +808,7 @@ msgid "Waiting for transfer to begin" msgstr "転送開始を待っています" -msgid "Canceled" +msgid "Cancelled" msgstr "キャンセルしました" msgid "Failed" @@ -16759,7 +16759,7 @@ #~ 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 "" #~ "ファイル転送が失敗しました。おそらく向こう側がキャンセルしたのでしょう。"
--- a/po/ka.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ka.po Sat Sep 11 19:03:25 2010 +0000 @@ -807,7 +807,7 @@ msgid "Waiting for transfer to begin" msgstr "ველოდები გადატანის დაწყებას" -msgid "Canceled" +msgid "Cancelled" msgstr "გაუქმებულია" #, fuzzy
--- a/po/km.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/km.po Sat Sep 11 19:03:25 2010 +0000 @@ -777,7 +777,7 @@ msgid "Waiting for transfer to begin" msgstr "រង់ចាំការផ្ទេរចាប់ផ្ដើម" -msgid "Canceled" +msgid "Cancelled" msgstr "បានបោះបង់" msgid "Failed"
--- a/po/kn.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/kn.po Sat Sep 11 19:03:25 2010 +0000 @@ -802,7 +802,7 @@ msgid "Waiting for transfer to begin" msgstr "ವರ್ಗಾವಣೆಯ ಪ್ರಾರಂಭಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ" -msgid "Canceled" +msgid "Cancelled" msgstr "ರದ್ದಾಗಿದೆ" msgid "Failed" @@ -15930,7 +15930,7 @@ #~ 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."
--- a/po/ko.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ko.po Sat Sep 11 19:03:25 2010 +0000 @@ -816,7 +816,7 @@ msgid "Waiting for transfer to begin" msgstr "전송 시작을 기다리고 있습니다." -msgid "Canceled" +msgid "Cancelled" msgstr "취소되었습니다." msgid "Failed" @@ -16691,7 +16691,7 @@ #~ 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."
--- a/po/ku.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ku.po Sat Sep 11 19:03:25 2010 +0000 @@ -828,7 +828,7 @@ msgid "Waiting for transfer to begin" msgstr "Li benda destpêkirina transferê ye" -msgid "Canceled" +msgid "Cancelled" msgstr "Hate Betalkirin" msgid "Failed"
--- a/po/lo.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/lo.po Sat Sep 11 19:03:25 2010 +0000 @@ -744,7 +744,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "" msgid "Failed"
--- a/po/lt.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/lt.po Sat Sep 11 19:03:25 2010 +0000 @@ -826,7 +826,7 @@ msgid "Waiting for transfer to begin" msgstr "Laukiama perdavimo pradžios" -msgid "Canceled" +msgid "Cancelled" msgstr "Atšaukta" msgid "Failed"
--- a/po/mk.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/mk.po Sat Sep 11 19:03:25 2010 +0000 @@ -806,7 +806,7 @@ msgid "Waiting for transfer to begin" msgstr "Чекам да започне преносот" -msgid "Canceled" +msgid "Cancelled" msgstr "Откажано" msgid "Failed" @@ -16667,7 +16667,7 @@ #~ 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."
--- a/po/ml.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ml.po Sat Sep 11 19:03:25 2010 +0000 @@ -788,7 +788,7 @@ msgid "Waiting for transfer to begin" msgstr "ഇടപാടു് ആരംഭിക്കുന്നതിനായി കാത്തിരിക്കുന്നു" -msgid "Canceled" +msgid "Cancelled" msgstr "റദ്ദാക്കിയിരിക്കുന്നു" msgid "Failed"
--- a/po/mn.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/mn.po Sat Sep 11 19:03:25 2010 +0000 @@ -774,7 +774,7 @@ msgid "Waiting for transfer to begin" msgstr "Файл шилжүүлэлт эхлүүлэхийг хүлээж байна" -msgid "Canceled" +msgid "Cancelled" msgstr "Цуцлагдсан" msgid "Failed" @@ -15602,7 +15602,7 @@ #~ 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."
--- a/po/mr.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/mr.po Sat Sep 11 19:03:25 2010 +0000 @@ -779,7 +779,7 @@ msgid "Waiting for transfer to begin" msgstr "स्थानांतर सुरू करण्याची प्रतिक्षा करत आहे" -msgid "Canceled" +msgid "Cancelled" msgstr "रद्द केले" msgid "Failed"
--- a/po/ms_MY.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ms_MY.po Sat Sep 11 19:03:25 2010 +0000 @@ -741,7 +741,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "" msgid "Failed"
--- a/po/my_MM.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/my_MM.po Sat Sep 11 19:03:25 2010 +0000 @@ -834,7 +834,7 @@ msgid "Waiting for transfer to begin" msgstr "Waiting for transfer to begin" -msgid "Canceled" +msgid "Cancelled" msgstr "Cancelled" msgid "Failed" @@ -17057,7 +17057,7 @@ #~ 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."
--- a/po/nb.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/nb.po Sat Sep 11 19:03:25 2010 +0000 @@ -803,7 +803,7 @@ 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 @@ #~ 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."
--- a/po/ne.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ne.po Sat Sep 11 19:03:25 2010 +0000 @@ -824,7 +824,7 @@ msgid "Waiting for transfer to begin" msgstr "स्थानान्तरण सुरू गर्नकोलागि पर्खिरहेको" -msgid "Canceled" +msgid "Cancelled" msgstr "रद्द गरियो" msgid "Failed" @@ -17025,7 +17025,7 @@ #~ 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."
--- a/po/nl.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/nl.po Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ msgid "Waiting for transfer to begin" msgstr "Wacht op starten van overdracht" -msgid "Canceled" +msgid "Cancelled" msgstr "Geannuleerd" msgid "Failed" @@ -5970,8 +5970,8 @@ 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 @@ 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 @@ 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" - -#, fuzzy +msgstr "_Media" + msgid "_Hangup" -msgstr "Ophangen" +msgstr "_Ophangen" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -15325,7 +15320,7 @@ "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 @@ 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"
--- a/po/nn.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/nn.po Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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." - -#, fuzzy +msgstr "MXit-id-en du brukte er ikkje registrert. Registrer deg først." + 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 @@ 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 @@ msgstr "Rom_namn:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Du har fått e-post." - -#, fuzzy +msgstr "Du har invitert " + 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 @@ 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" - -#, fuzzy +msgstr "_Media" + msgid "_Hangup" -msgstr "Legg på" +msgstr "_Legg på" #, c-format msgid "%s wishes to start an audio/video session with you."
--- a/po/oc.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/oc.po Sat Sep 11 19:03:25 2010 +0000 @@ -754,7 +754,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "Anullat" msgid "Failed"
--- a/po/or.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/or.po Sat Sep 11 19:03:25 2010 +0000 @@ -799,7 +799,7 @@ msgid "Waiting for transfer to begin" msgstr "ସ୍ଥାନାନ୍ତରଣ ଆରମ୍ଭ ହେବାକୁ ଅପେକ୍ଷା କରୁଛି" -msgid "Canceled" +msgid "Cancelled" msgstr "ବାତିଲ କରାଗଲା" msgid "Failed"
--- a/po/pa.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/pa.po Sat Sep 11 19:03:25 2010 +0000 @@ -8,10 +8,10 @@ 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 @@ msgid "Error" msgstr "ਗਲਤੀ" -#, fuzzy msgid "Account was not modified" -msgstr "ਅਕਾਊਂਟ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਗਿਆ" +msgstr "ਅਕਾਊਂਟ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ" msgid "Account was not added" msgstr "ਅਕਾਊਂਟ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਗਿਆ" @@ -76,11 +75,11 @@ 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 @@ msgid "Waiting for transfer to begin" msgstr "ਭੇਜਣ ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਉਡੀਕ ਜਾਰੀ" -msgid "Canceled" +msgid "Cancelled" msgstr "ਰੱਦ ਹੈ" msgid "Failed" @@ -1251,9 +1250,8 @@ msgid "Someone says your username in chat" msgstr "ਕਿਸੇ ਨੇ ਤੁਹਾਡਾ ਨਾਂ ਗੱਲਬਾਤ ਦੌਰਾਨ ਲਿਆ ਹੈ" -#, fuzzy msgid "Attention received" -msgstr "ਐਕਟੀਵੇਸ਼ਨ ਲੋੜੀਦੀ" +msgstr "ਐਕਟੀਵੇਸ਼ਨ ਲੋੜੀਦੀ ਹੈ" msgid "GStreamer Failure" msgstr "ਜੀਸਟਰੀਮਰ ਫੇਲ੍ਹ" @@ -1636,13 +1634,11 @@ msgid "Set User Info" msgstr "ਯੂਜ਼ਰ ਜਾਣਕਾਰੀ ਦਿਓ" -#, fuzzy msgid "This protocol does not support setting a public alias." -msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਗੱਲਬਾਤ ਰੂਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" - -#, fuzzy +msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਪਬਲਿਕ ਉਪ-ਨਾਂ ਲੈਣ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" + msgid "This protocol does not support fetching the public alias." -msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਗੱਲਬਾਤ ਰੂਮ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" +msgstr "ਇਹ ਪ੍ਰੋਟੋਕਾਲ ਪਬਲਿਕ ਉਪ-ਨਾਂ ਲੈਣ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।" msgid "Unknown" msgstr "ਅਣਜਾਣ" @@ -1664,7 +1660,7 @@ 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 @@ 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 +msgstr "ਸਰਵਰ ਨੂੰ ਇੱਕ ਗ਼ੈਰ-ਇੰਕ੍ਰਿਪਟਡ ਸਟਰੀਮ ਲਈ ਪਲੇਨ-ਟੈਕਸਟ ਪਰਮਾਣਕਿਤਾ ਦੀ ਲੋੜ ਹੋ ਸਕਦੀ ਹੈ।" + +#, 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 @@ msgid "SASL error: %s" msgstr "SASL ਗਲਤੀ: %s" -#, fuzzy msgid "Invalid Encoding" -msgstr "ਗਲਤ ਇੰਪੁੱਟ ਹਾਲਤ" - -#, fuzzy +msgstr "ਗਲਤ ਇੰਕੋਡਿੰਗ" + 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 "" - -#, fuzzy +"ਸਰਵਰ ਚੈਨਲ ਬਾਈਡਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ, ਪਰ ਐਲਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਪਦਾ ਹੈ। ਇਹ MITM ਹਮਲੇ ਦੇ ਸੰਕੇਤ " +"ਹੋ ਸਕਦਾ ਹੈ।" + msgid "Server does not support channel binding" -msgstr "ਸਰਵਰ ਪਾਬੰਦੀ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" - -#, fuzzy +msgstr "ਸਰਵਰ ਚੈਨਲ ਬਾਈਡਿੰਗ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + 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 @@ 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 @@ msgid "Allow Buzz" msgstr "ਬੱਜ਼ ਮਨਜ਼ੂਰ" -#, fuzzy msgid "Mood Name" -msgstr "ਮੱਧ ਨਾਂ" - -#, fuzzy +msgstr "ਮੂਡ ਨਾਂ" + msgid "Mood Comment" -msgstr "ਸੁਨੇਹੀ ਟਿੱਪਣੀ" +msgstr "ਮੂਡ ਟਿੱਪਣੀ" #. primitive #. ID @@ -4578,9 +4567,8 @@ 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 @@ 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 @@ 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 @@ msgstr "ਫਾਇਲ %s ਨੂੰ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ ਹੈ, ਫਾਇਲ ਟਰਾਂਸਫਰ ਲਈ ਸਹਿਯੋਗੀ ਨਹੀਂ" msgid "File Send Failed" -msgstr "ਫਾਇਲ ਭੇਜਣਾ ਅਸਫਲ" +msgstr "ਫਾਇਲ ਭੇਜਣ ਲਈ ਫੇਲ੍ਹ" #, c-format msgid "Unable to send file to %s, invalid JID" @@ -4803,31 +4789,26 @@ msgid "Please select the resource of %s to which you would like to send a file" msgstr "ਚੁਣੋ ਕਿ ਕਿਹੜੇ %s ਦੇ ਸਰੋਤ ਤੁਸੀਂ ਇੱਕ ਫਾਇਲ ਤੋਂ ਤੁਸੀਂ ਭੇਜਣੇ ਚਾਹੁੰਦੇ ਹੋ" -#, fuzzy msgid "Afraid" -msgstr "ਅਰਬੀ" - -#, fuzzy +msgstr "ਡਰਿਆ" + msgid "Amazed" -msgstr "ਸ਼ਰਮਸ਼ਾਰ" - -#, fuzzy +msgstr "ਡੌਰ-ਭੌਰ" + 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 @@ msgid "Bored" msgstr "ਅੱਕਿਆ" -#, fuzzy msgid "Brave" -msgstr "ਸੰਭਾਲੋ" - -#, fuzzy +msgstr "ਦਲੇਰ" + msgid "Calm" -msgstr "ਰੀਲੇਮ" - -#, fuzzy +msgstr "ਸ਼ਾਂਤ" + msgid "Cautious" -msgstr "ਗੱਲਬਾਤ" - -#, fuzzy +msgstr "ਚੌਕਸ" + msgid "Cold" -msgstr "ਗੂੜੇ" - -#, fuzzy +msgstr "ਠੰਡ" + msgid "Confident" -msgstr "ਟਕਰਾ" - -#, fuzzy +msgstr "ਹੌਸਲੇ ਨਾਲ" + msgid "Confused" -msgstr "ਜਾਰੀ ਰੱਖੋ" - -#, fuzzy +msgstr "ਉਲਝਿਆ" + msgid "Contemplative" -msgstr "ਸੰਪਰਕ" - -#, fuzzy +msgstr "ਅੰਤਰ ਧਿਆਨ" + msgid "Contented" -msgstr "ਜੁੜਿਆ" - -#, fuzzy +msgstr "ਪਰਸੰਨ" + msgid "Cranky" -msgstr "ਕੰਪਨੀ" +msgstr "ਵੈਹਮੀ" msgid "Crazy" -msgstr "" - -#, fuzzy +msgstr "ਝੱਲਾ" + msgid "Creative" -msgstr "ਬਣਾਓ" - -#, fuzzy +msgstr "ਸਿਰਜਣਸ਼ੀਲ" + msgid "Curious" -msgstr "ਸ਼ਾਨਦਾਰ" - -#, fuzzy +msgstr "ਜਿਆਸੂ" + msgid "Dejected" -msgstr "ਇਨਕਾਰ ਕੀਤਾ" - -#, fuzzy +msgstr "ਨਿੰਮੌਝੂਣਾ" + msgid "Depressed" -msgstr "ਹਟਾਇਆ" - -#, fuzzy +msgstr "ਦੁਖੀ" + msgid "Disappointed" -msgstr "ਕੁਨੈਕਸ਼ਨ ਬੰਦ ਹੈ।" +msgstr "ਨਿਰਾਸ਼" msgid "Disgusted" -msgstr "" - -#, fuzzy +msgstr "ਅੱਕਿਆ" + msgid "Dismayed" -msgstr "ਆਯੋਗ ਹੈ" - -#, fuzzy +msgstr "ਡਰਿਆ" + msgid "Distracted" -msgstr "ਅੱਡ" +msgstr "ਬੇਧਿਆਨਾ" msgid "Embarrassed" -msgstr "" - -#, fuzzy +msgstr "ਪਰੇਸ਼ਾਨ" + msgid "Envious" -msgstr "ਬੇਚੈਨ" +msgstr "ਈਰਖਾਲੂ" msgid "Excited" msgstr "ਜੋਸ਼ ਵਿੱਚ" -#, fuzzy msgid "Flirtatious" -msgstr "ਸ਼ਾਨਦਾਰ" - -#, fuzzy +msgstr "ਨਖ਼ਰੇ" + msgid "Frustrated" -msgstr "ਪਹਿਲਾਂ ਨਾਂ" +msgstr "ਨਿਰਾਸ਼" msgid "Grateful" -msgstr "" - -#, fuzzy +msgstr "ਇਹਸਾਨਮੰਦ" + msgid "Grieving" -msgstr "ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ..." +msgstr "ਸੋਗੀ" msgid "Grumpy" -msgstr "ਗਰੁੰਪੀ" - -#, fuzzy +msgstr "ਰੁੱਖਾ" + msgid "Guilty" -msgstr "ਸ਼ਹਿਰ" +msgstr "ਸ਼ਰਮਿੰਦਾ" msgid "Happy" msgstr "ਖੁਸ਼" msgid "Hopeful" -msgstr "" +msgstr "ਆਸਵੰਦ" msgid "Hot" msgstr "ਹਾਟ" msgid "Humbled" -msgstr "" +msgstr "ਨਿਮਾਣਾ" msgid "Humiliated" -msgstr "" - -#, fuzzy +msgstr "ਜਲੀਲ ਕੀਤਾ" + msgid "Hungry" -msgstr "ਗੁੱਸੇ ਵਿੱਚ" - -#, fuzzy +msgstr "ਭੁੱਖਾ" + msgid "Hurt" -msgstr "ਹਾਸਾ" +msgstr "ਬਦਸਲੂਕੀ" msgid "Impressed" -msgstr "" - -#, fuzzy +msgstr "ਪਰਭਾਵਿਤ" + msgid "In awe" -msgstr "ਪਿਆਰ ਨਾਲ" +msgstr "ਸਨਮਾਨ 'ਚ" msgid "In love" msgstr "ਪਿਆਰ ਨਾਲ" -#, fuzzy msgid "Indignant" -msgstr "ਇੰਡੋਨੇਸ਼ੀਆਈ" - -#, fuzzy +msgstr "ਰੁੱਸਿਆ" + msgid "Interested" -msgstr "ਦਿਲਚਸਪੀਆਂ" - -#, fuzzy +msgstr "ਉਤਸਕ" + msgid "Intoxicated" -msgstr "ਸੱਦਾ ਭੇਜਿਆ" +msgstr "ਮਦਹੋਸ਼" msgid "Invincible" msgstr "ਅਜਿੱਤ" msgid "Jealous" -msgstr "ਈਰਖਾਲੂ" - -#, fuzzy +msgstr "ਈਰਖਈ" + msgid "Lonely" -msgstr "ਬਾਂਦਰ" - -#, fuzzy +msgstr "ਇੱਕਲੇ" + msgid "Lost" -msgstr "ਸਭ ਤੋਂ ਉੱਚੀ" +msgstr "ਗੁਆਚਿਆ" msgid "Lucky" -msgstr "" - -#, fuzzy +msgstr "ਕਿਸਮਤ ਵਾਲਾ" + msgid "Mean" -msgstr "ਜਰਮਨ" - -#, fuzzy +msgstr "ਸ਼ੂਮ" + msgid "Moody" -msgstr "ਮੂਡ" +msgstr "ਦਿਲਗੀਰ" msgid "Nervous" -msgstr "" - -#, fuzzy +msgstr "ਬੌਂਦਲਿਆ" + msgid "Neutral" -msgstr "ਵੇਰਵਾ" - -#, fuzzy +msgstr "ਅਨਿਸ਼ਚਤ" + msgid "Offended" -msgstr "ਆਫਲਾਈਨ" +msgstr "ਦੋਸ਼ੀ" msgid "Outraged" -msgstr "" - -#, fuzzy +msgstr "ਅਤਿੱਆਚਾਰੀ" + msgid "Playful" -msgstr "ਚਲਾਓ" - -#, fuzzy +msgstr "ਰੌਣਕੀ" + msgid "Proud" -msgstr "ਉੱਚੀ" - -#, fuzzy +msgstr "ਮਜ਼ਾਜੀ" + msgid "Relaxed" -msgstr "ਅਸਲੀ ਨਾਂ" - -#, fuzzy +msgstr "ਸੁਸਤ" + msgid "Relieved" -msgstr "ਮਿਲੇ" - -#, fuzzy +msgstr "ਆਰਾਮ 'ਚ" + msgid "Remorseful" -msgstr "ਹਟਾਓ" - -#, fuzzy +msgstr "ਪਸ਼ਚਾਤਾਪਪੂਰਨ" + msgid "Restless" -msgstr "ਰਜਿਸਟਰ" +msgstr "ਬੇਚੈਨ" msgid "Sad" msgstr "ਉਦਾਸ" -#, fuzzy msgid "Sarcastic" -msgstr "ਮਰਾਠੀ" +msgstr "ਵਿਅੰਗਮਈ" msgid "Satisfied" -msgstr "" - -#, fuzzy +msgstr "ਸੰਤੁਸ਼ਟ" + msgid "Serious" -msgstr "ਸ਼ਾਨਦਾਰ" - -#, fuzzy +msgstr "ਗੰਭੀਰ" + msgid "Shocked" -msgstr "ਪਾਬੰਦੀ" +msgstr "ਸਦਮਾ" msgid "Shy" -msgstr "" +msgstr "ਸੰਗਾਊ" msgid "Sick" msgstr "ਬੀਮਾਰ" #. Sleepy / Tired msgid "Sleepy" -msgstr "ਉਬਾਸੀਆਂ" +msgstr "ਉਨੀਂਦਾ" msgid "Spontaneous" -msgstr "" - -#, fuzzy +msgstr "ਲਗਾਤਾਰ" + msgid "Stressed" -msgstr "ਸਪੀਡ" - -#, fuzzy +msgstr "ਦਬਾਅ 'ਚ" + msgid "Strong" -msgstr "ਗੀਤ" +msgstr "ਮਜ਼ਬੂਤ" msgid "Surprised" -msgstr "" +msgstr "ਹੈਰਾਨ" msgid "Thankful" -msgstr "" +msgstr "ਧੰਨਵਾਦੀ" msgid "Thirsty" -msgstr "" - -#, fuzzy +msgstr "ਇੱਛਕ" + msgid "Tired" -msgstr "ਫਾਇਰ" - -#, fuzzy +msgstr "ਥੱਕਿਆ/ਥੱਕੀ" + msgid "Undefined" -msgstr "ਹੇਠਾਂ ਲਾਈਨ" - -#, fuzzy +msgstr "ਅਸਪਸ਼ਟ" + msgid "Weak" -msgstr "ਧੱਫਾ" - -#, fuzzy +msgstr "ਹਲਕਾ" + msgid "Worried" -msgstr "ਅੱਕਿਆ" +msgstr "ਚਿੰਤਾਤੁਰ" msgid "Set User Nickname" msgstr "ਯੂਜ਼ਰ ਨਾਂ ਸੈੱਟ ਕਰੋ" @@ -5352,12 +5285,12 @@ #, 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 @@ 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 @@ 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 @@ msgstr "ਤੁਹਾਡੀ ਪਰੋਫਾਇਲ ਜਾਣਕਾਰੀ ਹਾਲੇ ਲਈ ਨਹੀਂ ਗਈ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।" msgid "Your UID" -msgstr "" +msgstr "ਤੁਹਾਡਾ UID" #. pin #. pin (required) @@ -5990,16 +5922,12 @@ 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 @@ msgid "Invalid country selected. Please try again." msgstr "ਗਲਤ ਦੇਸ਼ ਚੁਣਿਆ। ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।" -#, fuzzy msgid "The MXit ID you entered is not registered. Please register first." -msgstr "ਯੂਜ਼ਰ-ਨਾਂ ਰਜਿਸਟਰ ਨਹੀਂ ਹੈ। ਪਹਿਲਾਂ ਰਜਿਸਟਰ ਕਰੋ ਜੀ।" - -#, fuzzy +msgstr "ਤੁਹਾਡੇ ਵਲੋਂ ਦਿੱਤਾ MXit ID ਰਜਿਸਟਰ ਨਹੀਂ ਹੈ। ਪਹਿਲਾਂ ਰਜਿਸਟਰ ਕਰੋ ਜੀ।" + 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 @@ 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 @@ # , c-format #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "ਤੁਹਾਨੂੰ ਠੁੱਡਾ ਮਾਰਿਆ: (%s)" - -#, fuzzy +msgstr "ਤੁਹਾਨੰ ਇਸ ਮਲਟੀMX ਤੋਂ ਕਿੱਕ ਕੀਤਾ ਗਿਆ।" + msgid "was kicked" -msgstr "ਗਲਤ ਟਿਕਟ" - -#, fuzzy +msgstr "ਕਿੱਕ ਕੀਤਾ" + msgid "_Room Name:" -msgstr "ਰੂਮ(_R):" +msgstr "ਰੂਮ ਨਾਂ(_R):" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "ਤੁਹਾਨੂੰ ਮੇਲ ਆਈ ਹੈ!" - -#, fuzzy +msgstr "ਤੁਹਾਨੂੰ ਸੱਦਾ ਹੈ" + 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 @@ 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 @@ "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 @@ msgstr "%s ਨੂੰ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ ਅਸਮਰੱਥ: %s" msgid "Thinking" -msgstr "" - -#, fuzzy +msgstr "ਸੋਚ ਰਿਹਾ/ਰਹੀ ਹਾਂ" + msgid "Shopping" -msgstr "ਲਿਖਣਾ ਬੰਦ ਕੀਤਾ" - -#, fuzzy +msgstr "ਖਰੀਦਦਾਰੀ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ" + msgid "Questioning" -msgstr "ਸਵਾਲ ਡਾਈਲਾਗ" - -#, fuzzy +msgstr "ਸਵਾਲ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ" + msgid "Eating" -msgstr "ਪੇਜ਼ਿੰਗ" - -#, fuzzy +msgstr "ਖਾਣਾ ਖਾ ਰਿਹਾ/ਰਹੀ ਹਾਂ" + 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 "" - -#, fuzzy +msgstr "TV ਵੇਖਿਆ ਜਾ ਰਿਹਾ ਹੈ" + msgid "Having fun" -msgstr "ਹੈਂਡ ਅੱਪ" - -#, fuzzy +msgstr "ਮੌਜਾਂ ਕਰਦਾ" + msgid "Sleeping" -msgstr "ਉਬਾਸੀਆਂ" +msgstr "ਸੌ ਰਹੇ" msgid "Using a PDA" -msgstr "" - -#, fuzzy +msgstr "PDA ਦੀ ਵਰਤੋਂ" + msgid "Meeting friends" -msgstr "IM ਦੋਸਤ" - -#, fuzzy +msgstr "ਦੋਸਤਾਂ ਨਾਲ ਮਿਲ ਰਹੇ" + 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 "" - -#, fuzzy +msgstr "ਵੈੱਬ ਬਰਾਊਜ਼ ਕਰੋ" + msgid "Smoking" -msgstr "ਗੀਤ" - -#, fuzzy +msgstr "ਸਿਗਰਟ ਪੀ ਰਹੇ" + msgid "Writing" -msgstr "ਕੰਮ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ" +msgstr "ਲਿਖ ਰਹੇ" #. Drinking [Alcohol] -#, fuzzy msgid "Drinking" -msgstr "ਕੰਮ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ" +msgstr "ਪੈੱਗ ਲਾ ਰਹੇ" msgid "Listening to music" msgstr "ਸੰਗੀਤ ਸੁਣ ਰਿਹਾ/ਰਹੀ ਹਾਂ" -#, fuzzy msgid "Studying" -msgstr "ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ" - -#, fuzzy +msgstr "ਪੜ੍ਹ ਰਿਹਾ/ਰਹੀ ਹਾਂ" + msgid "In the restroom" -msgstr "ਦਿਲਚਸਪੀਆਂ" +msgstr "ਆਰਾਮ-ਕਮਰੇ 'ਚ" msgid "Received invalid data on connection with server" msgstr "ਸਰਵਰ ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਉੱਤੇ ਗਲਤ ਡਾਟਾ ਮਿਲਿਆ ਹੈ।" @@ -7141,7 +7046,7 @@ msgstr "ਖੇਡਾਂ" msgid "ICQ Xtraz" -msgstr "" +msgstr "ICQ Xtraz" msgid "Add-Ins" msgstr "ਹੋਰ" @@ -7209,25 +7114,20 @@ msgid "Invisible" msgstr "ਅਦਿੱਖ" -#, fuzzy msgid "Evil" -msgstr "ਈਮੇਲ" - -#, fuzzy +msgstr "ਬੁਰਾ" + msgid "Depression" -msgstr "ਕਿੱਤਾ" - -#, fuzzy +msgstr "ਉਦਾਸੀ" + msgid "At home" -msgstr "ਮੇਰੇ ਬਾਰੇ" - -#, fuzzy +msgstr "ਘਰੇ" + msgid "At work" -msgstr "ਨੈੱਟਵਰਕ" - -#, fuzzy +msgstr "ਕੰਮ ਉੱਤੇ" + msgid "At lunch" -msgstr "ਦੁਪੈਹਰ ਦੇ ਖਾਣੇ ਲਈ ਬਾਹਰ" +msgstr "ਦੁਪੈਹਰ ਦੇ ਖਾਣੇ ਲਈ" msgid "IP Address" msgstr "IP ਐਡਰੈੱਸ" @@ -7704,9 +7604,8 @@ msgid "iTunes Music Store Link" msgstr "iTunes ਸੰਗੀਤ ਸਟੋਰ ਲਿੰਕ" -#, fuzzy msgid "Lunch" -msgstr "ਫਿੰਚ" +msgstr "ਦੁਪਹਿਰ ਦਾ ਖਾਣਾ" #, c-format msgid "Buddy Comment for %s" @@ -7740,9 +7639,8 @@ 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 @@ msgstr "ਗਲਤ SNAC" msgid "Server rate limit exceeded" -msgstr "" +msgstr "ਸਰਵਰ ਰੇਟ ਲਿਮਟ ਵੱਧ ਗਈ" msgid "Client rate limit exceeded" -msgstr "" +msgstr "ਕਲਾਇਟ ਰੇਟ ਲਿਮਟ ਵੱਧ ਗਈ" msgid "Service unavailable" msgstr "ਸਰਵਿਸ ਉਪਲੱਬਧ ਨਹੀਂ" @@ -8218,9 +8116,8 @@ msgstr "ਐਡਮਿਨ" #. XXX: Should this be "Topic"? -#, fuzzy msgid "Room Title" -msgstr "ਰੂਮ ਲਿਸਟ" +msgstr "ਰੂਮ ਟਾਈਟਲ" msgid "Notice" msgstr "ਨੋਟਿਸ" @@ -10109,9 +10006,8 @@ 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 @@ "ਅਕਾਊਂਟ ਲਾਕ ਹੋਇਆ: ਅਣਜਾਣ ਕਾਰਨ। 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 @@ 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 @@ msgid "Extended away" msgstr "ਪਹੁੰਚ ਤੋਂ ਦੂਰ" -#, fuzzy msgid "Feeling" -msgstr "ਮਿਲਿਆ" +msgstr "ਮਹਿਸੂਸ ਕਰ ਰਹੇ" #, c-format msgid "%s (%s) changed status from %s to %s" @@ -11256,13 +11149,11 @@ msgid "Unknown node type" msgstr "ਅਣਜਾਣ ਨੋਡ ਟਾਈਪ" -#, fuzzy msgid "Please select your mood from the list" -msgstr "ਲਿਸਤ ਤੋਂ ਆਪਣਾ ਮੂਡ ਚੁਣੋ ਜੀ।" - -#, fuzzy +msgstr "ਲਿਸਟ 'ਚੋਂ ਆਪਣਾ ਮੂਡ ਚੁਣੋ" + msgid "Message (optional)" -msgstr "ਏਲੀਆਸ (ਚੋਣਵਾਂ)" +msgstr "ਸੁਨੇਹਾ (ਚੋਣਵਾਂ)" msgid "Edit User Mood" msgstr "ਯੂਜ਼ਰ ਮੋਡ ਸੋਧ" @@ -11345,9 +11236,8 @@ 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 @@ 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 "ਸਰਵਰ ਜਾਣਕਾਰੀ" - -#, fuzzy +msgstr "/ਮੱਦਦ/ਡਿਵੈਲਪਰ ਜਾਣਕਾਰੀ(_v)" + msgid "/Help/_Translator Information" -msgstr "ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ" +msgstr "/ਮੱਦਦ/ਅਨੁਵਾਦਕ ਜਾਣਕਾਰੀ(_T)" msgid "/Help/_About" msgstr "/ਮੱਦਦ/ਇਸ ਬਾਰੇ(_A)" @@ -11606,9 +11493,8 @@ msgid "_Edit Account" msgstr "ਅਕਾਊਂਟ ਸੋਧ(_E)" -#, fuzzy msgid "Set _Mood..." -msgstr "ਮੂਡ ਸੈੱਟ ਕਰੋ..." +msgstr "ਮੂਡ ਸੈੱਟ ਕਰੋ(_M)..." msgid "No actions available" msgstr "ਕੋਈ ਕਾਰਵਾਈ ਉਪਲੱਬਧ ਨਹੀਂ" @@ -11728,9 +11614,8 @@ 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 @@ 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 @@ msgid "0 people in room" msgstr "ਰੂਮ ਵਿੱਚ 0 ਵਿਅਕਤੀ" -#, fuzzy msgid "Close Find bar" -msgstr "ਇਹ ਟੈਬ ਬੰਦ ਕਰੋ" - -#, fuzzy +msgstr "ਖੋਜ ਪੱਟੀ ਬੰਦ ਕਰੋ" + msgid "Find:" -msgstr "ਖੋਜ" +msgstr "ਖੋਜ:" #, c-format msgid "%d person in room" @@ -12050,9 +11932,8 @@ msgid "Arabic" msgstr "ਅਰਬੀ" -#, fuzzy msgid "Assamese" -msgstr "ਸ਼ਰਮਸ਼ਾਰ" +msgstr "ਆਸਾਮੀ" msgid "Belarusian Latin" msgstr "ਬੇਲਾਰੂਸੀ ਲੈਟਿਨ" @@ -12063,9 +11944,8 @@ msgid "Bengali" msgstr "ਬੰਗਾਲੀ" -#, fuzzy msgid "Bengali-India" -msgstr "ਬੰਗਾਲੀ" +msgstr "ਬੰਗਾਲੀ-ਭਾਰਤੀ" msgid "Bosnian" msgstr "ਬੋਸਨੀਆਈ" @@ -12181,9 +12061,8 @@ msgid "Macedonian" msgstr "ਮੈਕਡੋਨੀਆਈ" -#, fuzzy msgid "Malayalam" -msgstr "ਮਲਾਏ" +msgstr "ਮਲਿਆਲਮ" msgid "Mongolian" msgstr "ਮੰਗੋਲੀਆਈ" @@ -12209,9 +12088,8 @@ msgid "Occitan" msgstr "ਅੱਸੀਟਾਨ" -#, fuzzy msgid "Oriya" -msgstr "Opera" +msgstr "ਓੜੀਆ" msgid "Punjabi" msgstr "ਪੰਜਾਬੀ" @@ -12294,7 +12172,7 @@ 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 @@ 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 @@ "Channel: #pidgin on irc.freenode.net<BR>\tXMPP MUC: devel@conference.pidgin." "im<BR><BR>" msgstr "" - -#, fuzzy, c-format +"<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>" + +#, 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 @@ "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 @@ 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 @@ msgid "Past Translators" msgstr "ਪੁਰਾਣੀ ਅਨੁਵਾਦਕ" -#, fuzzy, c-format +#, c-format msgid "%s Translator Information" -msgstr "ਹੋਰ ਜਾਣਕਾਰੀ" +msgstr "%s ਅਨੁਵਾਦ ਜਾਣਕਾਰੀ" msgid "_Name" msgstr "ਨਾਂ(_N)" @@ -12771,9 +12651,8 @@ msgid "Insert Smiley" msgstr "ਸਮਾਇਲੀ ਸ਼ਾਮਲ ਕਰੋ" -#, fuzzy msgid "Send Attention" -msgstr "ਭੇਜੋ ਬਟਨ" +msgstr "ਧਿਆਨ ਮੰਗੋ" msgid "<b>_Bold</b>" msgstr "<b>ਗੂੜਾ(_B)</b>" @@ -12821,7 +12700,7 @@ msgstr "ਸਮਾਇਲ(_S)!" msgid "_Attention!" -msgstr "" +msgstr "ਧਿਆਨ ਦਿਓ(_A)!" msgid "Log Deletion Failed" msgstr "ਲਾਗਇਨ ਹਟਾਉਣ ਲਈ ਫੇਲ੍ਹ" @@ -12948,13 +12827,11 @@ msgid "Exiting because another libpurple client is already running.\n" msgstr "ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ, ਕਿਉਂਕਿ ਇੱਕ ਹੋਰ libpurple ਕਲਾਇਟ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ ਹੈ।\n" -#, fuzzy msgid "_Media" -msgstr "/ਮੀਡਿਆ(_M)" - -#, fuzzy +msgstr "ਮੀਡਿਆ(_M)" + msgid "_Hangup" -msgstr "ਹੈਂਡ ਅੱਪ" +msgstr "ਹੈਂਗ ਅੱਪ(_H)" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -13900,9 +13777,8 @@ msgid "_Save File" msgstr "ਫਾਇਲ ਸੰਭਾਲੋ(_S)" -#, fuzzy msgid "Do you really want to clear?" -msgstr "ਕੀ ਤੁਸੀਂ %s ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?" +msgstr "ਕੀ ਤੁਸੀਂ ਸਾਫ਼ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?" msgid "Select color" msgstr "ਰੰਗ ਚੁਣੋ" @@ -14869,21 +14745,18 @@ msgid "Timestamp Format Options" msgstr "ਟਾਈਮ-ਸਟੈਂਪ ਫਾਰਮੈਟ ਚੋਣ" -#, fuzzy, c-format +#, c-format msgid "_Force timestamp format:" -msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)" - -#, fuzzy +msgstr "ਸਮਾਂ-ਮੋਹਰ ਫਾਰਮੈਟ ਲਈ ਮਜ਼ਬੂਰ(_F):" + msgid "Use system default" -msgstr "ਵੇਹੜਾ (ਡੈਸਕਟਾਪ) ਡਿਫਾਲਟ" - -#, fuzzy +msgstr "ਸਿਸਟਮ ਡਿਫਾਲਟ ਵਰਤੋਂ" + msgid "12 hour time format" -msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)" - -#, fuzzy +msgstr "੧੨ ਘੰਟਾ ਸਮਾਂ ਫਾਰਮੈਟ" + msgid "24 hour time format" -msgstr "24-ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ ਲਈ ਮਜ੍ਬੂਰ(_F)" +msgstr "੨੪ ਘੰਟੇ ਸਮਾਂ ਫਾਰਮੈਟ" msgid "Show dates in..." msgstr "ਮਿਤੀ ਵੇਖੋ..." @@ -15078,7 +14951,6 @@ msgstr "ਰਾਅ XMPP ਪ੍ਹੈਰਾ ਭੇਜੋ ਅਤੇ ਲਵੋ" #. * description -#, fuzzy msgid "This plugin is useful for debugging XMPP servers or clients." msgstr "ਇਹ ਪਲੱਗਇਨ XMPP ਸਰਵਰ ਜਾਂ ਕਲਾਇਟ ਡੀਬੱਗ ਲਈ ਫਾਇਦੇਮੰਦ ਹੈ।" @@ -15087,36 +14959,37 @@ "$(^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 @@ "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 @@ "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 "" - -#, fuzzy +msgstr "ਸਪੈਲ ਚੈੱਕ ਕਰਨ ਲਈ ਸਹਿਯੋਗ। (ਇੰਸਟਾਲੇਸ਼ਨ ਲਈ ਇੰਟਰਨੈੱਟ ਕੁਨੈਕਸ਼ਨ ਚਾਹੀਦਾ ਹੈ)" + 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 @@ #~ 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."
--- a/po/pl.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/pl.po Sat Sep 11 19:03:25 2010 +0000 @@ -13,8 +13,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ "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 @@ 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 @@ 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" - -#, fuzzy, c-format +"Serwer może wymagać uwierzytelnienia w zwykłym tekście przez niezaszyfrowany " +"strumień" + +#, 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 @@ 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 @@ 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 @@ 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 @@ 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ć." - -#, fuzzy +"Podany identyfikator MXit nie jest zarejestrowany. Proszę najpierw się " +"zarejestrować." + 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 @@ 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 @@ 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)" - -#, fuzzy +msgstr "Użytkownik został wyrzucony z tego MultiMX." + msgid "was kicked" -msgstr "Błędny bilet" - -#, fuzzy +msgstr "został wyrzucony" + msgid "_Room Name:" -msgstr "_Pokój:" +msgstr "_Nazwa pokoju:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Nowa wiadomość." - -#, fuzzy +msgstr "Zaproszono" + 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 @@ "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 "" - -#, fuzzy +msgstr "Przekroczono ograniczenie prędkości klienta" + 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 "" - -#, fuzzy +msgstr "Przestarzałe SNAC" + msgid "Not supported by host" -msgstr "Nieobsługiwane" - -#, fuzzy +msgstr "Nieobsługiwane przez serwer" + 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 "" - -#, fuzzy +msgstr "Odpowiedź jest za duża" + msgid "Responses lost" -msgstr "Prawdopodobieństwo odpowiedzi:" - -#, fuzzy +msgstr "Utracono odpowiedzi" + 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 "" - -#, fuzzy +msgstr "Poziom ostrzeżenia jest za wysoki (odbiorca)" + msgid "User temporarily unavailable" -msgstr "Usługa jest tymczasowo niedostępna" - -#, fuzzy +msgstr "Użytkownik jest tymczasowo niedostępny" + 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 @@ 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 @@ "Kończenie pracy, ponieważ inny klient biblioteki libpurple jest już " "uruchomiony.\n" -#, fuzzy msgid "_Media" -msgstr "/_Multimedia" - -#, fuzzy +msgstr "_Multimedia" + 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 @@ 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ę"
--- a/po/ps.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ps.po Sat Sep 11 19:03:25 2010 +0000 @@ -779,7 +779,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "فسخ شوه" msgid "Failed"
--- a/po/pt.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/pt.po Sat Sep 11 19:03:25 2010 +0000 @@ -843,7 +843,7 @@ 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 @@ #~ 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."
--- a/po/pt_BR.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/pt_BR.po Sat Sep 11 19:03:25 2010 +0000 @@ -804,7 +804,7 @@ 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 @@ #~ 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."
--- a/po/ro.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ro.po Sat Sep 11 19:03:25 2010 +0000 @@ -807,7 +807,7 @@ msgid "Waiting for transfer to begin" msgstr "Se așteaptă începerea transferului" -msgid "Canceled" +msgid "Cancelled" msgstr "Oprit" msgid "Failed"
--- a/po/ru.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ru.po Sat Sep 11 19:03:25 2010 +0000 @@ -807,7 +807,7 @@ msgid "Waiting for transfer to begin" msgstr "Ожидание начала передачи" -msgid "Canceled" +msgid "Cancelled" msgstr "Отменено" msgid "Failed" @@ -15600,7 +15600,7 @@ "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 @@ #~ 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 "" #~ "Не удалось произвести передачу файлов; вероятно, отменили на той стороне."
--- a/po/si.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/si.po Sat Sep 11 19:03:25 2010 +0000 @@ -757,7 +757,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "අහෝසි කරන්න" msgid "Failed"
--- a/po/sk.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sk.po Sat Sep 11 19:03:25 2010 +0000 @@ -803,7 +803,7 @@ 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 @@ #~ 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."
--- a/po/sl.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sl.po Sat Sep 11 19:03:25 2010 +0000 @@ -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 @@ 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 @@ 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 @@ msgid "Waiting for transfer to begin" msgstr "Čakanje na začetek prenosa" -msgid "Canceled" +msgid "Cancelled" msgstr "Preklicano" msgid "Failed" @@ -1698,6 +1700,8 @@ "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 @@ 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" - -#, fuzzy, c-format +"Strežnik lahko zahteva overovitev z navadnim besedilom preko nešifriranega " +"toka" + +#, 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 @@ 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 @@ 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 @@ 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 @@ 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." - -#, fuzzy +msgstr "" +"ID za MXit, ki ste ga vnesli, ni registriran. Najprej se registrirajte." + 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 @@ 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 @@ msgstr "Omogoči pozdravno okno ob zagonu" #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "Brcnjeni ste bili: (%s)" - -#, fuzzy +msgstr "Brcnjeni ste bili s tega MultiMX." + msgid "was kicked" -msgstr "Napačna vstopnica" - -#, fuzzy +msgstr "je bil brcnjen" + msgid "_Room Name:" -msgstr "_Soba:" +msgstr "_Ime sobe:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Dobili ste pošto!" - -#, fuzzy +msgstr "Povabili ste uporabnika" + 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 @@ "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 "" - -#, fuzzy +msgstr "Prekoračena omejitev hitrosti odjemalca" + 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 "" - -#, fuzzy +msgstr "Zastarel SNAC" + msgid "Not supported by host" -msgstr "Ni podprto" - -#, fuzzy +msgstr "Ni podprto s strani gostitelja" + 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 "" - -#, fuzzy +msgstr "Odgovor preobsežen" + msgid "Responses lost" -msgstr "Verjetnost odgovora:" - -#, fuzzy +msgstr "Odgovori izgubljeni" + 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 "" - -#, fuzzy +msgstr "Raven opozoril previsoka (sprejemnik)" + msgid "User temporarily unavailable" -msgstr "Storitev trenutno ni na voljo" - -#, fuzzy +msgstr "Uporabnik trenutno ni na voljo" + 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 @@ 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 @@ 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" - -#, fuzzy +msgstr "_Mediji" + 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 @@ #. 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 @@ 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."
--- a/po/sq.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sq.po Sat Sep 11 19:03:25 2010 +0000 @@ -814,7 +814,7 @@ msgid "Waiting for transfer to begin" msgstr "Po pritet të fillojë shpërngulja" -msgid "Canceled" +msgid "Cancelled" msgstr "Anuluar" msgid "Failed"
--- a/po/sr.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sr.po Sat Sep 11 19:03:25 2010 +0000 @@ -791,7 +791,7 @@ msgid "Waiting for transfer to begin" msgstr "Чекам да пренос почне" -msgid "Canceled" +msgid "Cancelled" msgstr "Откажи" msgid "Failed" @@ -16453,7 +16453,7 @@ #~ 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."
--- a/po/sr@latin.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sr@latin.po Sat Sep 11 19:03:25 2010 +0000 @@ -792,7 +792,7 @@ 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 @@ #~ 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."
--- a/po/sv.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sv.po Sat Sep 11 19:03:25 2010 +0000 @@ -797,7 +797,7 @@ 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 @@ #~ 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."
--- a/po/sw.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/sw.po Sat Sep 11 19:03:25 2010 +0000 @@ -784,7 +784,7 @@ msgid "Waiting for transfer to begin" msgstr "" -msgid "Canceled" +msgid "Cancelled" msgstr "Imeghairishwa" msgid "Failed"
--- a/po/ta.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ta.po Sat Sep 11 19:03:25 2010 +0000 @@ -795,7 +795,7 @@ msgid "Waiting for transfer to begin" msgstr "பரிமாற்றம் ஆரம்பமாவதற்காக காத்திருக்கிறது" -msgid "Canceled" +msgid "Cancelled" msgstr "தவிர்க்கப்பட்டது" msgid "Failed" @@ -16101,7 +16101,7 @@ #~ 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."
--- a/po/te.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/te.po Sat Sep 11 19:03:25 2010 +0000 @@ -787,7 +787,7 @@ msgid "Waiting for transfer to begin" msgstr "ప్రారంభించడానికి బదిలీ కోసం నిరీక్షణ " -msgid "Canceled" +msgid "Cancelled" msgstr "రద్దుచేయి" msgid "Failed"
--- a/po/th.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/th.po Sat Sep 11 19:03:25 2010 +0000 @@ -804,7 +804,7 @@ msgid "Waiting for transfer to begin" msgstr "กำลังรอการรับส่งแฟ้ม" -msgid "Canceled" +msgid "Cancelled" msgstr "ยกเลิก" msgid "Failed"
--- a/po/tr.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/tr.po Sat Sep 11 19:03:25 2010 +0000 @@ -805,7 +805,7 @@ 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 @@ #~ 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."
--- a/po/uk.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/uk.po Sat Sep 11 19:03:25 2010 +0000 @@ -9,16 +9,16 @@ 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 @@ msgid "Error" msgstr "Помилка" -#, fuzzy msgid "Account was not modified" -msgstr "Обліковий запис не був доданий" +msgstr "Обліковий запис не був змінений" msgid "Account was not added" msgstr "Обліковий запис не був доданий" @@ -76,10 +75,14 @@ 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 @@ msgstr "Не встановлений жодний з додатків протоколів." msgid "(You probably forgot to 'make install'.)" -msgstr "(Можливо, ви забули виконати 'make install'.)" +msgstr "(Можливо, ви забули виконати \"make install\".)" msgid "Modify Account" msgstr "Змінити обліковий запис" @@ -442,13 +445,13 @@ msgstr "За станом" msgid "Alphabetically" -msgstr "За алфавітом" +msgstr "За абеткою" msgid "By Log Size" msgstr "За розміром журналу" msgid "Buddy" -msgstr "Приятель" +msgstr "Контакт" msgid "Chat" msgstr "Балачка" @@ -460,10 +463,10 @@ 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 @@ msgstr "Помилка імпортування сертифікату" msgid "X.509 certificate import failed" -msgstr "Помилка імпорту сертифікату X.509" +msgstr "Помилка імпортування сертифікату X.509" msgid "Select a PEM certificate" msgstr "Вибрати сертифікат PEM" @@ -497,7 +500,7 @@ 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 @@ msgid "Waiting for transfer to begin" msgstr "Очікування початку передачі" -msgid "Canceled" +msgid "Cancelled" msgstr "Скасовано" msgid "Failed" @@ -1694,6 +1697,8 @@ "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 @@ 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 @@ 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 @@ 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 @@ 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 @@ msgid "Invalid country selected. Please try again." msgstr "Вибрана неправильна країна. Будь ласка, спробуйте ще раз." -#, fuzzy msgid "The MXit ID you entered is not registered. Please register first." -msgstr "Ім'я користувача не зареєстроване. Будь ласка, спершу зареєструйтеся." - -#, fuzzy +msgstr "Введений MXit ID не зареєстрований. Будь ласка, спершу зареєструйтеся." + 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 @@ 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 @@ msgstr "Увімкнути виринаючу екранну заставку" #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "Вас викинули: (%s)" - -#, fuzzy +msgstr "Вас викинули з цього MultiMX." + msgid "was kicked" -msgstr "Неправильний білет" - -#, fuzzy +msgstr "був викинутий" + msgid "_Room Name:" -msgstr "_Кімната:" +msgstr "_Назва кімнати:" #. Display system message in chat window -#, fuzzy msgid "You have invited" -msgstr "Ви маєте лист!" - -#, fuzzy +msgstr "Вас запросили" + 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 @@ "та є необхідним для передавання зображень. Так як ваша ІР адреса буде " "розкрита, це може вважатись загрозою безпеці." -#, fuzzy msgid "Invalid SNAC" -msgstr "Неправильний ID" +msgstr "Неправильний SNAC" msgid "Server rate limit exceeded" -msgstr "" +msgstr "Досягнуто обмеження швидкості сервера" msgid "Client rate limit exceeded" -msgstr "" - -#, fuzzy +msgstr "Досягнуто обмеження швидкості клієнта" + msgid "Service unavailable" -msgstr "Служба недоступна" - -#, fuzzy +msgstr "Послуга недоступна" + msgid "Service not defined" -msgstr "Конференція не знайдена" +msgstr "Послуга не визначена" msgid "Obsolete SNAC" -msgstr "" - -#, fuzzy +msgstr "Застарілий SNAC" + msgid "Not supported by host" -msgstr "Не підтримується" - -#, fuzzy +msgstr "Не підтримується вузлом" + msgid "Not supported by client" -msgstr "Не підтримується" +msgstr "Не підтримується клієнтом" msgid "Refused by client" -msgstr "" +msgstr "Відкинута клієнтом" msgid "Reply too big" -msgstr "" - -#, fuzzy +msgstr "Відповідь завелика" + msgid "Responses lost" -msgstr "Можливість відповіді:" - -#, fuzzy +msgstr "Відповіді втрачені" + 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 "" - -#, fuzzy +msgstr "Рівень попередження дуже високий (отримувач)" + msgid "User temporarily unavailable" -msgstr "Послуга тимчасово недоступна" - -#, fuzzy +msgstr "Користувач тимчасово недоступний" + 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 @@ "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 @@ 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 @@ "%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 @@ "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 @@ #, 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 @@ msgstr "" "Вихід, тому що вже запущений інший клієнт, який використовує libpurple.\n" -#, fuzzy msgid "_Media" -msgstr "/_Медіа" - -#, fuzzy +msgstr "_Медіа" + msgid "_Hangup" -msgstr "Завершити" +msgstr "_Завершити" #, c-format msgid "%s wishes to start an audio/video session with you." @@ -15291,7 +15269,7 @@ #. 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 @@ #, 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 @@ 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 "/Медіа/_Завершити"
--- a/po/ur.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/ur.po Sat Sep 11 19:03:25 2010 +0000 @@ -815,7 +815,7 @@ msgid "Waiting for transfer to begin" msgstr "ٹرانسفر ہونے کے لئے انتظار کررہا ہے" -msgid "Canceled" +msgid "Cancelled" msgstr " منسوخ کیا گیا" msgid "Failed" @@ -16800,7 +16800,7 @@ #~ 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."
--- a/po/vi.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/vi.po Sat Sep 11 19:03:25 2010 +0000 @@ -805,7 +805,7 @@ msgid "Waiting for transfer to begin" msgstr "Đợi bắt đầu truyền" -msgid "Canceled" +msgid "Cancelled" msgstr "Bị thôi" msgid "Failed"
--- a/po/xh.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/xh.po Sat Sep 11 19:03:25 2010 +0000 @@ -843,7 +843,7 @@ msgid "Waiting for transfer to begin" msgstr "Ulindele ukuba ukudlulisa kuqalise" -msgid "Canceled" +msgid "Cancelled" msgstr "IRhoxisiwe" msgid "Failed" @@ -17192,7 +17192,7 @@ #~ 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."
--- a/po/zh_CN.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/zh_CN.po Sat Sep 11 19:03:25 2010 +0000 @@ -777,7 +777,7 @@ msgid "Waiting for transfer to begin" msgstr "正在等待传送开始" -msgid "Canceled" +msgid "Cancelled" msgstr "已取消" msgid "Failed" @@ -15530,7 +15530,7 @@ #~ 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."
--- a/po/zh_HK.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/zh_HK.po Sat Sep 11 19:03:25 2010 +0000 @@ -868,7 +868,7 @@ msgid "Waiting for transfer to begin" msgstr "等待開始傳輸檔案中..." -msgid "Canceled" +msgid "Cancelled" msgstr "已取消" msgid "Failed"
--- a/po/zh_TW.po Sun Aug 01 00:08:26 2010 +0000 +++ b/po/zh_TW.po Sat Sep 11 19:03:25 2010 +0000 @@ -866,7 +866,7 @@ msgid "Waiting for transfer to begin" msgstr "等待開始傳輸檔案中..." -msgid "Canceled" +msgid "Cancelled" msgstr "已取消" msgid "Failed"
--- a/share/ca-certs/Makefile.am Sun Aug 01 00:08:26 2010 +0000 +++ b/share/ca-certs/Makefile.am Sat Sep 11 19:03:25 2010 +0000 @@ -9,6 +9,7 @@ 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 \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/ca-certs/ValiCert_Class_2_VA.pem Sat Sep 11 19:03:25 2010 +0000 @@ -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-----