Index: cmdproc.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/cmdproc.c,v retrieving revision 1.15 diff -u -p -r1.15 cmdproc.c --- cmdproc.c 11 Jan 2005 17:25:01 -0000 1.15 +++ cmdproc.c 8 Nov 2005 17:31:40 -0000 @@ -294,6 +294,9 @@ msn_cmdproc_process_cmd(MsnCmdProc *cmdp } } + if (trans != NULL) + cmd->trans = trans; + if (cmdproc->cbs_table->async != NULL) cb = g_hash_table_lookup(cmdproc->cbs_table->async, cmd->command); Index: command.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/command.h,v retrieving revision 1.3 diff -u -p -r1.3 command.h --- command.h 6 Jun 2004 03:42:54 -0000 1.3 +++ command.h 8 Nov 2005 17:31:40 -0000 @@ -29,10 +29,8 @@ typedef struct _MsnCommand MsnCommand; #include "cmdproc.h" #include "transaction.h" -#if 1 typedef void (*MsnPayloadCb)(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len); -#endif /** * A received command. Index: error.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/error.c,v retrieving revision 1.10 diff -u -p -r1.10 error.c --- error.c 6 Jun 2004 03:42:54 -0000 1.10 +++ error.c 8 Nov 2005 17:31:41 -0000 @@ -60,6 +60,9 @@ msn_error_get_text(unsigned int type) case 210: g_snprintf(msg, sizeof(msg), _("List Full")); break; + case 213: + g_snprintf(msg, sizeof(msg), _("List error (probably a gaim bug)")); + break; case 215: g_snprintf(msg, sizeof(msg), _("Already there")); break; Index: group.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/group.c,v retrieving revision 1.5 diff -u -p -r1.5 group.c --- group.c 6 Jun 2004 03:42:54 -0000 1.5 +++ group.c 8 Nov 2005 17:31:41 -0000 @@ -25,18 +25,18 @@ #include "group.h" MsnGroup * -msn_group_new(MsnUserList *userlist, int id, const char *name) +msn_group_new(MsnUserList *userlist, const char *id, const char *name) { MsnGroup *group; - g_return_val_if_fail(id >= 0, NULL); + g_return_val_if_fail(id != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); group = g_new0(MsnGroup, 1); msn_userlist_add_group(userlist, group); - group->id = id; + group->id = g_strdup(id); group->name = g_strdup(name); return group; @@ -48,16 +48,20 @@ msn_group_destroy(MsnGroup *group) g_return_if_fail(group != NULL); g_free(group->name); + g_free(group->id); g_free(group); } void -msn_group_set_id(MsnGroup *group, int id) +msn_group_set_id(MsnGroup *group, const char *id) { g_return_if_fail(group != NULL); - g_return_if_fail(id >= 0); + g_return_if_fail(id != NULL); - group->id = id; + if (group->id != NULL) + g_free(group->id); + + group->id = g_strdup(id); } void @@ -72,10 +76,10 @@ msn_group_set_name(MsnGroup *group, cons group->name = g_strdup(name); } -int +const char * msn_group_get_id(const MsnGroup *group) { - g_return_val_if_fail(group != NULL, -1); + g_return_val_if_fail(group != NULL, NULL); return group->id; } Index: group.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/group.h,v retrieving revision 1.5 diff -u -p -r1.5 group.h --- group.h 6 Jun 2004 03:42:54 -0000 1.5 +++ group.h 8 Nov 2005 17:31:41 -0000 @@ -33,6 +33,8 @@ typedef struct _MsnGroup MsnGroup; #include "userlist.h" +#define MSN_NO_GROUP_GUID "XxXxXxXx-XxXx-XxXx-XxXx-XxXxXxXxXxXx" + /** * A group. */ @@ -40,7 +42,7 @@ struct _MsnGroup { MsnSession *session; /**< The MSN session. */ - int id; /**< The group ID. */ + char *id; /**< The group ID. */ char *name; /**< The name of the group. */ }; @@ -58,7 +60,7 @@ struct _MsnGroup * * @return A new group structure. */ -MsnGroup *msn_group_new(MsnUserList *userlist, int id, const char *name); +MsnGroup *msn_group_new(MsnUserList *userlist, const char *id, const char *name); /** * Destroys a group structure. @@ -73,7 +75,7 @@ void msn_group_destroy(MsnGroup *group); * @param group The group. * @param id The ID. */ -void msn_group_set_id(MsnGroup *group, int id); +void msn_group_set_id(MsnGroup *group, const char *id); /** * Sets the name for a group. @@ -90,7 +92,7 @@ void msn_group_set_name(MsnGroup *group, * * @return The ID. */ -int msn_group_get_id(const MsnGroup *group); +const char *msn_group_get_id(const MsnGroup *group); /** * Returns the name for a group. Index: msn.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/msn.c,v retrieving revision 1.376 diff -u -p -r1.376 msn.c --- msn.c 6 Nov 2005 21:51:59 -0000 1.376 +++ msn.c 8 Nov 2005 17:31:41 -0000 @@ -116,52 +116,50 @@ msn_cmd_nudge(GaimConversation *conv, co } static void -msn_act_id(GaimConnection *gc, const char *entry) +msn_set_prp(GaimConnection *gc, const char *type, const char *entry) { MsnCmdProc *cmdproc; MsnSession *session; - GaimAccount *account; - const char *alias; session = gc->proto_data; cmdproc = session->notification->cmdproc; - account = gaim_connection_get_account(gc); - if(entry && strlen(entry)) - alias = gaim_url_encode(entry); + if (entry == NULL || *entry == '\0') + { + msn_cmdproc_send(cmdproc, "PRP", "%s", type); + } else - alias = ""; - - if (strlen(alias) > BUDDY_ALIAS_MAXLEN) { - gaim_notify_error(gc, NULL, - _("Your new MSN friendly name is too long."), NULL); - return; + msn_cmdproc_send(cmdproc, "PRP", "%s %s", type, + gaim_url_encode(entry)); } - - msn_cmdproc_send(cmdproc, "REA", "%s %s", - gaim_account_get_username(account), - alias); } static void -msn_set_prp(GaimConnection *gc, const char *type, const char *entry) +msn_act_id(GaimConnection *gc, const char *entry) { MsnCmdProc *cmdproc; MsnSession *session; + GaimAccount *account; + const char *alias; session = gc->proto_data; cmdproc = session->notification->cmdproc; + account = gaim_connection_get_account(gc); - if (entry == NULL || *entry == '\0') - { - msn_cmdproc_send(cmdproc, "PRP", "%s", type); - } + if(entry && strlen(entry)) + alias = entry; else + alias = ""; + + if (strlen(alias) > BUDDY_ALIAS_MAXLEN) { - msn_cmdproc_send(cmdproc, "PRP", "%s %s", type, - gaim_url_encode(entry)); + gaim_notify_error(gc, NULL, + _("Your new MSN friendly name is too long."), NULL); + return; } + + msn_set_prp(gc, "MFN", alias); } static void @@ -894,56 +892,6 @@ msn_set_idle(GaimConnection *gc, int idl msn_change_status(session); } -#if 0 -static void -fake_userlist_add_buddy(MsnUserList *userlist, - const char *who, int list_id, - const char *group_name) -{ - MsnUser *user; - static int group_id_c = 1; - int group_id; - - group_id = -1; - - if (group_name != NULL) - { - MsnGroup *group; - group = msn_group_new(userlist, group_id_c, group_name); - group_id = group_id_c++; - } - - user = msn_userlist_find_user(userlist, who); - - if (user == NULL) - { - user = msn_user_new(userlist, who, NULL); - msn_userlist_add_user(userlist, user); - } - else - if (user->list_op & (1 << list_id)) - { - if (list_id == MSN_LIST_FL) - { - if (group_id >= 0) - if (g_list_find(user->group_ids, - GINT_TO_POINTER(group_id))) - return; - } - else - return; - } - - if (group_id >= 0) - { - user->group_ids = g_list_append(user->group_ids, - GINT_TO_POINTER(group_id)); - } - - user->list_op |= (1 << list_id); -} -#endif - static void msn_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) { @@ -955,18 +903,6 @@ msn_add_buddy(GaimConnection *gc, GaimBu userlist = session->userlist; who = msn_normalize(gc->account, buddy->name); - if (!session->logged_in) - { -#if 0 - fake_userlist_add_buddy(session->sync_userlist, who, MSN_LIST_FL, - group ? group->name : NULL); -#else - gaim_debug_error("msn", "msn_add_buddy called before connected\n"); -#endif - - return; - } - #if 0 if (group != NULL && group->name != NULL) gaim_debug_info("msn", "msn_add_buddy: %s, %s\n", who, group->name); @@ -988,8 +924,8 @@ msn_add_buddy(GaimConnection *gc, GaimBu /* XXX - Would group ever be NULL here? I don't think so... * shx: Yes it should; MSN handles non-grouped buddies, and this is only * internal. */ - msn_userlist_add_buddy(userlist, who, MSN_LIST_FL, - group ? group->name : NULL); + /* stu: eh? nothing internal to MSN calls msn_add_buddy, so we should be fine */ + msn_userlist_add_buddy(userlist, who, MSN_LIST_FL, group->name); } static void @@ -1247,24 +1183,32 @@ msn_rename_group(GaimConnection *gc, con { MsnSession *session; MsnCmdProc *cmdproc; - int old_gid; + const char *old_gid; const char *enc_new_group_name; session = gc->proto_data; cmdproc = session->notification->cmdproc; enc_new_group_name = gaim_url_encode(group->name); + if (!strcmp(old_name, gaim_account_get_string(gc->account, "nogroup", _("Individuals")))) + { + gaim_account_set_string(gc->account, "nogroup", group->name); + } + old_gid = msn_userlist_find_group_id(session->userlist, old_name); - if (old_gid >= 0) + if (old_gid != NULL) { - msn_cmdproc_send(cmdproc, "REG", "%d %s 0", old_gid, + msn_cmdproc_send(cmdproc, "REG", "%s %s", old_gid, enc_new_group_name); } +#if 0 + /* would this ever happen except for the un-grouped group? */ else { - msn_cmdproc_send(cmdproc, "ADG", "%s 0", enc_new_group_name); + msn_cmdproc_send(cmdproc, "ADG", "%s", enc_new_group_name); } +#endif } static void @@ -1318,14 +1262,15 @@ msn_remove_group(GaimConnection *gc, Gai { MsnSession *session; MsnCmdProc *cmdproc; - int group_id; + const char *group_id; session = gc->proto_data; cmdproc = session->notification->cmdproc; - if ((group_id = msn_userlist_find_group_id(session->userlist, group->name)) >= 0) + group_id = msn_userlist_find_group_id(session->userlist, group->name); + if (group_id != NULL) { - msn_cmdproc_send(cmdproc, "RMG", "%d", group_id); + msn_cmdproc_send(cmdproc, "RMG", "%s", group_id); } } Index: msn.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/msn.h,v retrieving revision 1.30 diff -u -p -r1.30 msn.h --- msn.h 8 Oct 2005 00:51:51 -0000 1.30 +++ msn.h 8 Nov 2005 17:31:41 -0000 @@ -57,20 +57,16 @@ #define MSN_BUF_LEN 8192 -#define USEROPT_MSNSERVER 3 #define MSN_SERVER "messenger.hotmail.com" -#define USEROPT_MSNPORT 4 #define MSN_PORT 1863 #define MSN_TYPING_RECV_TIMEOUT 6 #define MSN_TYPING_SEND_TIMEOUT 4 #define HOTMAIL_URL "http://www.hotmail.com/cgi-bin/folders" -#define PASSPORT_URL "http://lc1.law13.hotmail.passport.com/cgi-bin/dologin?login=" +#define PASSPORT_URL "https://lc1.law13.hotmail.passport.com/cgi-bin/dologin?login=" #define PROFILE_URL "http://members.msn.com/" -#define USEROPT_HOTMAIL 0 - #define BUDDY_ALIAS_MAXLEN 387 #define MSN_FT_GUID "{5D3E02AB-6190-11d3-BBBB-00C04F795683}" @@ -85,7 +81,8 @@ typedef enum MSN_LIST_FL_OP = 0x01, MSN_LIST_AL_OP = 0x02, MSN_LIST_BL_OP = 0x04, - MSN_LIST_RL_OP = 0x08 + MSN_LIST_RL_OP = 0x08, + MSN_LIST_PL_OP = 0x10 } MsnListOp; Index: notification.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/notification.c,v retrieving revision 1.153 diff -u -p -r1.153 notification.c --- notification.c 6 Nov 2005 21:52:00 -0000 1.153 +++ notification.c 8 Nov 2005 17:31:41 -0000 @@ -153,7 +153,7 @@ msn_notification_disconnect(MsnNotificat **************************************************************************/ static void -group_error_helper(MsnSession *session, const char *msg, int group_id, int error) +group_error_helper(MsnSession *session, const char *msg, const char *group_id, int error) { GaimAccount *account; GaimConnection *gc; @@ -165,7 +165,7 @@ group_error_helper(MsnSession *session, if (error == 224) { - if (group_id == 0) + if (group_id == NULL) { return; } @@ -233,13 +233,9 @@ usr_cmd(MsnCmdProc *cmdproc, MsnCommand if (!g_ascii_strcasecmp(cmd->params[1], "OK")) { /* OK */ - const char *friendly = gaim_url_decode(cmd->params[3]); - - gaim_connection_set_display_name(gc, friendly); - msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN); - msn_cmdproc_send(cmdproc, "SYN", "%s", "0"); + msn_cmdproc_send(cmdproc, "SYN", "%s %s", "0", "0"); } else if (!g_ascii_strcasecmp(cmd->params[1], "TWN")) { @@ -438,40 +434,96 @@ chl_cmd(MsnCmdProc *cmdproc, MsnCommand **************************************************************************/ static void -add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) +adc_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session; MsnUser *user; const char *list; - const char *passport; - const char *friendly; + char *passport; + const char *friendly = NULL; + const char *contact_guid = NULL; MsnListId list_id; - int group_id; + GSList *group_ids = NULL; - list = cmd->params[1]; - passport = cmd->params[3]; - friendly = gaim_url_decode(cmd->params[4]); + list = cmd->params[1]; + list_id = msn_get_list_id(list); session = cmdproc->session; - user = msn_userlist_find_user(session->userlist, passport); - - if (user == NULL) + if ((cmd->param_count == 4) && (list_id == MSN_LIST_FL)) { - user = msn_user_new(session->userlist, passport, friendly); - msn_userlist_add_user(session->userlist, user); + const char *group_id; + /* this is a moved buddy */ + contact_guid = cmd->params[2] + 2; + group_id = cmd->params[3]; + user = msn_userlist_find_user_by_guid(session->userlist, contact_guid); + + g_return_if_fail(user != NULL); + + msn_user_add_group_id(user, group_id); + user->ungrouped = FALSE; } else - msn_user_set_friendly_name(user, friendly); + { + char **tokens; + /* this is a new buddy add */ + passport = cmd->params[2] + 2; /* Strip off the preceeding N= */ + if (cmd->param_count > 3 && strlen(cmd->params[3]) > 2) + friendly = gaim_url_decode(cmd->params[3] + 2); - list_id = msn_get_list_id(list); + if (cmd->param_count > 4 && strlen(cmd->params[4]) > 2) + contact_guid = cmd->params[4] + 2; - if (cmd->param_count >= 6) - group_id = atoi(cmd->params[5]); - else - group_id = -1; + user = msn_userlist_find_user(session->userlist, passport); + + if (user == NULL) + { + user = msn_user_new(session->userlist, passport, friendly, + contact_guid); + msn_userlist_add_user(session->userlist, user); + } + else if (friendly != NULL) + { + msn_user_set_friendly_name(user, friendly); + } + + if (cmd->param_count == 6) + { + char **c; + const char *group_nums; + + group_nums = cmd->params[5]; + + tokens = g_strsplit(group_nums, ",", -1); + + for (c = tokens; *c != NULL; c++) + { + char *id; + + id = *c; + group_ids = g_slist_append(group_ids, id); + } + } + + msn_got_add_user(session, user, list_id, group_ids); + + if (group_ids != NULL) { + g_strfreev(tokens); + g_slist_free(group_ids); + } + } + /* There is a user that must me moved to this group */ + if (list_id == MSN_LIST_FL && cmd->trans != NULL && cmd->trans->data != NULL) + { + MsnUserList *userlist = cmdproc->session->userlist; + MsnAddBuddy *data = cmd->trans->data; + + msn_notification_add_buddy(userlist->session->notification, "FL", data->who, + contact_guid, friendly, data->group_id); + g_free(data->who); + g_free(data->group_id); - msn_got_add_user(session, user, list_id, group_id); + } msn_user_update(user); } @@ -492,7 +544,7 @@ add_error(MsnCmdProc *cmdproc, MsnTransa params = g_strsplit(trans->params, " ", 0); list = params[0]; - passport = params[1]; + passport = params[1] + 2; if (!strcmp(list, "FL")) msg = g_strdup_printf(_("Unable to add user on %s (%s)"), @@ -559,14 +611,14 @@ adg_cmd(MsnCmdProc *cmdproc, MsnCommand { MsnGroup *group; MsnSession *session; - gint group_id; + const char *group_id; const char *group_name; session = cmdproc->session; - group_id = atoi(cmd->params[3]); + group_id = cmd->params[2]; - group_name = gaim_url_decode(cmd->params[2]); + group_name = gaim_url_decode(cmd->params[1]); group = msn_group_new(session->userlist, group_id, group_name); @@ -748,40 +800,27 @@ not_cmd(MsnCmdProc *cmdproc, MsnCommand } static void -rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) -{ - /* TODO: This might be for us too */ - - MsnSession *session; - GaimConnection *gc; - const char *friendly; - - session = cmdproc->session; - gc = session->account->gc; - friendly = gaim_url_decode(cmd->params[3]); - - gaim_connection_set_display_name(gc, friendly); -} - -static void prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session = cmdproc->session; + GaimConnection *gc = session->account->gc; const char *type, *value; g_return_if_fail(cmd->param_count >= 3); - type = cmd->params[2]; + type = cmd->params[1]; - if (cmd->param_count == 4) + if (cmd->param_count == 3) { - value = cmd->params[3]; + value = cmd->params[2]; if (!strcmp(type, "PHH")) msn_user_set_home_phone(session->user, gaim_url_decode(value)); else if (!strcmp(type, "PHW")) msn_user_set_work_phone(session->user, gaim_url_decode(value)); else if (!strcmp(type, "PHM")) msn_user_set_mobile_phone(session->user, gaim_url_decode(value)); + else if (!strcmp(type, "MFN")) + gaim_connection_set_display_name(gc, gaim_url_decode(value)); } else { @@ -798,12 +837,12 @@ static void reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session; - int group_id; + const char *group_id; const char *group_name; session = cmdproc->session; - group_id = atoi(cmd->params[2]); - group_name = gaim_url_decode(cmd->params[3]); + group_id = cmd->params[1]; + group_name = gaim_url_decode(cmd->params[2]); msn_userlist_rename_group_id(session->userlist, group_id, group_name); } @@ -811,12 +850,12 @@ reg_cmd(MsnCmdProc *cmdproc, MsnCommand static void reg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) { - int group_id; + const char *group_id; char **params; params = g_strsplit(trans->params, " ", 0); - group_id = atoi(params[0]); + group_id = params[0]; group_error_helper(cmdproc->session, _("Unable to rename group"), group_id, error); @@ -829,23 +868,28 @@ rem_cmd(MsnCmdProc *cmdproc, MsnCommand MsnSession *session; MsnUser *user; const char *list; - const char *passport; + const char *user_id; /* Could be passport, could be contact GUID. */ MsnListId list_id; - int group_id; + const char *group_id; session = cmdproc->session; list = cmd->params[1]; - passport = cmd->params[3]; - user = msn_userlist_find_user(session->userlist, passport); + user_id = cmd->params[2]; + + if (!strcmp(list, "FL")) + user = msn_userlist_find_user_by_guid(session->userlist, + user_id); + else + user = msn_userlist_find_user(session->userlist, user_id); g_return_if_fail(user != NULL); list_id = msn_get_list_id(list); - if (cmd->param_count == 5) - group_id = atoi(cmd->params[4]); + if (cmd->param_count == 4) + group_id = cmd->params[3]; else - group_id = -1; + group_id = NULL; msn_got_rem_user(session, user, list_id, group_id); msn_user_update(user); @@ -855,10 +899,10 @@ static void rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session; - int group_id; + const char *group_id; session = cmdproc->session; - group_id = atoi(cmd->params[2]); + group_id = cmd->params[1]; msn_userlist_remove_group_id(session->userlist, group_id); } @@ -866,12 +910,12 @@ rmg_cmd(MsnCmdProc *cmdproc, MsnCommand static void rmg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) { - int group_id; + const char *group_id; char **params; params = g_strsplit(trans->params, " ", 0); - group_id = atoi(params[0]); + group_id = params[0]; group_error_helper(cmdproc->session, _("Unable to delete group"), group_id, error); @@ -898,7 +942,7 @@ syn_cmd(MsnCmdProc *cmdproc, MsnCommand return; } - total_users = atoi(cmd->params[2]); + total_users = atoi(cmd->params[3]); if (total_users == 0) { @@ -1332,40 +1376,77 @@ system_msg(MsnCmdProc *cmdproc, MsnMessa void msn_notification_add_buddy(MsnNotification *notification, const char *list, - const char *who, const char *store_name, - int group_id) + const char *who, + const char *contact_guid, + const char *store_name, + const char *group_id) { MsnCmdProc *cmdproc; cmdproc = notification->servconn->cmdproc; - if (group_id < 0 && !strcmp(list, "FL")) - group_id = 0; - - if (group_id >= 0) + /* moogman: + * If old_group_name == NULL, then ADC cmd is different. + * If a new buddy (as opposed to a buddy move), ADC cmd is different. + * If !Fl, then do same as "new". + * stu: that didn't make much sense. what's old_group_name? */ + if (contact_guid != NULL && group_id != NULL) + { + /* Buddy already in FL. Add it to group_id. */ + msn_cmdproc_send(cmdproc, "ADC", "%s C=%s %s", + list, contact_guid, group_id); + } + else if (strcmp(list, "FL") == 0) { - msn_cmdproc_send(cmdproc, "ADD", "%s %s %s %d", - list, who, store_name, group_id); + /* Add buddy to our FL. */ + /* FunkTastic Foo! */ + MsnTransaction *trans; + MsnAddBuddy *data; + + cmdproc = notification->cmdproc; + data = g_new0(MsnAddBuddy, 1); + + data->who = g_strdup(who); + data->group_id = g_strdup(group_id); + + trans = msn_transaction_new(cmdproc, "ADC", "%s N=%s F=%s", + list, who, store_name); + + msn_transaction_set_data(trans, data); + + msn_cmdproc_send_trans(cmdproc, trans); + } else { - msn_cmdproc_send(cmdproc, "ADD", "%s %s %s", list, who, store_name); + /* Add buddy to another list (BL, AL). */ + msn_cmdproc_send(cmdproc, "ADC", "%s N=%s", + list, who); } } void msn_notification_rem_buddy(MsnNotification *notification, const char *list, - const char *who, int group_id) + const char *who, + const char *contact_guid, + const char *group_id) { MsnCmdProc *cmdproc; + const char *final_who; + cmdproc = notification->servconn->cmdproc; - if (group_id >= 0) + final_who = ((strcmp(list, "FL") == 0) ? contact_guid : who); + + /* moogman: If user is only in one group, set group_id == NULL (force a complete remove). + * It seems as if we don't need to do the above check. I've tested it as it is and it seems + * to work fine. However, a note is left here incase things change. */ + if (group_id != NULL) { - msn_cmdproc_send(cmdproc, "REM", "%s %s %d", list, who, group_id); + msn_cmdproc_send(cmdproc, "REM", "%s %s %s", list, final_who, group_id); } else { - msn_cmdproc_send(cmdproc, "REM", "%s %s", list, who); + msn_cmdproc_send(cmdproc, "REM", "%s %s", list, final_who); } } @@ -1383,15 +1464,14 @@ msn_notification_init(void) /* Synchronous */ msn_table_add_cmd(cbs_table, "CHG", "CHG", NULL); msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd); - msn_table_add_cmd(cbs_table, "ADD", "ADD", add_cmd); - msn_table_add_cmd(cbs_table, "ADD", "ILN", iln_cmd); + msn_table_add_cmd(cbs_table, "ADC", "ADC", adc_cmd); + msn_table_add_cmd(cbs_table, "ADC", "ILN", iln_cmd); msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd); msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd); msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd); msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd); msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd); - msn_table_add_cmd(cbs_table, "REA", "REA", rea_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, "BLP", "BLP", NULL); @@ -1407,7 +1487,7 @@ msn_notification_init(void) msn_table_add_cmd(cbs_table, NULL, "CHL", chl_cmd); msn_table_add_cmd(cbs_table, NULL, "REM", rem_cmd); - msn_table_add_cmd(cbs_table, NULL, "ADD", add_cmd); + msn_table_add_cmd(cbs_table, NULL, "ADC", adc_cmd); msn_table_add_cmd(cbs_table, NULL, "QRY", NULL); msn_table_add_cmd(cbs_table, NULL, "QNG", NULL); @@ -1421,10 +1501,9 @@ msn_notification_init(void) msn_table_add_cmd(cbs_table, "fallback", "XFR", xfr_cmd); - msn_table_add_error(cbs_table, "ADD", add_error); + msn_table_add_error(cbs_table, "ADC", add_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, "REA", rea_error); */ msn_table_add_error(cbs_table, "USR", usr_error); msn_table_add_msg_type(cbs_table, Index: notification.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/notification.h,v retrieving revision 1.9 diff -u -p -r1.9 notification.h --- notification.h 7 Jan 2005 02:48:33 -0000 1.9 +++ notification.h 8 Nov 2005 17:31:41 -0000 @@ -46,10 +46,12 @@ void msn_notification_init(void); void msn_notification_add_buddy(MsnNotification *notification, const char *list, const char *who, - const char *store_name, int group_id); + const char *contact_guid, + const char *store_name, const char *group_id); void msn_notification_rem_buddy(MsnNotification *notification, const char *list, const char *who, - int group_id); + const char *contact_guid, + const char *group_id); MsnNotification *msn_notification_new(MsnSession *session); void msn_notification_destroy(MsnNotification *notification); gboolean msn_notification_connect(MsnNotification *notification, Index: servconn.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/servconn.c,v retrieving revision 1.49 diff -u -p -r1.49 servconn.c --- servconn.c 30 Oct 2005 16:59:25 -0000 1.49 +++ servconn.c 8 Nov 2005 17:31:42 -0000 @@ -334,6 +334,7 @@ read_cb(gpointer data, gint source, Gaim if (len <= 0) { + gaim_debug_error("msn", "servconn read error, len: %d\n", len); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; Index: session.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/session.c,v retrieving revision 1.47 diff -u -p -r1.47 session.c --- session.c 6 Nov 2005 21:52:00 -0000 1.47 +++ session.c 8 Nov 2005 17:31:42 -0000 @@ -27,6 +27,8 @@ #include "dialog.h" +#define MSN_PROTOCOL_VERSION 10 + MsnSession * msn_session_new(GaimAccount *account) { @@ -40,10 +42,9 @@ msn_session_new(GaimAccount *account) session->notification = msn_notification_new(session); session->userlist = msn_userlist_new(session); - session->user = msn_user_new(session->userlist, - gaim_account_get_username(account), NULL); + session->user = msn_user_new(session->userlist, gaim_account_get_username(account), NULL, NULL); - session->protocol_ver = 9; + session->protocol_ver = MSN_PROTOCOL_VERSION; session->conv_seq = 1; return session; @@ -235,7 +236,6 @@ msn_session_sync_users(MsnSession *sessi /* The core used to use msn_add_buddy to add all buddies before * being logged in. This no longer happens, so we manually iterate * over the whole buddy list to identify sync issues. */ - for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { GaimGroup *group = (GaimGroup *)gnode; const char *group_name = group->name; @@ -253,19 +253,27 @@ msn_session_sync_users(MsnSession *sessi MsnUser *remote_user; gboolean found = FALSE; - remote_user = msn_userlist_find_user(session->userlist, b->name); + remote_user = msn_userlist_find_user(session->userlist, + b->name); if ((remote_user != NULL) && (remote_user->list_op & MSN_LIST_FL_OP)) { - int group_id; + const char *gid; GList *l; - group_id = msn_userlist_find_group_id(remote_user->userlist, + gid = msn_userlist_find_group_id(remote_user->userlist, group_name); + /* humm, this group doesn't really exist. */ + /* Fix this when your brain works */ + if (remote_user->ungrouped && !strcmp(group_name, + gaim_account_get_string(gc->account, + "nogroup", _("Individuals")))) + continue; + for (l = remote_user->group_ids; l != NULL; l = l->next) { - if (group_id == GPOINTER_TO_INT(l->data)) + if ((gid != NULL) && !strcmp(l->data, gid)) { found = TRUE; break; @@ -276,8 +284,8 @@ msn_session_sync_users(MsnSession *sessi if (!found) { - /* The user was not on the server list or not in that group - * on the server list */ + /* The user was not on the server list, or not in that + * group on the server list */ msn_show_sync_issue(session, b->name, group_name); } } Index: state.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/state.h,v retrieving revision 1.8 diff -u -p -r1.8 state.h --- state.h 6 Nov 2005 21:52:00 -0000 1.8 +++ state.h 8 Nov 2005 17:31:42 -0000 @@ -41,8 +41,6 @@ typedef enum } MsnAwayType; -#define MSN_AWAY_TYPE(x) (((x) >> 1) & 0x0F) - /** * Changes the status of the user. * Index: sync.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/sync.c,v retrieving revision 1.6 diff -u -p -r1.6 sync.c --- sync.c 30 Dec 2004 15:55:19 -0000 1.6 +++ sync.c 8 Nov 2005 17:31:42 -0000 @@ -60,6 +60,7 @@ static void prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session = cmdproc->session; + GaimConnection *gc = session->account->gc; const char *type, *value; type = cmd->params[0]; @@ -73,6 +74,8 @@ prp_cmd(MsnCmdProc *cmdproc, MsnCommand msn_user_set_work_phone(session->user, gaim_url_decode(value)); else if (!strcmp(type, "PHM")) msn_user_set_mobile_phone(session->user, gaim_url_decode(value)); + else if (!strcmp(type, "MFN")) + gaim_connection_set_display_name(gc, gaim_url_decode(value)); } else { @@ -92,18 +95,13 @@ lsg_cmd(MsnCmdProc *cmdproc, MsnCommand MsnGroup *group; GaimGroup *g; const char *name; - int group_id; + const char *group_id; - group_id = atoi(cmd->params[0]); - name = gaim_url_decode(cmd->params[1]); + name = gaim_url_decode(cmd->params[0]); + group_id = cmd->params[1]; group = msn_group_new(session->userlist, group_id, name); - /* HACK */ - if (group_id == 0) - /* Group of ungroupped buddies */ - return; - if ((g = gaim_find_group(name)) == NULL) { g = gaim_group_new(name); @@ -117,47 +115,82 @@ lst_cmd(MsnCmdProc *cmdproc, MsnCommand MsnSession *session = cmdproc->session; char *passport = NULL; const char *friend = NULL; + const char *contact_guid = NULL; int list_op; MsnUser *user; - passport = cmd->params[0]; - friend = gaim_url_decode(cmd->params[1]); - list_op = atoi(cmd->params[2]); + /* moogman: + * MSNP9 LST has three arguments. + * MSNP11 LST has variable parameter count. + * 5 : User is on your list. + * 2 : User is not on your list/blocked? */ + + /* from http://msnpiki.msnfanatic.com/index.php/MSNP11:Changes#LST : + * 0 1 2 3 4 + * N=passport@hotmail.com F=Display%20Name C=cGUID 13 gGUID1,gGUID2,... + * N=passport@hotmail.com F=Display%20Name C=cGUID 13 + * N=passport@hotmail.com F=Display%20Name 13 + * N=passport@hotmail.com 13 + */ + + g_return_if_fail(cmd->param_count >= 2); + g_return_if_fail(strlen(cmd->params[0]) > 2); + + passport = cmd->params[0] + 2; + + if (cmd->param_count > 3) + { + g_return_if_fail(strlen(cmd->params[2]) > 2); + contact_guid = cmd->params[2] + 2; + list_op = strtoul(cmd->params[3], NULL, 10); + } + else if (cmd->param_count > 2) + { + g_return_if_fail(strlen(cmd->params[1]) > 2); + friend = gaim_url_decode(cmd->params[1] + 2); + list_op = strtoul(cmd->params[2], NULL, 10); + } + else + { + list_op = strtoul(cmd->params[1], NULL, 10); + } - user = msn_user_new(session->userlist, passport, friend); + user = msn_user_new(session->userlist, passport, friend, contact_guid); msn_userlist_add_user(session->userlist, user); - session->sync->last_user = user; /* TODO: This can be improved */ if (list_op & MSN_LIST_FL_OP) { - char **c; - char **tokens; - const char *group_nums; - GSList *group_ids; + char **tokens = NULL; + GSList *group_ids = NULL; - group_nums = cmd->params[3]; + if (cmd->param_count >= 5) + { + char **c; + const char *group_nums; - group_ids = NULL; + group_nums = cmd->params[4]; - tokens = g_strsplit(group_nums, ",", -1); + tokens = g_strsplit(group_nums, ",", -1); - for (c = tokens; *c != NULL; c++) - { - int id; + for (c = tokens; *c != NULL; c++) + { + char *id; - id = atoi(*c); - group_ids = g_slist_append(group_ids, GINT_TO_POINTER(id)); + id = *c; + group_ids = g_slist_append(group_ids, id); + } } - g_strfreev(tokens); - msn_got_lst_user(session, user, list_op, group_ids); - g_slist_free(group_ids); + if (group_ids != NULL) { + g_strfreev(tokens); + g_slist_free(group_ids); + } } else { Index: user.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/user.c,v retrieving revision 1.28 diff -u -p -r1.28 user.c --- user.c 8 Oct 2005 16:08:51 -0000 1.28 +++ user.c 8 Nov 2005 17:31:42 -0000 @@ -27,7 +27,7 @@ MsnUser * msn_user_new(MsnUserList *userlist, const char *passport, - const char *store_name) + const char *store_name, const char *contact_guid) { MsnUser *user; @@ -37,6 +37,7 @@ msn_user_new(MsnUserList *userlist, cons msn_user_set_passport(user, passport); msn_user_set_store_name(user, store_name); + msn_user_set_contact_guid(user, contact_guid); /* * XXX This seems to reset the friendly name from what it should be @@ -73,6 +74,9 @@ msn_user_destroy(MsnUser *user) if (user->store_name != NULL) g_free(user->store_name); + if (user->contact_guid != NULL) + g_free(user->contact_guid); + if (user->phone.home != NULL) g_free(user->phone.home); @@ -163,6 +167,15 @@ msn_user_set_store_name(MsnUser *user, c } void +msn_user_set_contact_guid(MsnUser *user, const char *guid) +{ + if (user->contact_guid != NULL) + g_free(user->contact_guid); + + user->contact_guid = g_strdup(guid); +} + +void msn_user_set_buddy_icon(MsnUser *user, const char *filename) { struct stat st; @@ -245,29 +258,36 @@ msn_user_set_buddy_icon(MsnUser *user, c } void -msn_user_add_group_id(MsnUser *user, int id) +msn_user_add_group_id(MsnUser *user, const char *id) { MsnUserList *userlist; GaimAccount *account; GaimBuddy *b; GaimGroup *g; const char *passport; - const char *group_name; + const char *group_name = NULL; g_return_if_fail(user != NULL); - g_return_if_fail(id >= 0); - - user->group_ids = g_list_append(user->group_ids, GINT_TO_POINTER(id)); userlist = user->userlist; account = userlist->session->account; passport = msn_user_get_passport(user); - group_name = msn_userlist_find_group_name(userlist, id); + if (id != NULL) + { + user->group_ids = g_list_append(user->group_ids, g_strdup(id)); + group_name = msn_userlist_find_group_name(userlist, id); + } + + if (group_name == NULL) + { + /* I hate MSN */ + group_name = gaim_account_get_string(account, "nogroup", _("Individuals")); + } g = gaim_find_group(group_name); - if ((id == 0) && (g == NULL)) + if (g == NULL) { g = gaim_group_new(group_name); gaim_blist_add_group(g, NULL); @@ -286,12 +306,21 @@ msn_user_add_group_id(MsnUser *user, int } void -msn_user_remove_group_id(MsnUser *user, int id) +msn_user_remove_group_id(MsnUser *user, const char *id) { + GList *l; + g_return_if_fail(user != NULL); - g_return_if_fail(id >= 0); + g_return_if_fail(id != NULL); + + l = g_list_find_custom(user->group_ids, id, (GCompareFunc)strcmp); - user->group_ids = g_list_remove(user->group_ids, GINT_TO_POINTER(id)); + if (l != NULL) + { + char *gid = (char *)l->data; + user->group_ids = g_list_remove(user->group_ids, gid); + g_free(gid); + } } void Index: user.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/user.h,v retrieving revision 1.16 diff -u -p -r1.16 user.h --- user.h 30 Dec 2004 15:55:19 -0000 1.16 +++ user.h 8 Nov 2005 17:31:42 -0000 @@ -44,6 +44,7 @@ struct _MsnUser char *passport; /**< The passport account. */ char *store_name; /**< The name stored in the server. */ char *friendly_name; /**< The friendly name. */ + char *contact_guid; /**< The contact's GUID. */ const char *status; /**< The state of the user. */ gboolean idle; /**< The idle state of the user. */ @@ -66,6 +67,8 @@ struct _MsnUser GHashTable *clientcaps; /**< The client's capabilities. */ int list_op; + + gboolean ungrouped; /**< The user is not in any groups */ }; /**************************************************************************/ @@ -79,11 +82,12 @@ struct _MsnUser * @param session The MSN session. * @param passport The initial passport. * @param stored_name The initial stored name. + * @param contact_guid The contact's GUID. * * @return A new user structure. */ MsnUser *msn_user_new(MsnUserList *userlist, const char *passport, - const char *store_name); + const char *store_name, const char *contact_guid); /** * Destroys a user structure. @@ -135,6 +139,14 @@ void msn_user_set_friendly_name(MsnUser void msn_user_set_store_name(MsnUser *user, const char *name); /** + * Sets the contact guid for a user. + * + * @param user The user. + * @param name The contact guid. + */ +void msn_user_set_contact_guid(MsnUser *user, const char *guid); + +/** * Sets the buddy icon for a local user. * * @param user The user. @@ -156,7 +168,7 @@ void msn_user_set_group_ids(MsnUser *use * @param user The user. * @param id The group ID. */ -void msn_user_add_group_id(MsnUser *user, int id); +void msn_user_add_group_id(MsnUser *user, const char *id); /** * Removes the group ID from a user. @@ -164,7 +176,7 @@ void msn_user_add_group_id(MsnUser *user * @param user The user. * @param id The group ID. */ -void msn_user_remove_group_id(MsnUser *user, int id); +void msn_user_remove_group_id(MsnUser *user, const char *id); /** * Sets the home phone number for a user. Index: userlist.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/userlist.c,v retrieving revision 1.31 diff -u -p -r1.31 userlist.c --- userlist.c 10 Oct 2005 17:59:46 -0000 1.31 +++ userlist.c 8 Nov 2005 17:31:42 -0000 @@ -24,11 +24,12 @@ #include "msn.h" #include "userlist.h" -const char *lists[] = { "FL", "AL", "BL", "RL" }; +const char *lists[] = { "FL", "AL", "BL", "RL", "PL"}; typedef struct { GaimConnection *gc; + MsnUser *user; char *who; } MsnPermitAdd; @@ -39,12 +40,20 @@ typedef struct static void msn_accept_add_cb(MsnPermitAdd *pa) { + MsnUser *user = pa->user; + if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) { MsnSession *session = pa->gc->proto_data; MsnUserList *userlist = session->userlist; msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_AL, NULL); + if (user->list_op & MSN_LIST_PL_OP) + { + msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_RL, NULL); + msn_userlist_rem_buddy(userlist, pa->who, MSN_LIST_PL, NULL); + user->list_op &= ~MSN_LIST_PL_OP; + } /* TODO: This ask for the alias, right? */ gaim_account_notify_added(pa->gc->account, NULL, pa->who, NULL, NULL); @@ -57,12 +66,19 @@ msn_accept_add_cb(MsnPermitAdd *pa) static void msn_cancel_add_cb(MsnPermitAdd *pa) { + MsnUser *user = pa->user; + if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) { MsnSession *session = pa->gc->proto_data; MsnUserList *userlist = session->userlist; msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_BL, NULL); + if (user->list_op & MSN_LIST_PL_OP) + { + msn_userlist_rem_buddy(userlist, pa->who, MSN_LIST_PL, NULL); + user->list_op &= ~MSN_LIST_PL_OP; + } } g_free(pa->who); @@ -70,16 +86,35 @@ msn_cancel_add_cb(MsnPermitAdd *pa) } static void -got_new_entry(GaimConnection *gc, const char *passport, const char *friendly) +got_new_entry(GaimConnection *gc, MsnUser *user) { MsnPermitAdd *pa; + const char *passport, *friendly; char *msg; + passport = msn_user_get_passport(user); + friendly = msn_user_get_store_name(user); + + /* they're on the pending list AND already on either allow or block */ + if ((user->list_op & MSN_LIST_PL_OP) && (user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP))) + { + MsnSession *session = gc->proto_data; + MsnUserList *userlist = session->userlist; + + if (user->list_op & MSN_LIST_AL_OP) + msn_userlist_add_buddy(userlist, passport, MSN_LIST_RL, NULL); + msn_userlist_rem_buddy(userlist, passport, MSN_LIST_PL, NULL); + user->list_op &= ~MSN_LIST_PL_OP; + + return; + } + pa = g_new0(MsnPermitAdd, 1); pa->who = g_strdup(passport); + pa->user = user; pa->gc = gc; - if (friendly != NULL) + if (friendly != NULL && strcmp(friendly, passport)) { msg = g_strdup_printf( _("The user %s (%s) wants to add %s to his or her " @@ -108,22 +143,28 @@ got_new_entry(GaimConnection *gc, const **************************************************************************/ static gboolean -user_is_in_group(MsnUser *user, int group_id) +user_is_in_group(MsnUser *user, const char *group_id) { + GList *cur_gid; + if (user == NULL) return FALSE; - if (group_id < 0) - return FALSE; + cur_gid = g_list_first(user->group_ids); - if (g_list_find(user->group_ids, GINT_TO_POINTER(group_id))) - return TRUE; + if (group_id == NULL) + { + if (cur_gid == NULL) + return TRUE; - return FALSE; + return FALSE; + } + + return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp) != NULL); } static gboolean -user_is_there(MsnUser *user, int list_id, int group_id) +user_is_there(MsnUser *user, int list_id, const char *group_id) { int list_op; @@ -137,8 +178,7 @@ user_is_there(MsnUser *user, int list_id if (list_id == MSN_LIST_FL) { - if (group_id >= 0) - return user_is_in_group(user, group_id); + return user_is_in_group(user, group_id); } return TRUE; @@ -212,13 +252,15 @@ msn_get_list_id(const char *list) return MSN_LIST_BL; else if (list[0] == 'R') return MSN_LIST_RL; + else if (list[0] == 'P') + return MSN_LIST_PL; return -1; } void msn_got_add_user(MsnSession *session, MsnUser *user, - MsnListId list_id, int group_id) + MsnListId list_id, GSList *group_ids) { GaimAccount *account; const char *passport; @@ -237,12 +279,22 @@ msn_got_add_user(MsnSession *session, Ms serv_got_alias(gc, passport, friendly); - if (group_id >= 0) + if (group_ids != NULL) { - msn_user_add_group_id(user, group_id); + GSList *c; + + for (c = group_ids; c != NULL; c = g_slist_next(c)) + { + const char *group_id; + group_id = c->data; + msn_user_add_group_id(user, group_id); + user->ungrouped = FALSE; + } } else { + msn_user_add_group_id(user, NULL); + user->ungrouped = TRUE; /* session->sync->fl_users_count++; */ } } @@ -265,23 +317,23 @@ msn_got_add_user(MsnSession *session, Ms "%s has added you to his or her contact list.\n", passport); - convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, passport, account); - if (convo) { - GaimBuddy *buddy; - char *msg; - - buddy = gaim_find_buddy(account, passport); - msg = g_strdup_printf( - _("%s has added you to his or her contact list."), - buddy ? gaim_buddy_get_contact_alias(buddy) : passport); - gaim_conv_im_write(GAIM_CONV_IM(convo), passport, msg, - GAIM_MESSAGE_SYSTEM, time(NULL)); - g_free(msg); - } - - if (!(user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP))) + convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, passport, account); + if (convo) { + GaimBuddy *buddy; + char *msg; + + buddy = gaim_find_buddy(account, passport); + msg = g_strdup_printf( + _("%s has added you to his or her contact list."), + buddy ? gaim_buddy_get_contact_alias(buddy) : passport); + gaim_conv_im_write(GAIM_CONV_IM(convo), passport, msg, + GAIM_MESSAGE_SYSTEM, time(NULL)); + g_free(msg); + } + + if (!(user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)) || (user->list_op & MSN_LIST_PL_OP)) { - got_new_entry(gc, passport, friendly); + got_new_entry(gc, user); } } @@ -291,21 +343,29 @@ msn_got_add_user(MsnSession *session, Ms void msn_got_rem_user(MsnSession *session, MsnUser *user, - MsnListId list_id, int group_id) + MsnListId list_id, const char *group_id) { GaimAccount *account; const char *passport; account = session->account; - passport = msn_user_get_passport(user); if (list_id == MSN_LIST_FL) { /* TODO: When is the user totally removed? */ - if (group_id >= 0) + if (group_id != NULL) { msn_user_remove_group_id(user, group_id); + + gaim_debug_info("msn", "Buddy '%s' shall be deleted? (on %d groups!)\n", + passport, g_list_length(user->group_ids)); + /* No. well, yes, but the rest of the code explodes. */ + + if ((g_list_length(user->group_ids)) == 0 && !user->ungrouped) + { + gaim_debug_info("msn", "This one REALLY SHOULD GO!!!\n"); + } return; } else @@ -349,9 +409,9 @@ msn_got_rem_user(MsnSession *session, Ms if (user->list_op == 0) { - gaim_debug_info("msn", "Buddy '%s' shall be deleted?.\n", - passport); - + gaim_debug_info("msn", "Buddy '%s' shall be deleted? (on %d groups!)\n", + passport, g_list_length(user->group_ids)); + /* No. well, yes, but the rest of the code explodes. */ } } @@ -370,14 +430,26 @@ msn_got_lst_user(MsnSession *session, Ms passport = msn_user_get_passport(user); store = msn_user_get_store_name(user); + user->list_op = list_op; + if (list_op & MSN_LIST_FL_OP) { - GSList *c; - for (c = group_ids; c != NULL; c = g_slist_next(c)) + if (group_ids != NULL) { - int group_id; - group_id = GPOINTER_TO_INT(c->data); - msn_user_add_group_id(user, group_id); + GSList *c; + for (c = group_ids; c != NULL; c = g_slist_next(c)) + { + const char *group_id; + group_id = c->data; + msn_user_add_group_id(user, group_id); + } + user->ungrouped = FALSE; + } + else + { + /* group_ids == NULL happens when in no group */ + msn_user_add_group_id(user, NULL); + user->ungrouped = TRUE; } /* FIXME: It might be a real alias */ @@ -410,18 +482,16 @@ msn_got_lst_user(MsnSession *session, Ms gaim_privacy_deny_add(account, passport, TRUE); } - if (list_op & MSN_LIST_RL_OP) + if (list_op & (MSN_LIST_RL_OP | MSN_LIST_PL_OP)) { /* These are users who have us on their contact list. */ /* TODO: what does store name is when this happens? */ - if (!(list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP))) + if (!(list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)) || (list_op & MSN_LIST_PL_OP)) { - got_new_entry(gc, passport, store); + got_new_entry(gc, user); } } - - user->list_op = list_op; } /************************************************************************** @@ -497,6 +567,28 @@ msn_userlist_find_user(MsnUserList *user return NULL; } +MsnUser * +msn_userlist_find_user_by_guid(MsnUserList *userlist, const char *guid) +{ + GList *l; + + g_return_val_if_fail(guid != NULL, NULL); + + for (l = userlist->users; l != NULL; l = l->next) + { + MsnUser *user = (MsnUser *)l->data; + + if (user->contact_guid == NULL) + continue; + + if (!strcmp(guid, user->contact_guid)) + return user; + } + + return NULL; +} + + void msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group) { @@ -510,18 +602,18 @@ msn_userlist_remove_group(MsnUserList *u } MsnGroup * -msn_userlist_find_group_with_id(MsnUserList *userlist, int id) +msn_userlist_find_group_with_id(MsnUserList *userlist, const char *id) { GList *l; g_return_val_if_fail(userlist != NULL, NULL); - g_return_val_if_fail(id >= 0, NULL); + g_return_val_if_fail(id != NULL, NULL); for (l = userlist->groups; l != NULL; l = l->next) { MsnGroup *group = l->data; - if (group->id == id) + if (!strcmp(group->id, id)) return group; } @@ -547,7 +639,7 @@ msn_userlist_find_group_with_name(MsnUse return NULL; } -int +const char * msn_userlist_find_group_id(MsnUserList *userlist, const char *group_name) { MsnGroup *group; @@ -557,14 +649,16 @@ msn_userlist_find_group_id(MsnUserList * if (group != NULL) return msn_group_get_id(group); else - return -1; + return NULL; } const char * -msn_userlist_find_group_name(MsnUserList *userlist, int group_id) +msn_userlist_find_group_name(MsnUserList *userlist, const char *group_id) { MsnGroup *group; + g_return_val_if_fail(group_id != NULL, NULL); + group = msn_userlist_find_group_with_id(userlist, group_id); if (group != NULL) @@ -574,11 +668,13 @@ msn_userlist_find_group_name(MsnUserList } void -msn_userlist_rename_group_id(MsnUserList *userlist, int group_id, +msn_userlist_rename_group_id(MsnUserList *userlist, const char *group_id, const char *new_name) { MsnGroup *group; + /* XXX: if group_id is NULL, add new group instead? */ + group = msn_userlist_find_group_with_id(userlist, group_id); if (group != NULL) @@ -586,10 +682,12 @@ msn_userlist_rename_group_id(MsnUserList } void -msn_userlist_remove_group_id(MsnUserList *userlist, int group_id) +msn_userlist_remove_group_id(MsnUserList *userlist, const char *group_id) { MsnGroup *group; + g_return_if_fail(group_id != NULL); + group = msn_userlist_find_group_with_id(userlist, group_id); if (group != NULL) @@ -604,37 +702,47 @@ msn_userlist_rem_buddy(MsnUserList *user const char *who, int list_id, const char *group_name) { MsnUser *user; - int group_id; + const char *group_id = NULL; const char *list; user = msn_userlist_find_user(userlist, who); - group_id = -1; + + g_return_if_fail(user != NULL); if (group_name != NULL) { group_id = msn_userlist_find_group_id(userlist, group_name); - if (group_id < 0) + if (group_id == NULL && !user->ungrouped) { /* Whoa, there is no such group. */ gaim_debug_error("msn", "Group doesn't exist: %s\n", group_name); + /* Whoa, MSN SUCKS! ... this is probably a user not in a group. */ return; + /* nogroup = TRUE; */ } } + list = lists[list_id]; + + /* if this user is not in that group and is an ungrouped user, and that group is the group + * for ungrouped users, etc. */ + if (list_id == MSN_LIST_FL && group_id && user->ungrouped && + !strcmp(group_name, gaim_account_get_string(userlist->session->account, "nogroup", _("Individuals")))) + { + group_id = NULL; + } /* First we're going to check if not there. */ - if (!(user_is_there(user, list_id, group_id))) + if ((list_id != MSN_LIST_FL || group_id) && !(user_is_there(user, list_id, group_id)) && !user->ungrouped) { - list = lists[list_id]; gaim_debug_error("msn", "User '%s' is not there: %s\n", who, list); return; } /* Then request the rem to the server. */ - list = lists[list_id]; - - msn_notification_rem_buddy(userlist->session->notification, list, who, group_id); + msn_notification_rem_buddy(userlist->session->notification, list, who, + user->contact_guid, group_id); } void @@ -643,12 +751,10 @@ msn_userlist_add_buddy(MsnUserList *user const char *group_name) { MsnUser *user; - int group_id; + const char *group_id = NULL; const char *list; const char *store_name; - group_id = -1; - if (!gaim_email_is_valid(who)) { /* only notify the user about problems adding to the friends list @@ -669,7 +775,7 @@ msn_userlist_add_buddy(MsnUserList *user { group_id = msn_userlist_find_group_id(userlist, group_name); - if (group_id < 0) + if (group_id == NULL) { /* Whoa, we must add that group first. */ msn_request_add_group(userlist, who, NULL, group_name); @@ -679,10 +785,11 @@ msn_userlist_add_buddy(MsnUserList *user user = msn_userlist_find_user(userlist, who); + list = lists[list_id]; + /* First we're going to check if it's already there. */ if (user_is_there(user, list_id, group_id)) { - list = lists[list_id]; gaim_debug_error("msn", "User '%s' is already there: %s\n", who, list); return; } @@ -690,26 +797,25 @@ msn_userlist_add_buddy(MsnUserList *user store_name = (user != NULL) ? get_store_name(user) : who; /* Then request the add to the server. */ - list = lists[list_id]; - msn_notification_add_buddy(userlist->session->notification, list, who, - store_name, group_id); + user ? user->contact_guid : NULL, store_name, group_id); } void msn_userlist_move_buddy(MsnUserList *userlist, const char *who, const char *old_group_name, const char *new_group_name) { - int new_group_id; + const char *new_group_id; new_group_id = msn_userlist_find_group_id(userlist, new_group_name); - if (new_group_id < 0) + if (new_group_id == NULL) { msn_request_add_group(userlist, who, old_group_name, new_group_name); return; } msn_userlist_add_buddy(userlist, who, MSN_LIST_FL, new_group_name); - msn_userlist_rem_buddy(userlist, who, MSN_LIST_FL, old_group_name); + if (old_group_name != NULL) + msn_userlist_rem_buddy(userlist, who, MSN_LIST_FL, old_group_name); } Index: userlist.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/msn/userlist.h,v retrieving revision 1.3 diff -u -p -r1.3 userlist.h --- userlist.h 25 Aug 2004 01:43:54 -0000 1.3 +++ userlist.h 8 Nov 2005 17:31:42 -0000 @@ -35,7 +35,8 @@ typedef enum MSN_LIST_FL, MSN_LIST_AL, MSN_LIST_BL, - MSN_LIST_RL + MSN_LIST_RL, + MSN_LIST_PL } MsnListId; @@ -46,6 +47,13 @@ typedef struct } MsnMoveBuddy; +typedef struct +{ + char *who; + char *group_id; + +} MsnAddBuddy; + struct _MsnUserList { MsnSession *session; @@ -66,9 +74,9 @@ struct _MsnUserList MsnListId msn_get_list_id(const char *list); void msn_got_add_user(MsnSession *session, MsnUser *user, - MsnListId list_id, int group_id); + MsnListId list_id, GSList *group_id); void msn_got_rem_user(MsnSession *session, MsnUser *user, - MsnListId list_id, int group_id); + MsnListId list_id, const char *group_id); void msn_got_lst_user(MsnSession *session, MsnUser *user, int list_op, GSList *group_ids); @@ -78,18 +86,20 @@ void msn_userlist_add_user(MsnUserList * void msn_userlist_remove_user(MsnUserList *userlist, MsnUser *user); MsnUser *msn_userlist_find_user(MsnUserList *userlist, const char *passport); +MsnUser *msn_userlist_find_user_by_guid(MsnUserList *userlist, + const char *guid); void msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group); void msn_userlist_remove_group(MsnUserList *userlist, MsnGroup *group); -MsnGroup *msn_userlist_find_group_with_id(MsnUserList *userlist, int id); +MsnGroup *msn_userlist_find_group_with_id(MsnUserList *userlist, const char *id); MsnGroup *msn_userlist_find_group_with_name(MsnUserList *userlist, const char *name); -int msn_userlist_find_group_id(MsnUserList *userlist, +const char *msn_userlist_find_group_id(MsnUserList *userlist, const char *group_name); const char *msn_userlist_find_group_name(MsnUserList *userlist, - int group_id); -void msn_userlist_rename_group_id(MsnUserList *userlist, int group_id, + const char *group_id); +void msn_userlist_rename_group_id(MsnUserList *userlist, const char *group_id, const char *new_name); -void msn_userlist_remove_group_id(MsnUserList *userlist, int group_id); +void msn_userlist_remove_group_id(MsnUserList *userlist, const char *group_id); void msn_userlist_rem_buddy(MsnUserList *userlist, const char *who, int list_id, const char *group_name);