Mercurial > pidgin
diff src/protocols/msn/switchboard.c @ 10225:ecf3ce2e2ab1
[gaim-migrate @ 11357]
This is mostly a patch from Felipe Contreras that eliminates MSN switchboard
errors and fixes MSN buddy icon syncronization, with some tweaks by me.
Thank Felipe if it works, blame me if something broke.
I also fixed a couple of text markup escaping things, fixed a glib warning that
was bugging me, fix a rare SILC crash, and make gtkstatusselector.c compile
(but do nothing) with gtk < 2.4
committer: Tailor Script <tailor@pidgin.im>
| author | Stu Tomlinson <stu@nosnilmot.com> |
|---|---|
| date | Sun, 21 Nov 2004 17:48:09 +0000 |
| parents | 1a91e814e9d8 |
| children | a66cf83552dc |
line wrap: on
line diff
--- a/src/protocols/msn/switchboard.c Sun Nov 21 06:16:23 2004 +0000 +++ b/src/protocols/msn/switchboard.c Sun Nov 21 17:48:09 2004 +0000 @@ -31,6 +31,8 @@ static MsnTable *cbs_table; +static void cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error); + /************************************************************************** * Utility functions **************************************************************************/ @@ -39,7 +41,7 @@ { MsnMessage *msg; - msg = msn_message_new(); + msg = msn_message_new(MSN_MSG_CAPS); msn_message_set_content_type(msg, "text/x-clientcaps"); msn_message_set_flag(msg, 'U'); msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO)); @@ -135,14 +137,41 @@ swboard->ready = TRUE; } +GaimConversation * +msn_switchboard_get_conv(MsnSwitchBoard *swboard) +{ + GaimAccount *account; + + g_return_val_if_fail(swboard != NULL, NULL); + + if (swboard->conv != NULL) + return swboard->conv; + + account = swboard->session->account; + + return gaim_find_conversation_with_account(swboard->im_user, account); +} + +void +msn_switchboard_report_user(MsnSwitchBoard *swboard, GaimMessageFlags flags, const char *msg) +{ + GaimConversation *conv; + + g_return_if_fail(swboard != NULL); + g_return_if_fail(msg != NULL); + + if ((conv = msn_switchboard_get_conv(swboard)) != NULL) + { + gaim_conversation_write(conv, NULL, msg, flags, time(NULL)); + } +} + static void bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { - GaimAccount *account; MsnSwitchBoard *swboard; const char *user; - account = cmdproc->session->account; swboard = cmdproc->servconn->data; user = cmd->params[0]; @@ -155,16 +184,8 @@ } else { - char *username; - GaimConversation *conv; - GaimBuddy *b; char *str = NULL; - if ((b = gaim_find_buddy(account, user)) != NULL) - username = gaim_escape_html(gaim_buddy_get_alias(b)); - else - username = gaim_escape_html(user); - if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1) { if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice")) @@ -177,22 +198,28 @@ { if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_close_notice")) { + char *username; + GaimAccount *account; + GaimBuddy *b; + + account = cmdproc->session->account; + + if ((b = gaim_find_buddy(account, user)) != NULL) + username = gaim_escape_html(gaim_buddy_get_alias(b)); + else + username = gaim_escape_html(user); + str = g_strdup_printf(_("%s has closed the conversation " "window."), username); + + g_free(username); } } - if (str != NULL && - (conv = gaim_find_conversation_with_account(user, account)) != NULL) - { - gaim_conversation_write(conv, NULL, str, GAIM_MESSAGE_SYSTEM, - time(NULL)); - - g_free(str); - } + if (str != NULL) + msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str); msn_switchboard_disconnect(swboard); - g_free(username); } } @@ -433,6 +460,71 @@ #endif } +static void +msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg) +{ + if (msg->type == MSN_MSG_TEXT) + { + MsnSwitchBoard *swboard; + char *body; + char *report; + char *str_reason; + + swboard = cmdproc->servconn->data; + + switch (swboard->error) + { + case MSN_SB_ERROR_OFFLINE: + str_reason = _("Message could not be sent, not allowed while invisible"); + break; + case MSN_SB_ERROR_USER_OFFLINE: + str_reason = _("Message could not be sent because the user is offline"); + break; + case MSN_SB_ERROR_CONNECTION: + str_reason = _("Message could not be sent because a connection error occured"); + break; + default: + str_reason = _("Message could not be sent for an unkwnown reason"); + break; + } + + body = msn_message_to_string(msg); + report = g_strdup_printf(_("%s:\n%s"), str_reason, body); + gaim_debug_info("msn", "%s\n", report); + msn_switchboard_report_user(cmdproc->servconn->data, GAIM_MESSAGE_ERROR, report); + g_free(report); + g_free(body); + } +} + +static void +msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) +{ + MsnMessage *msg; + + msg = trans->data; + g_return_if_fail(msg != NULL); + + gaim_debug_info("msn", "msg_timeout\n"); + msg_error_helper(cmdproc, msg); +} + +static void +msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) +{ + msg_error_helper(cmdproc, trans->data); +} + +static void +msg_ack (MsnCmdProc *cmdproc, MsnCommand *cmd) +{ + MsnMessage *msg; + + msg = cmd->trans->data; + + msg->ack_cb (msg->ack_data); +} + void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) { @@ -450,11 +542,19 @@ /* msn_message_show_readable(msg, "SB SEND", FALSE); */ - trans = msn_transaction_new("MSG", "%c %d", msn_message_get_flag(msg), - payload_len); + trans = msn_transaction_new(cmdproc, "MSG", "%c %d", + msn_message_get_flag(msg), payload_len); + + /* Data for callbacks */ + msn_transaction_set_data(trans, msg); if (msg->ack_cb != NULL) - msn_transaction_add_cb(trans, "ACK", msg->ack_cb, msg->ack_data); + { + msn_transaction_add_cb(trans, "ACK", msg_ack); + msn_transaction_set_timeout_cb(trans, msg_timeout); + } + else if (msg->type == MSN_MSG_TEXT) + msn_transaction_set_timeout_cb(trans, msg_timeout); trans->payload = payload; trans->payload_len = payload_len; @@ -563,7 +663,8 @@ msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); #endif - msn_table_add_error(cbs_table, "MSG", NULL); + msn_table_add_error(cbs_table, "MSG", msg_error); + msn_table_add_error(cbs_table, "CAL", cal_error); /* Register the message type callbacks. */ msn_table_add_msg_type(cbs_table, "text/plain", @@ -637,6 +738,19 @@ swboard->destroying = TRUE; + /* Destroy the message queue */ + while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) + { + if (swboard->error > 0) + { + /* The messages could not be sent due to an error */ + msg_error_helper(swboard->servconn->cmdproc, msg); + } + msn_message_destroy(msg); + } + + g_queue_free(swboard->im_queue); + if (swboard->im_user != NULL) g_free(swboard->im_user); @@ -655,36 +769,10 @@ if (swboard->servconn != NULL) msn_servconn_destroy(swboard->servconn); - while ((msg = g_queue_pop_head(swboard->im_queue)) != NULL) - msn_message_destroy(msg); - - g_queue_free(swboard->im_queue); - g_free(swboard); } #if 0 -void -msn_switchboard_set_user(MsnSwitchBoard *swboard, const char *user) -{ - g_return_if_fail(swboard != NULL); - - if (swboard->user != NULL) - g_free(swboard->user); - - swboard->user = g_strdup(user); -} - -const char * -msn_switchboard_get_user(MsnSwitchBoard *swboard) -{ - g_return_val_if_fail(swboard != NULL, NULL); - - return swboard->user; -} -#endif - -#if 0 static void got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -699,6 +787,53 @@ } #endif +static void +swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) +{ + gaim_debug_info("msg", "Error: Unable to call the user %s\n", passport); + + if (swboard->total_users == 0) + { + swboard->error = reason; + msn_switchboard_destroy(swboard); + } +} + +static void +cal_error_helper(MsnTransaction *trans, int reason) +{ + MsnSwitchBoard *swboard; + const char *passport; + char **params; + + params = g_strsplit(trans->params, " ", 0); + + passport = params[0]; + + swboard = trans->data; + + swboard_error_helper(swboard, reason, passport); + + g_strfreev(params); +} + +static void +cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) +{ + cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); +} + +static void +cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) +{ + int reason = MSN_SB_ERROR_UNKNOWN; + + if (error == 217) + reason = MSN_SB_ERROR_USER_OFFLINE; + + cal_error_helper(trans, reason); +} + void msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) { @@ -709,8 +844,11 @@ cmdproc = swboard->servconn->cmdproc; - trans = msn_transaction_new("CAL", "%s", user); - /* msn_transaction_add_cb(trans, "CAL", got_cal, NULL); */ + trans = msn_transaction_new(cmdproc, "CAL", "%s", user); + /* msn_transaction_add_cb(trans, "CAL", got_cal); */ + + msn_transaction_set_data(trans, swboard); + msn_transaction_set_timeout_cb(trans, cal_timeout); if (swboard->ready) msn_cmdproc_send_trans(cmdproc, trans); @@ -839,6 +977,20 @@ g_free(host); } +static void +xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) +{ + MsnSwitchBoard *swboard; + int reason = MSN_SB_ERROR_UNKNOWN; + + if (error == 913) + reason = MSN_SB_ERROR_OFFLINE; + + swboard = trans->data; + + swboard_error_helper(swboard, reason, swboard->im_user); +} + void msn_switchboard_request(MsnSwitchBoard *swboard) { @@ -849,8 +1001,10 @@ cmdproc = swboard->session->notification->cmdproc; - trans = msn_transaction_new("XFR", "%s", "SB"); - msn_transaction_add_cb(trans, "XFR", got_swboard, swboard); + trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); + msn_transaction_add_cb(trans, "XFR", got_swboard); + msn_transaction_set_data(trans, swboard); + msn_transaction_set_error_cb(trans, xfr_error); msn_cmdproc_send_trans(cmdproc, trans); }
