--- a/libpurple/protocols/msn/notification.c Sat Jun 20 00:35:12 2009 +0000 +++ b/libpurple/protocols/msn/notification.c Sat Jun 20 18:27:49 2009 +0000 @@ -149,48 +149,6 @@ } /************************************************************************** - * Util - **************************************************************************/ - -static void -group_error_helper(MsnSession *session, const char *msg, const char *group_id, int error) -{ - PurpleAccount *account; - PurpleConnection *gc; - char *reason = NULL; - char *title = NULL; - - account = session->account; - gc = purple_account_get_connection(account); - - if (error == 224) - { - if (group_id == 0) - { - return; - } - else - { - const char *group_name; - group_name = msn_userlist_find_group_name(session->userlist,group_id); - reason = g_strdup_printf(_("%s is not a valid group."), - group_name ? group_name : ""); - } - } - else - { - reason = g_strdup(_("Unknown error.")); - } - - title = g_strdup_printf(_("%s on %s (%s)"), msg, - purple_account_get_username(account), - purple_account_get_protocol_name(account)); - purple_notify_error(gc, NULL, title, reason); - g_free(title); - g_free(reason); -} - -/************************************************************************** * Login **************************************************************************/ @@ -521,6 +479,12 @@ /************************************************************************** * Buddy Lists **************************************************************************/ + +typedef struct MsnFqyCbData { + MsnFqyCb cb; + gpointer data; +} MsnFqyCbData; + /* add contact to xmlnode */ static void msn_add_contact_xml(MsnSession *session, xmlnode *mlNode,const char *passport, MsnListOp list_op, MsnNetwork networkId) @@ -593,24 +557,40 @@ msn_cmdproc_send_trans(cmdproc, trans); } +static void +msn_notification_post_rml(MsnCmdProc *cmdproc, const char *payload, int payload_len) +{ + MsnTransaction *trans; + purple_debug_info("msn", "Sending RML with payload: %s\n", payload); + trans = msn_transaction_new(cmdproc, "RML", "%i", payload_len); + msn_transaction_set_payload(trans, payload, payload_len); + msn_cmdproc_send_trans(cmdproc, trans); +} + void msn_notification_send_fqy(MsnSession *session, const char *payload, int payload_len, - MsnFqyCb cb) + MsnFqyCb cb, + gpointer cb_data) { MsnTransaction *trans; MsnCmdProc *cmdproc; + MsnFqyCbData *data; cmdproc = session->notification->cmdproc; + data = g_new(MsnFqyCbData, 1); + data->cb = cb; + data->data = cb_data; + trans = msn_transaction_new(cmdproc, "FQY", "%d", payload_len); msn_transaction_set_payload(trans, payload, payload_len); - msn_transaction_set_data(trans, cb); + msn_transaction_set_data(trans, data); msn_cmdproc_send_trans(cmdproc, trans); } static void -update_contact_network(MsnSession *session, const char *passport, MsnNetwork network) +update_contact_network(MsnSession *session, const char *passport, MsnNetwork network, gpointer unused) { MsnUser *user; @@ -726,7 +706,7 @@ payload = xmlnode_to_str(fqy_node, &payload_len); msn_notification_send_fqy(session, payload, payload_len, - update_contact_network); + update_contact_network, NULL); g_free(payload); xmlnode_free(fqy_node); @@ -751,7 +731,7 @@ payload = xmlnode_to_str(fqy_node, &payload_len); msn_notification_send_fqy(session, payload, payload_len, - update_contact_network); + update_contact_network, NULL); g_free(payload); } @@ -961,15 +941,20 @@ passport = g_strdup_printf("%s@%s", local, domain); - if (!g_ascii_isdigit(cmd->command[0]) && type != NULL) + if (g_ascii_isdigit(cmd->command[0])) + network = MSN_NETWORK_UNKNOWN; + else if (type != NULL) network = (MsnNetwork)strtoul(type, NULL, 10); - else - network = MSN_NETWORK_UNKNOWN; purple_debug_info("msn", "FQY response says %s is from network %d\n", passport, network); - if (cmd->trans->data) - ((MsnFqyCb)cmd->trans->data)(session, passport, network); + if (cmd->trans->data) { + MsnFqyCbData *fqy_data = cmd->trans->data; + fqy_data->cb(session, passport, network, fqy_data->data); + /* TODO: This leaks, but the server responds to FQY multiple times, so we + can't free it yet. We need to figure out somewhere else to do so. + g_free(fqy_data); */ + } g_free(passport); } @@ -994,7 +979,7 @@ FQY error, it's probably going to disconnect us. So it isn't necessary to tell the handler about it. */ else if (trans->data) - ((MsnFqyCb)trans->data)(session, NULL, MSN_NETWORK_UNKNOWN); */ + ((MsnFqyCb)trans->data)(session, NULL, MSN_NETWORK_UNKNOWN, NULL); #endif } @@ -1023,117 +1008,6 @@ } static void -add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) -{ - MsnSession *session; - PurpleAccount *account; - PurpleConnection *gc; - const char *list, *passport; - char *reason = NULL; - char *msg = NULL; - char **params; - - session = cmdproc->session; - account = session->account; - gc = purple_account_get_connection(account); - params = g_strsplit(trans->params, " ", 0); - - list = params[0]; - passport = params[1]; - - if (!strcmp(list, "FL")) - msg = g_strdup_printf(_("Unable to add user on %s (%s)"), - purple_account_get_username(account), - purple_account_get_protocol_name(account)); - else if (!strcmp(list, "BL")) - msg = g_strdup_printf(_("Unable to block user on %s (%s)"), - purple_account_get_username(account), - purple_account_get_protocol_name(account)); - else if (!strcmp(list, "AL")) - msg = g_strdup_printf(_("Unable to permit user on %s (%s)"), - purple_account_get_username(account), - purple_account_get_protocol_name(account)); - - if (!strcmp(list, "FL")) - { - if (error == 210) - { - reason = g_strdup_printf(_("%s could not be added because " - "your buddy list is full."), passport); - } - } - - if (reason == NULL) - { - if (error == 208) - { - reason = g_strdup_printf(_("%s is not a valid passport account."), - passport); - } - else if (error == 500) - { - reason = g_strdup(_("Service Temporarily Unavailable.")); - } - else - { - reason = g_strdup(_("Unknown error.")); - } - } - - if (msg != NULL) - { - purple_notify_error(gc, NULL, msg, reason); - g_free(msg); - } - - if (!strcmp(list, "FL")) - { - PurpleBuddy *buddy; - - buddy = purple_find_buddy(account, passport); - - if (buddy != NULL) - purple_blist_remove_buddy(buddy); - } - - g_free(reason); - - g_strfreev(params); -} - -static void -adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) -{ - MsnSession *session; - gint group_id; - const char *group_name; - - session = cmdproc->session; - - group_id = atoi(cmd->params[3]); - - group_name = purple_url_decode(cmd->params[2]); - - msn_group_new(session->userlist, cmd->params[3], group_name); - - /* There is a user that must be moved to this group */ - if (cmd->trans->data) - { - /* msn_userlist_move_buddy(); */ - MsnUserList *userlist = cmdproc->session->userlist; - MsnCallbackState *data = cmd->trans->data; - - if (data->old_group_name != NULL) - { - msn_userlist_move_buddy(userlist, data->who, data->old_group_name, group_name); - g_free(data->old_group_name); - } else { - /* msn_add_contact_to_group(userlist, data, data->who, group_name); */ - } - } -} - -static void qng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { /* TODO: Call PNG after the timeout specified. */ @@ -1468,61 +1342,6 @@ } } -static void -reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) -{ - MsnSession *session; - const char *group_id, *group_name; - - session = cmdproc->session; - group_id = cmd->params[2]; - group_name = purple_url_decode(cmd->params[3]); - - msn_userlist_rename_group_id(session->userlist, group_id, group_name); -} - -static void -reg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) -{ - const char * group_id; - char **params; - - params = g_strsplit(trans->params, " ", 0); - - group_id = params[0]; - - group_error_helper(cmdproc->session, _("Unable to rename group"), group_id, error); - - g_strfreev(params); -} - -static void -rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) -{ - MsnSession *session; - const char *group_id; - - session = cmdproc->session; - group_id = cmd->params[2]; - - msn_userlist_remove_group_id(session->userlist, group_id); -} - -static void -rmg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) -{ - const char *group_id; - char **params; - - params = g_strsplit(trans->params, " ", 0); - - group_id = params[0]; - - group_error_helper(cmdproc->session, _("Unable to delete group"), group_id, error); - - g_strfreev(params); -} - /************************************************************************** * Misc commands **************************************************************************/ @@ -2075,10 +1894,54 @@ g_hash_table_destroy(table); } +/************************************************************************** + * Dispatch server list management + **************************************************************************/ +typedef struct MsnAddRemoveListData { + MsnCmdProc *cmdproc; + MsnUser *user; + MsnListOp list_op; + gboolean add; +} MsnAddRemoveListData; + +static void +modify_unknown_buddy_on_list(MsnSession *session, const char *passport, + MsnNetwork network, gpointer data) +{ + MsnAddRemoveListData *addrem = data; + MsnCmdProc *cmdproc; + xmlnode *node; + char *payload; + int payload_len; + + cmdproc = addrem->cmdproc; + + /* Update user first */ + msn_user_set_network(addrem->user, network); + + node = xmlnode_new("ml"); + node->child = NULL; + + msn_add_contact_xml(session, node, passport, + addrem->list_op, network); + + payload = xmlnode_to_str(node, &payload_len); + xmlnode_free(node); + + if (addrem->add) + msn_notification_post_adl(cmdproc, payload, payload_len); + else + msn_notification_post_rml(cmdproc, payload, payload_len); + + g_free(payload); + g_free(addrem); +} + void msn_notification_add_buddy_to_list(MsnNotification *notification, MsnListId list_id, MsnUser *user) { + MsnAddRemoveListData *addrem; MsnCmdProc *cmdproc; MsnListOp list_op = 1 << list_id; xmlnode *adl_node; @@ -2093,11 +1956,23 @@ msn_add_contact_xml(notification->session, adl_node, user->passport, list_op, user->networkid); - payload = xmlnode_to_str(adl_node,&payload_len); + payload = xmlnode_to_str(adl_node, &payload_len); xmlnode_free(adl_node); - msn_notification_post_adl(notification->servconn->cmdproc, - payload,payload_len); + if (user->networkid != MSN_NETWORK_UNKNOWN) { + msn_notification_post_adl(cmdproc, payload, payload_len); + + } else { + addrem = g_new(MsnAddRemoveListData, 1); + addrem->cmdproc = cmdproc; + addrem->user = user; + addrem->list_op = list_op; + addrem->add = TRUE; + + msn_notification_send_fqy(notification->session, payload, payload_len, + modify_unknown_buddy_on_list, addrem); + } + g_free(payload); } @@ -2105,8 +1980,8 @@ msn_notification_rem_buddy_from_list(MsnNotification *notification, MsnListId list_id, MsnUser *user) { + MsnAddRemoveListData *addrem; MsnCmdProc *cmdproc; - MsnTransaction *trans; MsnListOp list_op = 1 << list_id; xmlnode *rml_node; char *payload; @@ -2123,10 +1998,20 @@ payload = xmlnode_to_str(rml_node, &payload_len); xmlnode_free(rml_node); - purple_debug_info("msn", "Send RML with payload:\n%s\n", payload); - trans = msn_transaction_new(cmdproc, "RML","%" G_GSIZE_FORMAT, strlen(payload)); - msn_transaction_set_payload(trans, payload, strlen(payload)); - msn_cmdproc_send_trans(cmdproc, trans); + if (user->networkid != MSN_NETWORK_UNKNOWN) { + msn_notification_post_rml(cmdproc, payload, payload_len); + + } else { + addrem = g_new(MsnAddRemoveListData, 1); + addrem->cmdproc = cmdproc; + addrem->user = user; + addrem->list_op = list_op; + addrem->add = FALSE; + + msn_notification_send_fqy(notification->session, payload, payload_len, + modify_unknown_buddy_on_list, addrem); + } + g_free(payload); } @@ -2149,9 +2034,6 @@ msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd); msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd); msn_table_add_cmd(cbs_table, "BLP", "BLP", blp_cmd); - msn_table_add_cmd(cbs_table, "REG", "REG", reg_cmd); - msn_table_add_cmd(cbs_table, "ADG", "ADG", adg_cmd); - msn_table_add_cmd(cbs_table, "RMG", "RMG", rmg_cmd); msn_table_add_cmd(cbs_table, "XFR", "XFR", xfr_cmd); /* Asynchronous */ @@ -2184,11 +2066,8 @@ msn_table_add_cmd(cbs_table, NULL, "241", adl_241_error_cmd); - msn_table_add_error(cbs_table, "ADD", add_error); msn_table_add_error(cbs_table, "ADL", adl_error); msn_table_add_error(cbs_table, "FQY", fqy_error); - msn_table_add_error(cbs_table, "REG", reg_error); - msn_table_add_error(cbs_table, "RMG", rmg_error); msn_table_add_error(cbs_table, "USR", usr_error); msn_table_add_msg_type(cbs_table,