# HG changeset patch
# User andrew.victor@mxit.com
# Date 1282293327 0
# Node ID 581a070c37371d2dde5b080c91275de1ded9066b
# Parent 69760676c50cf2c97f5284fc3962dd00cc3b831f# Parent 9789e8e7d83411b3051400eec415452d73444db7
propagate from branch 'im.pidgin.pidgin' (head 47179f04bde4a1cd3857fd05eb4e40f25ee9e26f)
to branch 'im.pidgin.pidgin.mxit' (head 2b62fc7e560dfcd0decc64eff067becbb581c423)
diff -r 69760676c50c -r 581a070c3737 finch/libgnt/gntentry.c
--- a/finch/libgnt/gntentry.c Fri Aug 20 08:34:12 2010 +0000
+++ b/finch/libgnt/gntentry.c Fri Aug 20 08:35:27 2010 +0000
@@ -480,7 +480,7 @@
{
GntEntry *entry = GNT_ENTRY(bind);
GList *iter;
- const char *current , *pos;
+ const char *current;
int len;
if (entry->history->prev && entry->search->needle)
@@ -497,7 +497,7 @@
const char *str = iter->data;
/* A more utf8-friendly version of strstr would have been better, but
* for now, this will have to do. */
- if ((pos = strstr(str, current)))
+ if (strstr(str, current) != NULL)
break;
}
diff -r 69760676c50c -r 581a070c3737 finch/libgnt/gnttextview.c
--- a/finch/libgnt/gnttextview.c Fri Aug 20 08:34:12 2010 +0000
+++ b/finch/libgnt/gnttextview.c Fri Aug 20 08:35:27 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;
diff -r 69760676c50c -r 581a070c3737 libpurple/log.c
--- a/libpurple/log.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/log.c Fri Aug 20 08:35:27 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];
diff -r 69760676c50c -r 581a070c3737 libpurple/media/backend-fs2.c
--- a/libpurple/media/backend-fs2.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/media/backend-fs2.c Fri Aug 20 08:35:27 2010 +0000
@@ -1791,7 +1791,7 @@
const gchar *sess_id)
{
PurpleMediaBackendFs2Private *priv;
- gboolean ret;
+ gboolean ret = FALSE;
g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE);
diff -r 69760676c50c -r 581a070c3737 libpurple/plugins/tcl/tcl_cmd.c
--- a/libpurple/plugins/tcl/tcl_cmd.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/plugins/tcl/tcl_cmd.c Fri Aug 20 08:35:27 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",
diff -r 69760676c50c -r 581a070c3737 libpurple/plugins/tcl/tcl_signals.c
--- a/libpurple/plugins/tcl/tcl_signals.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/plugins/tcl/tcl_signals.c Fri Aug 20 08:35:27 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;
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/bonjour/jabber.c
--- a/libpurple/protocols/bonjour/jabber.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/bonjour/jabber.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/bonjour/mdns_avahi.c
--- a/libpurple/protocols/bonjour/mdns_avahi.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c Fri Aug 20 08:35:27 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
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/auth_cyrus.c
--- a/libpurple/protocols/jabber/auth_cyrus.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/auth_cyrus.c Fri Aug 20 08:35:27 2010 +0000
@@ -103,6 +103,7 @@
return SASL_BADPARAM;
len = strlen(pw);
+ /* Not an off-by-one because sasl_secret_t defines char data[1] */
x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);
if (!x)
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/bosh.c
--- a/libpurple/protocols/jabber/bosh.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/bosh.c Fri Aug 20 08:35:27 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.
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/disco.c
--- a/libpurple/protocols/jabber/disco.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/disco.c Fri Aug 20 08:35:27 2010 +0000
@@ -604,7 +604,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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.c Fri Aug 20 08:35:27 2010 +0000
@@ -205,7 +205,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);
}
@@ -3493,7 +3493,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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/message.c Fri Aug 20 08:35:27 2010 +0000
@@ -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 */
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/jabber/si.c
--- a/libpurple/protocols/jabber/si.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/jabber/si.c Fri Aug 20 08:35:27 2010 +0000
@@ -1734,7 +1734,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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/msn/contact.c
--- a/libpurple/protocols/msn/contact.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/msn/contact.c Fri Aug 20 08:35:27 2010 +0000
@@ -536,7 +536,7 @@
abLastChange = purple_account_get_string(session->account,
"ablastChange", NULL);
dynamicItemLastChange = purple_account_get_string(session->account,
- "dynamicItemLastChange", NULL);
+ "DynamicItemLastChanged", NULL);
if (state->partner_scenario == MSN_PS_INITIAL) {
#ifdef MSN_PARTIAL_LISTS
@@ -684,20 +684,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 +836,7 @@
g_free(uid);
g_free(type);
g_free(mobile_number);
+ g_free(alias);
}
static gboolean
@@ -885,7 +886,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 +896,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) {
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/Makefile.am
--- a/libpurple/protocols/oscar/Makefile.am Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/Makefile.am Fri Aug 20 08:35:27 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)
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/Makefile.mingw
--- a/libpurple/protocols/oscar/Makefile.mingw Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/Makefile.mingw Fri Aug 20 08:35:27 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)
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/authorization.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/authorization.c Fri Aug 20 08:35:27 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
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/bstream.c
--- a/libpurple/protocols/oscar/bstream.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/bstream.c Fri Aug 20 08:35:27 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;
}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/encoding.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/encoding.c Fri Aug 20 08:35:27 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);
+}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/encoding.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/oscar/encoding.h Fri Aug 20 08:35:27 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
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_admin.c
--- a/libpurple/protocols/oscar/family_admin.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_admin.c Fri Aug 20 08:35:27 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);
}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_advert.c
--- a/libpurple/protocols/oscar/family_advert.c Fri Aug 20 08:34:12 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;
-}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_alert.c
--- a/libpurple/protocols/oscar/family_alert.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_alert.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_auth.c
--- a/libpurple/protocols/oscar/family_auth.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_auth.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_bart.c
--- a/libpurple/protocols/oscar/family_bart.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_bart.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_bos.c
--- a/libpurple/protocols/oscar/family_bos.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_bos.c Fri Aug 20 08:35:27 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)
{
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_buddy.c
--- a/libpurple/protocols/oscar/family_buddy.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_buddy.c Fri Aug 20 08:35:27 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
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_chat.c
--- a/libpurple/protocols/oscar/family_chat.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_chat.c Fri Aug 20 08:35:27 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.
*/
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_chatnav.c
--- a/libpurple/protocols/oscar/family_chatnav.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_chatnav.c Fri Aug 20 08:35:27 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);
}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_feedbag.c
--- a/libpurple/protocols/oscar/family_feedbag.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c Fri Aug 20 08:35:27 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)
{
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_icbm.c
--- a/libpurple/protocols/oscar/family_icbm.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c Fri Aug 20 08:35:27 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
@@ -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)
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_icq.c
--- a/libpurple/protocols/oscar/family_icq.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_icq.c Fri Aug 20 08:35:27 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
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_invite.c
--- a/libpurple/protocols/oscar/family_invite.c Fri Aug 20 08:34:12 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;
-}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_locate.c
--- a/libpurple/protocols/oscar/family_locate.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_locate.c Fri Aug 20 08:35:27 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)
{
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_odir.c
--- a/libpurple/protocols/oscar/family_odir.c Fri Aug 20 08:34:12 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;
-}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_oservice.c
--- a/libpurple/protocols/oscar/family_oservice.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_oservice.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_translate.c
--- a/libpurple/protocols/oscar/family_translate.c Fri Aug 20 08:34:12 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;
-}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/family_userlookup.c
--- a/libpurple/protocols/oscar/family_userlookup.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/family_userlookup.c Fri Aug 20 08:35:27 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);
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/flap_connection.c
--- a/libpurple/protocols/oscar/flap_connection.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c Fri Aug 20 08:35:27 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;
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/libaim.c
--- a/libpurple/protocols/oscar/libaim.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/libaim.c Fri Aug 20 08:35:27 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 */
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/libicq.c
--- a/libpurple/protocols/oscar/libicq.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/libicq.c Fri Aug 20 08:35:27 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 */
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/misc.c
--- a/libpurple/protocols/oscar/misc.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/misc.c Fri Aug 20 08:35:27 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)))
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/msgcookie.c
--- a/libpurple/protocols/oscar/msgcookie.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/msgcookie.c Fri Aug 20 08:35:27 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;
- }
-}
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/odc.c
--- a/libpurple/protocols/oscar/odc.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/odc.c Fri Aug 20 08:35:27 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)
diff -r 69760676c50c -r 581a070c3737 libpurple/protocols/oscar/oscar.c
--- a/libpurple/protocols/oscar/oscar.c Fri Aug 20 08:34:12 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c Fri Aug 20 08:35:27 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("%s",
- 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)
{
@@ -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", "
");
+ 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;
@@ -3376,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("%s",
- 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;
@@ -3617,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);
@@ -3631,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);
@@ -3656,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;
@@ -3675,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);
@@ -3796,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;
@@ -3851,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;
}
@@ -3993,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));
@@ -4034,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("%s", 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("%s", 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("%s", 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("%s", 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;
@@ -4458,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;
@@ -4520,8 +3132,7 @@
g_string_append(msg, "