summaryrefslogtreecommitdiff
path: root/libpurple/protocols/msn/switchboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpurple/protocols/msn/switchboard.c')
-rw-r--r--libpurple/protocols/msn/switchboard.c214
1 files changed, 69 insertions, 145 deletions
diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c
index 827a03709b..f875a35ecf 100644
--- a/libpurple/protocols/msn/switchboard.c
+++ b/libpurple/protocols/msn/switchboard.c
@@ -21,18 +21,18 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
-#include "msn.h"
-#include "prefs.h"
-#include "switchboard.h"
-#include "notification.h"
-#include "msnutils.h"
-#include "error.h"
+#include "internal.h"
+#include "debug.h"
-static MsnTable *cbs_table;
+#include "msnutils.h"
+#include "switchboard.h"
+#include "sbconn.h"
+#include "slplink.h"
+#include "user.h"
+#include "userlist.h"
-static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg,
- MsnMsgErrorType error);
+static MsnTable *cbs_table;
/**************************************************************************
* Main
@@ -90,9 +90,11 @@ msn_switchboard_destroy(MsnSwitchBoard *swboard)
while (swboard->slplinks != NULL) {
MsnSlpLink *slplink = swboard->slplinks->data;
+ swboard->slplinks = g_list_remove(swboard->slplinks, slplink);
+
/* Destroy only those slplinks which use the switchboard */
if (slplink->dc == NULL)
- msn_slplink_destroy(slplink);
+ msn_slplink_unref(slplink);
else {
swboard->slplinks = g_list_remove(swboard->slplinks, slplink);
slplink->swboard = NULL;
@@ -123,7 +125,7 @@ msn_switchboard_destroy(MsnSwitchBoard *swboard)
g_free(swboard->session_id);
for (; swboard->users; swboard->users = g_list_delete_link(swboard->users, swboard->users))
- g_free(swboard->users->data);
+ msn_user_unref(swboard->users->data);
session = swboard->session;
session->switches = g_list_remove(session->switches, swboard);
@@ -231,6 +233,8 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
{
MsnCmdProc *cmdproc;
PurpleAccount *account;
+ MsnUserList *userlist;
+ MsnUser *msnuser;
char *semicolon;
char *passport;
@@ -246,13 +250,36 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
else
passport = g_strdup(user);
+ userlist = swboard->session->userlist;
+ msnuser = msn_userlist_find_user(userlist, passport);
+
/* Don't add multiple endpoints to the conversation. */
- if (g_list_find_custom(swboard->users, passport, (GCompareFunc)strcmp)) {
+ if (g_list_find_custom(swboard->users, passport, (GCompareFunc)msn_user_passport_cmp)) {
+ g_free(passport);
+ return;
+ }
+
+ /* Don't add ourselves either... */
+ if (g_str_equal(passport, purple_account_get_username(account))) {
g_free(passport);
return;
}
- swboard->users = g_list_prepend(swboard->users, passport);
+ /* Don't add ourselves either... */
+ if (g_str_equal(passport, purple_account_get_username(account))) {
+ g_free(passport);
+ return;
+ }
+
+ if (!msnuser) {
+ purple_debug_info("msn","User %s is not on our list.\n", passport);
+ msnuser = msn_user_new(userlist, passport, NULL);
+ } else
+ msn_user_ref(msnuser);
+
+ g_free(passport);
+
+ swboard->users = g_list_prepend(swboard->users, msnuser);
swboard->current_users++;
swboard->empty = FALSE;
@@ -270,11 +297,11 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
if ((swboard->conv != NULL) &&
(purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
{
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL,
+ purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), msnuser->passport, NULL,
PURPLE_CBFLAGS_NONE, TRUE);
msn_servconn_set_idle_timeout(swboard->servconn, 0);
}
- else if (swboard->current_users > 1 || swboard->total_users > 1)
+ else if (swboard->current_users > 1)
{
msn_servconn_set_idle_timeout(swboard->servconn, 0);
if (swboard->conv == NULL ||
@@ -299,7 +326,7 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
{
const char *tmp_user;
- tmp_user = l->data;
+ tmp_user = ((MsnUser*)l->data)->passport;
purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);
@@ -316,7 +343,7 @@ msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
else if (swboard->conv == NULL)
{
swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- user, account);
+ msnuser->passport, account);
}
else
{
@@ -406,7 +433,7 @@ msg_resend_cb(gpointer data)
return FALSE;
}
-static void
+void
msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error)
{
MsnSwitchBoard *swboard;
@@ -514,7 +541,7 @@ msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error)
body_enc = g_markup_escape_text(body_str, -1);
g_free(body_str);
- format = msn_message_get_attr(msg, "X-MMS-IM-Format");
+ format = msn_message_get_header_value(msg, "X-MMS-IM-Format");
msn_parse_format(format, &pre, &post);
body_str = g_strdup_printf("%s%s%s", pre ? pre : "",
body_enc ? body_enc : "", post ? post : "");
@@ -543,17 +570,6 @@ msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error)
* Message Stuff
**************************************************************************/
-/** Called when a message times out. */
-static void
-msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- MsnMessage *msg;
-
- msg = trans->data;
-
- msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT);
-}
-
/** Called when we receive an error of a message. */
static void
msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
@@ -588,96 +604,6 @@ msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd)
}
#endif
-static void
-release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
-{
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
- char *payload;
- gsize payload_len;
- char flag;
-
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- cmdproc = swboard->cmdproc;
-
- payload = msn_message_gen_payload(msg, &payload_len);
-
- if (purple_debug_is_verbose()) {
- purple_debug_info("msn", "SB length:{%" G_GSIZE_FORMAT "}\n", payload_len);
- msn_message_show_readable(msg, "SB SEND", FALSE);
- }
-
- flag = msn_message_get_flag(msg);
- trans = msn_transaction_new(cmdproc, "MSG", "%c %" G_GSIZE_FORMAT,
- flag, payload_len);
-
- /* Data for callbacks */
- msn_transaction_set_data(trans, msg);
-
- if (flag != 'U') {
- if (msg->type == MSN_MSG_TEXT)
- {
- msg->ack_ref = TRUE;
- msn_message_ref(msg);
- swboard->ack_list = g_list_append(swboard->ack_list, msg);
- msn_transaction_set_timeout_cb(trans, msg_timeout);
- }
- else if (msg->type == MSN_MSG_SLP)
- {
- msg->ack_ref = TRUE;
- msn_message_ref(msg);
- swboard->ack_list = g_list_append(swboard->ack_list, msg);
- msn_transaction_set_timeout_cb(trans, msg_timeout);
-#if 0
- if (msg->ack_cb != NULL)
- {
- msn_transaction_add_cb(trans, "ACK", msg_ack);
- msn_transaction_add_cb(trans, "NAK", msg_nak);
- }
-#endif
- }
- }
-
- trans->payload = payload;
- trans->payload_len = payload_len;
-
- msg->trans = trans;
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- purple_debug_info("msn", "Appending message to queue.\n");
-
- g_queue_push_tail(swboard->msg_queue, msg);
-
- msn_message_ref(msg);
-}
-
-static void
-process_queue(MsnSwitchBoard *swboard)
-{
- MsnMessage *msg;
-
- g_return_if_fail(swboard != NULL);
-
- purple_debug_info("msn", "Processing queue\n");
-
- while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)
- {
- purple_debug_info("msn", "Sending message\n");
- release_msg(swboard, msg);
- msn_message_unref(msg);
- }
-}
-
gboolean
msn_switchboard_can_send(MsnSwitchBoard *swboard)
{
@@ -689,20 +615,6 @@ msn_switchboard_can_send(MsnSwitchBoard *swboard)
return TRUE;
}
-void
-msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
- gboolean queue)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- purple_debug_info("msn", "switchboard send msg..\n");
- if (msn_switchboard_can_send(swboard))
- release_msg(swboard, msg);
- else if (queue)
- queue_msg(swboard, msg);
-}
-
/**************************************************************************
* Switchboard Commands
**************************************************************************/
@@ -745,7 +657,10 @@ bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);
passport = g_list_find_custom(swboard->users, user, (GCompareFunc)strcmp);
- g_free(passport->data);
+ if (passport)
+ g_free(passport->data);
+ else
+ purple_debug_warning("msn", "Can't find user %s in the switchboard\n", user);
swboard->users = g_list_delete_link(swboard->users, passport);
swboard->current_users--;
if (swboard->current_users == 0)
@@ -762,11 +677,9 @@ static void
iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
PurpleAccount *account;
- PurpleConnection *gc;
MsnSwitchBoard *swboard;
account = cmdproc->session->account;
- gc = account->gc;
swboard = cmdproc->data;
swboard->total_users = atoi(cmd->params[2]);
@@ -779,7 +692,6 @@ joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
MsnSession *session;
PurpleAccount *account;
- PurpleConnection *gc;
MsnSwitchBoard *swboard;
const char *passport;
@@ -787,12 +699,11 @@ joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
session = cmdproc->session;
account = session->account;
- gc = account->gc;
swboard = cmdproc->data;
msn_switchboard_add_user(swboard, passport);
- process_queue(swboard);
+ msn_sbconn_process_queue(swboard);
if (!session->http_method)
send_clientcaps(swboard);
@@ -855,8 +766,8 @@ ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
msg = cmd->trans->data;
- if (msg->ack_cb != NULL)
- msg->ack_cb(msg, msg->ack_data);
+ if (msg->part && msg->part->ack_cb != NULL)
+ msg->part->ack_cb(msg->part, msg->part->ack_data);
swboard = cmdproc->data;
if (swboard)
@@ -978,6 +889,7 @@ connect_cb(MsnServConn *servconn)
MsnTransaction *trans;
MsnCmdProc *cmdproc;
PurpleAccount *account;
+ char *username;
cmdproc = servconn->cmdproc;
g_return_if_fail(cmdproc != NULL);
@@ -986,24 +898,33 @@ connect_cb(MsnServConn *servconn)
swboard = cmdproc->data;
g_return_if_fail(swboard != NULL);
+ if (servconn->session->protocol_ver >= 16)
+ username = g_strdup_printf("%s;{%s}",
+ purple_account_get_username(account),
+ servconn->session->guid);
+ else
+ username = g_strdup(purple_account_get_username(account));
+
if (msn_switchboard_is_invited(swboard))
{
swboard->empty = FALSE;
trans = msn_transaction_new(cmdproc, "ANS", "%s %s %s",
- purple_account_get_username(account),
+ username,
swboard->auth_key, swboard->session_id);
}
else
{
trans = msn_transaction_new(cmdproc, "USR", "%s %s",
- purple_account_get_username(account),
+ username,
swboard->auth_key);
}
msn_transaction_set_error_cb(trans, ans_usr_error);
msn_transaction_set_data(trans, swboard);
msn_cmdproc_send_trans(cmdproc, trans);
+
+ g_free(username);
}
static void
@@ -1221,8 +1142,11 @@ msn_switchboard_close(MsnSwitchBoard *swboard)
!swboard->session->connected)
{
MsnCmdProc *cmdproc;
+ MsnTransaction *trans;
cmdproc = swboard->cmdproc;
- msn_cmdproc_send_quick(cmdproc, "OUT", NULL, NULL);
+ trans = msn_transaction_new(cmdproc, "OUT", NULL);
+ msn_transaction_set_saveable(trans, FALSE);
+ msn_cmdproc_send_trans(cmdproc, trans);
msn_switchboard_destroy(swboard);
}