comparison src/protocols/msn/notification.c @ 9193:502707ca1836

[gaim-migrate @ 9988] Patch by Felipe Contreras to add MSN file transfer and buddy icons. Please test and report any bugs! committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sun, 06 Jun 2004 02:39:08 +0000
parents c30d81b4dd22
children 364aa73323b5
comparison
equal deleted inserted replaced
9192:5655dcd94d0f 9193:502707ca1836
22 #include "msn.h" 22 #include "msn.h"
23 #include "notification.h" 23 #include "notification.h"
24 #include "state.h" 24 #include "state.h"
25 #include "error.h" 25 #include "error.h"
26 #include "utils.h" 26 #include "utils.h"
27 27 #include "page.h"
28 typedef struct 28
29 { 29 #include "userlist.h"
30 GaimConnection *gc; 30 #include "sync.h"
31 MsnUser *user; 31
32 32 #define BUDDY_ALIAS_MAXLEN 388
33 } MsnPermitAdd; 33
34 34 static MsnTable *cbs_table;
35 static MsnTable *cbs_table = NULL;
36
37 /**************************************************************************
38 * Utility functions
39 **************************************************************************/
40 static gboolean
41 add_buddy(MsnCmdProc *cmdproc, MsnUser *user)
42 {
43 MsnSession *session;
44 GaimAccount *account;
45 GaimConnection *gc;
46 GaimBuddy *b;
47 MsnGroup *group = NULL;
48 GaimGroup *g = NULL;
49 GList *l, *l2;
50 GSList *sl;
51 GSList *buddies;
52
53 session = cmdproc->session;
54 account = session->account;
55 gc = gaim_account_get_connection(account);
56 buddies = gaim_find_buddies(account, msn_user_get_passport(user));
57
58 for (l = msn_user_get_group_ids(user); l != NULL; l = l->next)
59 {
60 int group_id = GPOINTER_TO_INT(l->data);
61
62 if (group_id > -1)
63 group = msn_groups_find_with_id(session->groups, group_id);
64
65 if (group == NULL)
66 {
67 gaim_debug(GAIM_DEBUG_WARNING, "msn",
68 "Group ID %d for user %s was not defined.\n",
69 group_id, msn_user_get_passport(user));
70
71 /* Find a group that we can stick this guy into. Lamer. */
72 l2 = msn_groups_get_list(session->groups);
73
74 if (l2 != NULL)
75 {
76 group = l2->data;
77
78 msn_user_add_group_id(user, msn_group_get_id(group));
79 }
80 }
81
82 if (group == NULL ||
83 (g = gaim_find_group(msn_group_get_name(group))) == NULL)
84 {
85 gaim_debug(GAIM_DEBUG_ERROR, "msn",
86 "Group '%s' appears in server-side "
87 "buddy list, but not here!",
88 msn_group_get_name(group));
89 }
90
91 if (group != NULL)
92 msn_group_add_user(group, user);
93
94 b = NULL;
95
96 for (sl = buddies; sl != NULL; sl = sl->next)
97 {
98 b = (GaimBuddy *)sl->data;
99
100 if (gaim_find_buddys_group(b) == g)
101 break;
102
103 b = NULL;
104 }
105
106 if (b == NULL)
107 {
108 const char *passport, *friendly;
109
110 passport = msn_user_get_passport(user);
111
112 b = gaim_buddy_new(account, passport, NULL);
113
114 b->proto_data = user;
115
116 gaim_blist_add_buddy(b, NULL, g, NULL);
117
118 if ((friendly = msn_user_get_name(user)) != NULL)
119 serv_got_alias(gc, passport, friendly);
120 }
121 else
122 b->proto_data = user;
123 }
124
125 g_slist_free(buddies);
126
127 serv_got_alias(gc, (char *)msn_user_get_passport(user),
128 (char *)msn_user_get_name(user));
129
130 return TRUE;
131 }
132
133 /**************************************************************************
134 * Callbacks
135 **************************************************************************/
136 static void
137 msn_accept_add_cb(MsnPermitAdd *pa)
138 {
139 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL)
140 {
141 MsnSession *session;
142 MsnCmdProc *cmdproc;
143
144 session = pa->gc->proto_data;
145 cmdproc = session->notification_conn->cmdproc;
146
147 msn_cmdproc_send(cmdproc, "ADD", "AL %s %s",
148 msn_user_get_passport(pa->user),
149 gaim_url_encode(msn_user_get_name(pa->user)));
150
151 if (cmdproc->error)
152 return;
153
154 gaim_privacy_permit_add(pa->gc->account,
155 msn_user_get_passport(pa->user), TRUE);
156 gaim_account_notify_added(pa->gc->account, NULL,
157 msn_user_get_passport(pa->user),
158 msn_user_get_name(pa->user), NULL);
159 }
160
161 msn_user_destroy(pa->user);
162 g_free(pa);
163 }
164
165 static void
166 msn_cancel_add_cb(MsnPermitAdd *pa)
167 {
168 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL)
169 {
170 MsnSession *session;
171 MsnCmdProc *cmdproc;
172
173 session = pa->gc->proto_data;
174 cmdproc = session->notification_conn->cmdproc;
175
176 msn_cmdproc_send(cmdproc, "ADD", "BL %s %s",
177 msn_user_get_passport(pa->user),
178 gaim_url_encode(msn_user_get_name(pa->user)));
179
180 if (cmdproc->error)
181 return;
182
183 gaim_privacy_deny_add(pa->gc->account,
184 msn_user_get_passport(pa->user), TRUE);
185 }
186
187 msn_user_destroy(pa->user);
188 g_free(pa);
189 }
190 35
191 /************************************************************************** 36 /**************************************************************************
192 * Login 37 * Login
193 **************************************************************************/ 38 **************************************************************************/
194 39
40 void
41 msn_got_login_params(MsnSession *session, const char *login_params)
42 {
43 MsnCmdProc *cmdproc;
44
45 cmdproc = session->notification->cmdproc;
46
47 msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params);
48 }
49
195 static void 50 static void
196 cvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 51 cvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
197 { 52 {
198 GaimAccount *account; 53 GaimAccount *account;
199 54
212 account = cmdproc->session->account; 67 account = cmdproc->session->account;
213 gc = gaim_account_get_connection(account); 68 gc = gaim_account_get_connection(account);
214 69
215 if (strcmp(cmd->params[1], "MD5")) 70 if (strcmp(cmd->params[1], "MD5"))
216 { 71 {
217 gaim_connection_error(gc, _("Unable to login using MD5")); 72 msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
218
219 return; 73 return;
220 } 74 }
221 75
222 msn_cmdproc_send(cmdproc, "USR", "MD5 I %s", 76 msn_cmdproc_send(cmdproc, "USR", "MD5 I %s",
223 gaim_account_get_username(account)); 77 gaim_account_get_username(account));
252 106
253 /* OK */ 107 /* OK */
254 108
255 gaim_connection_set_display_name(gc, friendly); 109 gaim_connection_set_display_name(gc, friendly);
256 110
257 session->syncing_lists = TRUE;
258
259 msn_cmdproc_send(cmdproc, "SYN", "%s", "0"); 111 msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
260 112
261 if (cmdproc->error) 113 if (cmdproc->error)
262 return; 114 return;
263 115
270 122
271 /* Passport authentication */ 123 /* Passport authentication */
272 session->nexus = msn_nexus_new(session); 124 session->nexus = msn_nexus_new(session);
273 125
274 /* Parse the challenge data. */ 126 /* Parse the challenge data. */
127
275 elems = g_strsplit(cmd->params[3], ",", 0); 128 elems = g_strsplit(cmd->params[3], ",", 0);
276 129
277 for (cur = elems; *cur != NULL; cur++) 130 for (cur = elems; *cur != NULL; cur++)
278 { 131 {
279 tokens = g_strsplit(*cur, "=", 2); 132 tokens = g_strsplit(*cur, "=", 2);
323 static void 176 static void
324 ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 177 ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
325 { 178 {
326 MsnSession *session; 179 MsnSession *session;
327 GaimAccount *account; 180 GaimAccount *account;
328 GaimConnection *gc;
329 gboolean protocol_supported = FALSE; 181 gboolean protocol_supported = FALSE;
330 char proto_str[8]; 182 char proto_str[8];
331 size_t i; 183 size_t i;
332 184
333 session = cmdproc->session; 185 session = cmdproc->session;
334 account = session->account; 186 account = session->account;
335 gc = gaim_account_get_connection(account);
336 187
337 g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver); 188 g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver);
338 189
339 for (i = 1; i < cmd->param_count; i++) 190 for (i = 1; i < cmd->param_count; i++)
340 { 191 {
345 } 196 }
346 } 197 }
347 198
348 if (!protocol_supported) 199 if (!protocol_supported)
349 { 200 {
350 gaim_connection_error(gc, _("Protocol not supported")); 201 msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
351
352 return; 202 return;
353 } 203 }
354 204
355 if (session->protocol_ver >= 8) 205 msn_cmdproc_send(cmdproc, "CVR",
356 { 206 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s",
357 msn_cmdproc_send(cmdproc, "CVR", 207 gaim_account_get_username(account));
358 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s",
359 gaim_account_get_username(account));
360 }
361 else
362 {
363 msn_cmdproc_send(cmdproc, "INF", NULL, NULL);
364 }
365 } 208 }
366 209
367 /************************************************************************** 210 /**************************************************************************
368 * Log out 211 * Log out
369 **************************************************************************/ 212 **************************************************************************/
370 static void 213 static void
371 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 214 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
372 { 215 {
373 GaimConnection *gc;
374
375 gc = cmdproc->session->account->gc;
376
377 if (!g_ascii_strcasecmp(cmd->params[0], "OTH")) 216 if (!g_ascii_strcasecmp(cmd->params[0], "OTH"))
378 { 217 msn_cmdproc_show_error(cmdproc, MSN_ERROR_SIGNOTHER);
379 gc->wants_to_die = TRUE;
380 gaim_connection_error(gc,
381 _("You have been disconnected. You have "
382 "signed on from another location."));
383 }
384 else if (!g_ascii_strcasecmp(cmd->params[0], "SSD")) 218 else if (!g_ascii_strcasecmp(cmd->params[0], "SSD"))
385 { 219 msn_cmdproc_show_error(cmdproc, MSN_ERROR_SERVDOWN);
386 gaim_connection_error(gc,
387 _("You have been disconnected. The MSN servers "
388 "are going down temporarily."));
389 }
390 } 220 }
391 221
392 /************************************************************************** 222 /**************************************************************************
393 * Messages 223 * Messages
394 **************************************************************************/ 224 **************************************************************************/
395 static void 225 static void
396 msg_cmd_post(MsnCmdProc *cmdproc, char *payload, size_t len) 226 msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
227 size_t len)
397 { 228 {
398 MsnMessage *msg; 229 MsnMessage *msg;
399 230
400 msg = msn_message_new(); 231 msg = msn_message_new_from_cmd(cmdproc->session, cmd);
401 232
402 msn_message_parse_payload(msg, payload, len); 233 msn_message_parse_payload(msg, payload, len);
403 234 /* msn_message_show_readable(msg, "Notification", TRUE); */
404 msg->passport = cmdproc->temp; 235
236 msg->remote_user = g_strdup(cmd->params[0]);
405 msn_cmdproc_process_msg(cmdproc, msg); 237 msn_cmdproc_process_msg(cmdproc, msg);
406 g_free(cmdproc->temp);
407 cmdproc->temp = NULL;
408 238
409 msn_message_destroy(msg); 239 msn_message_destroy(msg);
410 } 240 }
411 241
412 static void 242 static void
413 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 243 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
414 { 244 {
415 cmdproc->payload_cb = msg_cmd_post; 245 /* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued
416 cmdproc->servconn->payload_len = atoi(cmd->params[2]); 246 * command and we are processing it */
417 cmdproc->temp = g_strdup(cmd->params[0]); 247
248 if (cmd->payload == NULL)
249 {
250 cmdproc->last_cmd->payload_cb = msg_cmd_post;
251 cmdproc->servconn->payload_len = atoi(cmd->params[2]);
252 }
253 else
254 {
255 g_return_if_fail(cmd->payload_cb != NULL);
256
257 cmd->payload_cb(cmdproc, cmd, cmd->payload, cmd->payload_len);
258 }
418 } 259 }
419 260
420 /************************************************************************** 261 /**************************************************************************
421 * Challenges 262 * Challenges
422 **************************************************************************/ 263 **************************************************************************/
423 static void 264 static void
424 chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 265 chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
425 { 266 {
426 MsnSession *session;
427 MsnTransaction *trans; 267 MsnTransaction *trans;
428 char buf[33]; 268 char buf[33];
429 const char *challenge_resp; 269 const char *challenge_resp;
430 const char *challenge_str;
431 md5_state_t st; 270 md5_state_t st;
432 md5_byte_t di[16]; 271 md5_byte_t di[16];
433 int i; 272 int i;
434 273
435 session = cmdproc->session;
436
437 md5_init(&st); 274 md5_init(&st);
438 md5_append(&st, (const md5_byte_t *)cmd->params[1], 275 md5_append(&st, (const md5_byte_t *)cmd->params[1],
439 strlen(cmd->params[1])); 276 strlen(cmd->params[1]));
440 277
441 if (session->protocol_ver >= 8) 278 challenge_resp = "VT6PX?UQTM4WM%YR";
442 {
443 challenge_resp = "VT6PX?UQTM4WM%YR";
444 challenge_str = "PROD0038W!61ZTF9";
445 }
446 else
447 {
448 challenge_resp = "Q1P7W2E4J9R8U3S5";
449 challenge_str = "msmsgs@msnmsgr.com";
450 }
451 279
452 md5_append(&st, (const md5_byte_t *)challenge_resp, 280 md5_append(&st, (const md5_byte_t *)challenge_resp,
453 strlen(challenge_resp)); 281 strlen(challenge_resp));
454 md5_finish(&st, di); 282 md5_finish(&st, di);
455 283
456 for (i = 0; i < 16; i++) 284 for (i = 0; i < 16; i++)
457 g_snprintf(buf + (i*2), 3, "%02x", di[i]); 285 g_snprintf(buf + (i*2), 3, "%02x", di[i]);
458 286
459 trans = msn_transaction_new("QRY", "%s 32", challenge_str); 287 trans = msn_transaction_new("QRY", "%s 32", "PROD0038W!61ZTF9");
460 288
461 msn_transaction_set_payload(trans, buf, 32); 289 msn_transaction_set_payload(trans, buf, 32);
462 290
463 msn_cmdproc_send_trans(cmdproc, trans); 291 msn_cmdproc_send_trans(cmdproc, trans);
464 } 292 }
469 static void 297 static void
470 add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 298 add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
471 { 299 {
472 MsnSession *session; 300 MsnSession *session;
473 MsnUser *user; 301 MsnUser *user;
474 GaimAccount *account; 302 const char *list;
475 GaimConnection *gc; 303 const char *passport;
476 MsnPermitAdd *pa; 304 const char *friendly;
477 GSList *sl; 305 MsnListId list_id;
478 const char *list, *passport, *group_id = NULL; 306 int group_id;
479 const char *friend;
480 char msg[MSN_BUF_LEN];
481
482 session = cmdproc->session;
483 account = session->account;
484 gc = gaim_account_get_connection(account);
485 307
486 list = cmd->params[1]; 308 list = cmd->params[1];
487 passport = cmd->params[3]; 309 passport = cmd->params[3];
488 friend = gaim_url_decode(cmd->params[4]); 310 friendly = gaim_url_decode(cmd->params[4]);
489 311
312 session = cmdproc->session;
313
314 user = msn_userlist_find_user(session->userlist, passport);
315
316 if (user == NULL)
317 {
318 user = msn_user_new(session->userlist, passport, friendly);
319 msn_userlist_add_user(session->userlist, user);
320 }
321
322 list_id = msn_get_list_id(list);
323
490 if (cmd->param_count >= 6) 324 if (cmd->param_count >= 6)
491 group_id = cmd->params[5]; 325 group_id = atoi(cmd->params[5]);
492 326 else
493 if (!g_ascii_strcasecmp(list, "FL")) 327 group_id = -1;
494 { 328
495 user = msn_user_new(session, passport, NULL); 329 msn_got_add_user(session, user, list_id, group_id);
496
497 if (group_id != NULL)
498 msn_user_add_group_id(user, atoi(group_id));
499
500 add_buddy(cmdproc, user);
501
502 return;
503 }
504 else if (g_ascii_strcasecmp(list, "RL"))
505 return;
506
507 for (sl = gc->account->permit; sl != NULL; sl = sl->next)
508 if (!gaim_utf8_strcasecmp(sl->data, passport))
509 return;
510
511 user = msn_user_new(session, passport, friend);
512 msn_user_set_name(user, friend);
513
514 pa = g_new0(MsnPermitAdd, 1);
515 pa->user = user;
516 pa->gc = gc;
517
518 g_snprintf(msg, sizeof(msg),
519 _("The user %s (%s) wants to add %s to his or her buddy list."),
520 passport, friend, gaim_account_get_username(account));
521
522 gaim_request_action(gc, NULL, msg, NULL, 0, pa, 2,
523 _("Authorize"), G_CALLBACK(msn_accept_add_cb),
524 _("Deny"), G_CALLBACK(msn_cancel_add_cb));
525 } 330 }
526 331
527 static void 332 static void
528 add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) 333 add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
529 { 334 {
583 g_free(reason); 388 g_free(reason);
584 389
585 g_strfreev(params); 390 g_strfreev(params);
586 } 391 }
587 392
393
588 static void 394 static void
589 adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 395 adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
590 { 396 {
591 MsnGroup *group; 397 MsnGroup *group;
592 MsnSession *session; 398 MsnSession *session;
597 403
598 group_id = atoi(cmd->params[3]); 404 group_id = atoi(cmd->params[3]);
599 405
600 group_name = gaim_url_decode(cmd->params[2]); 406 group_name = gaim_url_decode(cmd->params[2]);
601 407
602 group = msn_group_new(session, group_id, group_name); 408 group = msn_group_new(session->userlist, group_id, group_name);
603 409
604 msn_groups_add(session->groups, group); 410 /* There is a user that must me moved to this group */
605 } 411 if (cmd->trans->data)
606 412 {
607 static void 413 /* msn_userlist_move_buddy(); */
608 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 414 MsnUserList *userlist = cmdproc->session->userlist;
609 { 415 MsnMoveBuddy *data = cmd->trans->data;
610 GaimConnection *gc; 416
611 const char *list_name; 417 if (data->old_group_name != NULL)
612
613 gc = cmdproc->session->account->gc;
614
615 if (cmdproc->session->protocol_ver >= 8)
616 list_name = cmd->params[0];
617 else
618 list_name = cmd->params[2];
619
620 if (!g_ascii_strcasecmp(list_name, "AL"))
621 {
622 /*
623 * If the current setting is AL, messages from users who
624 * are not in BL will be delivered.
625 *
626 * In other words, deny some.
627 */
628 gc->account->perm_deny = GAIM_PRIVACY_DENY_USERS;
629 }
630 else
631 {
632 /* If the current setting is BL, only messages from people
633 * who are in the AL will be delivered.
634 *
635 * In other words, permit some.
636 */
637 gc->account->perm_deny = GAIM_PRIVACY_ALLOW_USERS;
638 }
639 }
640
641 static void
642 bpr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
643 {
644 MsnSession *session;
645 GaimConnection *gc;
646 const char *passport, *type, *value;
647 GaimBuddy *b;
648 MsnUser *user;
649
650 session = cmdproc->session;
651 gc = session->account->gc;
652
653 if (cmd->param_count == 4)
654 {
655 passport = cmd->params[1];
656 type = cmd->params[2];
657 value = cmd->params[3];
658 }
659 else if (cmd->param_count == 2)
660 {
661 passport = msn_user_get_passport(session->last_user_added);
662 type = cmd->params[0];
663 value = cmd->params[1];
664 }
665 else
666 return;
667
668 user = msn_users_find_with_passport(session->users, passport);
669
670 if (value != NULL)
671 {
672 if (!strcmp(type, "MOB"))
673 { 418 {
674 if (!strcmp(value, "Y") || !strcmp(value, "N")) 419 msn_userlist_rem_buddy(userlist, data->who, MSN_LIST_FL, data->old_group_name);
675 { 420 g_free(data->old_group_name);
676 user->mobile = (!strcmp(value, "Y") ? TRUE : FALSE);
677
678 if ((b = gaim_find_buddy(gc->account, passport)) != NULL)
679 {
680 if (GAIM_BUDDY_IS_ONLINE(b))
681 {
682 serv_got_update(gc, (char *)passport,
683 1, 0, 0, 0, b->uc);
684 }
685 }
686 }
687 } 421 }
688 else if (!strcmp(type, "PHH")) 422
689 msn_user_set_home_phone(user, gaim_url_decode(value)); 423 msn_userlist_add_buddy(userlist, data->who, MSN_LIST_FL, group_name);
690 else if (!strcmp(type, "PHW")) 424 g_free(data->who);
691 msn_user_set_work_phone(user, gaim_url_decode(value)); 425
692 else if (!strcmp(type, "PHM"))
693 msn_user_set_mobile_phone(user, gaim_url_decode(value));
694 } 426 }
695 } 427 }
696 428
697 static void 429 static void
698 fln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 430 fln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
710 MsnSession *session; 442 MsnSession *session;
711 GaimConnection *gc; 443 GaimConnection *gc;
712 MsnUser *user; 444 MsnUser *user;
713 MsnObject *msnobj; 445 MsnObject *msnobj;
714 int status = 0; 446 int status = 0;
715 const char *state, *passport, *friend; 447 const char *state, *passport, *friendly;
716 GaimBuddy *b; 448 GaimBuddy *b;
717 449
718 session = cmdproc->session; 450 session = cmdproc->session;
719 gc = session->account->gc; 451 gc = session->account->gc;
720 452
721 state = cmd->params[1]; 453 state = cmd->params[1];
722 passport = cmd->params[2]; 454 passport = cmd->params[2];
723 friend = gaim_url_decode(cmd->params[3]); 455 friendly = gaim_url_decode(cmd->params[3]);
724 456
725 user = msn_users_find_with_passport(session->users, passport); 457 user = msn_userlist_find_user(session->userlist, passport);
726 458
727 serv_got_alias(gc, passport, friend); 459 /* serv_got_nick(gc, passport, friendly); */
728 460 serv_got_alias(gc, passport, friendly);
729 msn_user_set_name(user, friend); 461
462 msn_user_set_friendly_name(user, friendly);
730 463
731 if (session->protocol_ver >= 9 && cmd->param_count == 6) 464 if (session->protocol_ver >= 9 && cmd->param_count == 6)
732 { 465 {
733 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[5])); 466 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[5]));
734 msn_user_set_object(user, msnobj); 467 msn_user_set_object(user, msnobj);
748 else if (!g_ascii_strcasecmp(state, "PHN")) 481 else if (!g_ascii_strcasecmp(state, "PHN"))
749 status |= UC_UNAVAILABLE | (MSN_PHONE << 1); 482 status |= UC_UNAVAILABLE | (MSN_PHONE << 1);
750 else if (!g_ascii_strcasecmp(state, "LUN")) 483 else if (!g_ascii_strcasecmp(state, "LUN"))
751 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1); 484 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1);
752 485
753 serv_got_update(gc, (char *)passport, 1, 0, 0, 0, status); 486 serv_got_update(gc, passport, 1, 0, 0, 0, status);
487 }
488
489 static void
490 ipg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
491 {
492 #if 0
493 gaim_debug_misc("msn", "Incoming Page: {%s}\n", payload);
494 #endif
754 } 495 }
755 496
756 static void 497 static void
757 ipg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 498 ipg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
758 { 499 {
759 cmdproc->payload_cb = NULL;
760 cmdproc->servconn->payload_len = atoi(cmd->params[0]); 500 cmdproc->servconn->payload_len = atoi(cmd->params[0]);
761 } 501 cmdproc->last_cmd->payload_cb = ipg_cmd_post;
762
763 static void
764 lsg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
765 {
766 MsnSession *session;
767 MsnGroup *group;
768 GaimGroup *g;
769 const char *name;
770 int num_groups, group_id;
771
772 session = cmdproc->session;
773
774 if (session->protocol_ver >= 8)
775 {
776 group_id = atoi(cmd->params[0]);
777 name = gaim_url_decode(cmd->params[1]);
778 }
779 else
780 {
781 num_groups = atoi(cmd->params[3]);
782 group_id = atoi(cmd->params[4]);
783 name = gaim_url_decode(cmd->params[5]);
784
785 if (num_groups == 0)
786 return;
787
788 if (!strcmp(name, "~"))
789 name = _("Buddies");
790 }
791
792 group = msn_group_new(session, group_id, name);
793
794 msn_groups_add(session->groups, group);
795
796 if ((g = gaim_find_group(name)) == NULL)
797 {
798 g = gaim_group_new(name);
799 gaim_blist_add_group(g, NULL);
800 }
801 }
802
803 static void
804 lst_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
805 {
806 MsnSession *session;
807 GaimAccount *account;
808 GaimConnection *gc;
809 const char *passport = NULL;
810 const char *friend = NULL;
811
812 session = cmdproc->session;
813 account = session->account;
814 gc = gaim_account_get_connection(account);
815
816 if (session->protocol_ver >= 8)
817 {
818 const char *group_nums;
819 int list_op;
820
821 passport = cmd->params[0];
822 friend = gaim_url_decode(cmd->params[1]);
823 list_op = atoi(cmd->params[2]);
824 group_nums = cmd->params[3];
825
826 if (list_op & MSN_LIST_FL_OP)
827 {
828 MsnUser *user;
829 char **c;
830 char **tokens;
831
832 user = msn_user_new(session, passport, friend);
833
834 /* Ensure we have a friendly name set. */
835 msn_user_set_name(user, friend);
836
837 tokens = g_strsplit((group_nums ? group_nums : ""), ",", -1);
838
839 gaim_debug_misc("msn", "Fetching group IDs from '%s'\n",
840 group_nums);
841 for (c = tokens; *c != NULL; c++)
842 {
843 gaim_debug_misc("msn", "Appending group ID %d\n", atoi(*c));
844 msn_user_add_group_id(user, atoi(*c));
845 }
846
847 g_strfreev(tokens);
848
849 session->lists.forward =
850 g_slist_append(session->lists.forward, user);
851
852 session->last_user_added = user;
853 }
854
855 if (list_op & MSN_LIST_AL_OP)
856 {
857 /* These are users who are allowed to see our status. */
858
859 if (g_slist_find_custom(account->deny, passport,
860 (GCompareFunc)strcmp))
861 {
862 gaim_privacy_deny_remove(gc->account, passport, TRUE);
863 }
864
865 gaim_privacy_permit_add(account, passport, TRUE);
866 }
867
868 if (list_op & MSN_LIST_BL_OP)
869 {
870 /* These are users who are not allowed to see our status. */
871 gaim_privacy_deny_add(account, passport, TRUE);
872 }
873
874 if (list_op & MSN_LIST_RL_OP)
875 {
876 /* These are users who have us on their contact list. */
877
878 gboolean new_entry = TRUE;
879
880 if (g_slist_find_custom(account->permit, passport,
881 (GCompareFunc)g_ascii_strcasecmp) ||
882 g_slist_find_custom(account->deny, passport,
883 (GCompareFunc)g_ascii_strcasecmp))
884 {
885 new_entry = FALSE;
886 }
887
888 if (new_entry)
889 {
890 MsnPermitAdd *pa;
891 char msg[MSN_BUF_LEN];
892
893 pa = g_new0(MsnPermitAdd, 1);
894 pa->user = msn_user_new(session, passport, friend);
895 pa->gc = gc;
896
897 /* Ensure we have a friendly name set. */
898 msn_user_set_name(pa->user, friend);
899
900 g_snprintf(msg, sizeof(msg),
901 _("The user %s (%s) wants to add you to their "
902 "buddy list."),
903 msn_user_get_passport(pa->user),
904 msn_user_get_name(pa->user));
905
906 gaim_request_action(gc, NULL, msg, NULL, 0, pa, 2,
907 _("Authorize"),
908 G_CALLBACK(msn_accept_add_cb),
909 _("Deny"),
910 G_CALLBACK(msn_cancel_add_cb));
911 }
912 }
913
914 session->num_users++;
915
916 if (session->num_users == session->total_users)
917 {
918 msn_user_set_buddy_icon(session->user,
919 gaim_account_get_buddy_icon(session->account));
920
921 if (!msn_session_change_status(session, "NLN"))
922 return;
923
924 gaim_connection_set_state(gc, GAIM_CONNECTED);
925 serv_finish_login(gc);
926
927 if (session->lists.allow == NULL)
928 session->lists.allow = g_slist_copy(account->permit);
929 else
930 session->lists.allow = g_slist_concat(session->lists.allow,
931 account->permit);
932
933 if (session->lists.block == NULL)
934 session->lists.block = g_slist_copy(account->permit);
935 else
936 session->lists.block = g_slist_concat(session->lists.block,
937 account->deny);
938
939 while (session->lists.forward != NULL)
940 {
941 MsnUser *user = session->lists.forward->data;
942 GSList *buddies;
943 GSList *sl;
944
945 session->lists.forward =
946 g_slist_remove(session->lists.forward, user);
947
948 add_buddy(cmdproc, user);
949
950 buddies = gaim_find_buddies(account,
951 msn_user_get_passport(user));
952
953 /* Find all occurrences of this buddy in the wrong place. */
954 for (sl = buddies; sl != NULL; sl = sl->next)
955 {
956 GaimBuddy *b = sl->data;
957
958 if (b->proto_data == NULL)
959 {
960 gaim_debug_warning("msn",
961 "Deleting misplaced user %s (%s) during sync "
962 "with server.\n",
963 b->name, gaim_find_buddys_group(b)->name);
964
965 gaim_blist_remove_buddy(b);
966 }
967 }
968
969 g_slist_free(buddies);
970 }
971
972 session->syncing_lists = FALSE;
973 session->lists_synced = TRUE;
974 }
975 }
976 else
977 {
978 const char *list_name;
979 int user_num;
980 int num_users;
981
982 list_name = cmd->params[1];
983 user_num = atoi(cmd->params[3]);
984 num_users = atoi(cmd->params[4]);
985
986 if (g_ascii_strcasecmp(list_name, "RL") &&
987 user_num == 0 && num_users == 0)
988 {
989 return; /* There are no users on this list. */
990 }
991
992 if (num_users > 0)
993 {
994 passport = cmd->params[5];
995 friend = gaim_url_decode(cmd->params[6]);
996 }
997
998 if (session->syncing_lists && session->lists_synced)
999 return;
1000
1001 if (!g_ascii_strcasecmp(list_name, "FL") && user_num != 0)
1002 {
1003 /* These are users on our contact list. */
1004 MsnUser *user;
1005
1006 user = msn_user_new(session, passport, friend);
1007
1008 if (cmd->param_count == 8)
1009 msn_user_add_group_id(user, atoi(cmd->params[7]));
1010
1011 session->lists.forward =
1012 g_slist_append(session->lists.forward, user);
1013 }
1014 else if (!g_ascii_strcasecmp(list_name, "AL") && user_num != 0)
1015 {
1016 /* These are users who are allowed to see our status. */
1017 if (g_slist_find_custom(gc->account->deny, passport,
1018 (GCompareFunc)strcmp))
1019 {
1020 gaim_debug(GAIM_DEBUG_INFO, "msn",
1021 "Moving user from deny list to permit: %s (%s)\n",
1022 passport, friend);
1023
1024 gaim_privacy_deny_remove(gc->account, passport, TRUE);
1025 }
1026
1027 gaim_privacy_permit_add(gc->account, passport, TRUE);
1028 }
1029 else if (!g_ascii_strcasecmp(list_name, "BL") && user_num != 0)
1030 {
1031 /* These are users who are not allowed to see our status. */
1032 gaim_privacy_deny_add(gc->account, passport, TRUE);
1033 }
1034 else if (!g_ascii_strcasecmp(list_name, "RL"))
1035 {
1036 /* These are users who have us on their contact list. */
1037 if (user_num > 0)
1038 {
1039 gboolean new_entry = TRUE;
1040
1041 if (g_slist_find_custom(gc->account->permit, passport,
1042 (GCompareFunc)g_ascii_strcasecmp))
1043 {
1044 new_entry = FALSE;
1045 }
1046
1047 if (g_slist_find_custom(gc->account->deny, passport,
1048 (GCompareFunc)g_ascii_strcasecmp))
1049 {
1050 new_entry = FALSE;
1051 }
1052
1053 if (new_entry)
1054 {
1055 MsnPermitAdd *pa;
1056 char msg[MSN_BUF_LEN];
1057
1058 gaim_debug(GAIM_DEBUG_WARNING, "msn",
1059 "Unresolved MSN RL entry: %s\n", passport);
1060
1061 pa = g_new0(MsnPermitAdd, 1);
1062 pa->user = msn_user_new(session, passport, friend);
1063 pa->gc = gc;
1064
1065 msn_user_set_name(pa->user, friend);
1066
1067 g_snprintf(msg, sizeof(msg),
1068 _("The user %s (%s) wants to add you to their "
1069 "buddy list."),
1070 msn_user_get_passport(pa->user),
1071 msn_user_get_name(pa->user));
1072
1073 gaim_request_action(gc, NULL, msg, NULL, 0, pa, 2,
1074 _("Authorize"),
1075 G_CALLBACK(msn_accept_add_cb),
1076 _("Deny"),
1077 G_CALLBACK(msn_cancel_add_cb));
1078 }
1079 }
1080
1081 if (user_num != num_users)
1082 return; /* This isn't the last one in the RL. */
1083
1084 /* Now we're at the last one, so we can do final work. */
1085 if (!session->lists_synced)
1086 {
1087 if (!msn_session_change_status(session, "NLN"))
1088 return;
1089
1090 gaim_connection_set_state(gc, GAIM_CONNECTED);
1091 serv_finish_login(gc);
1092 }
1093
1094 if (session->lists.allow == NULL)
1095 session->lists.allow = g_slist_copy(gc->account->permit);
1096 else
1097 session->lists.allow = g_slist_concat(session->lists.allow,
1098 gc->account->permit);
1099
1100 if (session->lists.block == NULL)
1101 session->lists.block = g_slist_copy(gc->account->deny);
1102 else
1103 session->lists.block = g_slist_concat(session->lists.block,
1104 gc->account->deny);
1105
1106 while (session->lists.forward != NULL)
1107 {
1108 MsnUser *user = session->lists.forward->data;
1109
1110 session->lists.forward =
1111 g_slist_remove(session->lists.forward, user);
1112
1113 add_buddy(cmdproc, user);
1114 }
1115
1116 session->syncing_lists = FALSE;
1117 session->lists_synced = TRUE;
1118 }
1119 }
1120 } 502 }
1121 503
1122 static void 504 static void
1123 nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 505 nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1124 { 506 {
1126 GaimConnection *gc; 508 GaimConnection *gc;
1127 MsnUser *user; 509 MsnUser *user;
1128 MsnObject *msnobj; 510 MsnObject *msnobj;
1129 const char *state; 511 const char *state;
1130 const char *passport; 512 const char *passport;
1131 const char *friend; 513 const char *friendly;
1132 int status = 0; 514 int status = 0;
1133 515
1134 session = cmdproc->session; 516 session = cmdproc->session;
1135 gc = session->account->gc; 517 gc = session->account->gc;
1136 518
1137 state = cmd->params[0]; 519 state = cmd->params[0];
1138 passport = cmd->params[1]; 520 passport = cmd->params[1];
1139 friend = gaim_url_decode(cmd->params[2]); 521 friendly = gaim_url_decode(cmd->params[2]);
1140 522
1141 user = msn_users_find_with_passport(session->users, passport); 523 user = msn_userlist_find_user(session->userlist, passport);
1142 524
1143 serv_got_alias(gc, passport, friend); 525 /* serv_got_nick(gc, passport, friendly); */
1144 526 serv_got_alias(gc, passport, friendly);
1145 msn_user_set_name(user, friend); 527
528 msn_user_set_friendly_name(user, friendly);
1146 529
1147 if (session->protocol_ver >= 9 && cmd->param_count == 5) 530 if (session->protocol_ver >= 9 && cmd->param_count == 5)
1148 { 531 {
1149 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[4])); 532 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[4]));
1150 msn_user_set_object(user, msnobj); 533 msn_user_set_object(user, msnobj);
1165 548
1166 serv_got_update(gc, passport, 1, 0, 0, 0, status); 549 serv_got_update(gc, passport, 1, 0, 0, 0, status);
1167 } 550 }
1168 551
1169 static void 552 static void
1170 not_cmd_post(MsnCmdProc *cmdproc, char *payload, size_t len) 553 chg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
554 {
555 char *state = cmd->params[1];
556 int state_id = 0;
557
558 if (!strcmp(state, "NLN"))
559 state_id = MSN_ONLINE;
560 else if (!strcmp(state, "BSY"))
561 state_id = MSN_BUSY;
562 else if (!strcmp(state, "IDL"))
563 state_id = MSN_IDLE;
564 else if (!strcmp(state, "BRB"))
565 state_id = MSN_BRB;
566 else if (!strcmp(state, "AWY"))
567 state_id = MSN_AWAY;
568 else if (!strcmp(state, "PHN"))
569 state_id = MSN_PHONE;
570 else if (!strcmp(state, "LUN"))
571 state_id = MSN_LUNCH;
572 else if (!strcmp(state, "HDN"))
573 state_id = MSN_HIDDEN;
574
575 cmdproc->session->state = state_id;
576 }
577
578
579 static void
580 not_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
1171 { 581 {
1172 #if 0 582 #if 0
583 MSN_SET_PARAMS("NOT %d\r\n%s", cmdproc->servconn->payload, payload);
1173 gaim_debug_misc("msn", "Notification: {%s}\n", payload); 584 gaim_debug_misc("msn", "Notification: {%s}\n", payload);
1174 #endif 585 #endif
1175 } 586 }
1176 587
1177 static void 588 static void
1178 not_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 589 not_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1179 { 590 {
1180 cmdproc->servconn->payload_len = atoi(cmd->params[0]); 591 cmdproc->servconn->payload_len = atoi(cmd->params[0]);
1181 cmdproc->payload_cb = not_cmd_post; 592 cmdproc->last_cmd->payload_cb = not_cmd_post;
1182 }
1183
1184 static void
1185 prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1186 {
1187 MsnSession *session;
1188 const char *type, *value;
1189
1190 session = cmdproc->session;
1191
1192 type = cmd->params[2];
1193 value = cmd->params[3];
1194
1195 if (cmd->param_count == 4)
1196 {
1197 if (!strcmp(type, "PHH"))
1198 msn_user_set_home_phone(session->user, gaim_url_decode(value));
1199 else if (!strcmp(type, "PHW"))
1200 msn_user_set_work_phone(session->user, gaim_url_decode(value));
1201 else if (!strcmp(type, "PHM"))
1202 msn_user_set_mobile_phone(session->user, gaim_url_decode(value));
1203 }
1204 } 593 }
1205 594
1206 static void 595 static void
1207 rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 596 rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1208 { 597 {
598 /* TODO: This might be with us too */
599
1209 MsnSession *session; 600 MsnSession *session;
1210 GaimConnection *gc; 601 GaimConnection *gc;
1211 const char *friend; 602 const char *friendly;
1212 603
1213 session = cmdproc->session; 604 session = cmdproc->session;
1214 gc = session->account->gc; 605 gc = session->account->gc;
1215 friend = gaim_url_decode(cmd->params[3]); 606 friendly = gaim_url_decode(cmd->params[3]);
1216 607
1217 gaim_connection_set_display_name(gc, friend); 608 gaim_connection_set_display_name(gc, friendly);
1218 } 609 }
1219 610
1220 static void 611 static void
1221 reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 612 reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1222 { 613 {
1223 MsnSession *session; 614 MsnSession *session;
1224 MsnGroup *group;
1225 int group_id; 615 int group_id;
1226 const char *group_name; 616 const char *group_name;
1227 617
1228 session = cmdproc->session; 618 session = cmdproc->session;
1229 group_id = atoi(cmd->params[2]); 619 group_id = atoi(cmd->params[2]);
1230
1231 group_name = gaim_url_decode(cmd->params[3]); 620 group_name = gaim_url_decode(cmd->params[3]);
1232 621
1233 group = msn_groups_find_with_id(session->groups, group_id); 622 msn_userlist_rename_group_id(session->userlist, group_id, group_name);
1234
1235 gaim_debug(GAIM_DEBUG_INFO, "msn", "Renamed group %s to %s\n",
1236 msn_group_get_name(group), group_name);
1237
1238 if (group != NULL)
1239 msn_group_set_name(group, group_name);
1240 } 623 }
1241 624
1242 static void 625 static void
1243 rem_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 626 rem_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1244 { 627 {
1245 MsnSession *session; 628 MsnSession *session;
629 MsnUser *user;
630 const char *list;
1246 const char *passport; 631 const char *passport;
1247 632 MsnListId list_id;
1248 session = cmdproc->session; 633 int group_id;
634
635 session = cmdproc->session;
636 list = cmd->params[1];
1249 passport = cmd->params[3]; 637 passport = cmd->params[3];
638 user = msn_userlist_find_user(session->userlist, passport);
639
640 g_return_if_fail(user != NULL);
641
642 list_id = msn_get_list_id(list);
1250 643
1251 if (cmd->param_count == 5) 644 if (cmd->param_count == 5)
1252 { 645 group_id = atoi(cmd->params[4]);
1253 MsnUser *user; 646 else
1254 int group_id = atoi(cmd->params[4]); 647 group_id = -1;
1255 648
1256 user = msn_users_find_with_passport(session->users, passport); 649 msn_got_rem_user(session, user, list_id, group_id);
1257
1258 msn_user_remove_group_id(user, group_id);
1259 }
1260
1261 /* I hate this. */
1262 /* shx: it won't be here for long. */
1263 if (session->moving_buddy)
1264 {
1265 MsnGroup *group, *old_group;
1266 const char *friendly;
1267
1268 group = msn_groups_find_with_name(session->groups,
1269 session->dest_group_name);
1270
1271 old_group = session->old_group;
1272
1273 session->moving_buddy = FALSE;
1274 session->old_group = NULL;
1275
1276 if (group == NULL)
1277 {
1278 gaim_debug_error("msn",
1279 "Still don't have a group ID for %s while moving %s!\n",
1280 session->dest_group_name, passport);
1281
1282 g_free(session->dest_group_name);
1283 session->dest_group_name = NULL;
1284
1285 return;
1286 }
1287
1288 g_free(session->dest_group_name);
1289 session->dest_group_name = NULL;
1290
1291 if ((friendly = msn_user_get_name(session->moving_user)) == NULL)
1292 friendly = passport;
1293
1294 msn_cmdproc_send(cmdproc, "ADD", "FL %s %s %d",
1295 passport, gaim_url_encode(friendly),
1296 msn_group_get_id(group));
1297
1298 if (cmdproc->error)
1299 return;
1300
1301 if (old_group != NULL)
1302 msn_group_remove_user(old_group, session->moving_user);
1303
1304 msn_user_unref(session->moving_user);
1305
1306 session->moving_user = NULL;
1307
1308 if (old_group != NULL &&
1309 msn_users_get_count(msn_group_get_users(old_group)) <= 0)
1310 {
1311 msn_cmdproc_send(cmdproc, "RMG", "%s", "%d",
1312 msn_group_get_id(old_group));
1313 }
1314 }
1315 } 650 }
1316 651
1317 static void 652 static void
1318 rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 653 rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1319 { 654 {
1320 MsnSession *session; 655 MsnSession *session;
1321 MsnGroup *group; 656 int group_id;
1322 657
1323 session = cmdproc->session; 658 session = cmdproc->session;
1324 group = msn_groups_find_with_id(session->groups, atoi(cmd->params[2])); 659 group_id = atoi(cmd->params[2]);
1325 660
1326 if (group != NULL) 661 msn_userlist_remove_group_id(session->userlist, group_id);
1327 msn_groups_remove(session->groups, group);
1328 } 662 }
1329 663
1330 static void 664 static void
1331 syn_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 665 syn_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1332 { 666 {
1333 MsnSession *session; 667 MsnSession *session;
1334 GaimConnection *gc; 668 GaimConnection *gc;
669 int total_users;
1335 670
1336 session = cmdproc->session; 671 session = cmdproc->session;
1337 gc = gaim_account_get_connection(session->account); 672 gc = gaim_account_get_connection(session->account);
1338 673 total_users = atoi(cmd->params[2]);
1339 if (session->protocol_ver >= 8) 674
1340 { 675 if (total_users == 0)
1341 if (cmd->param_count == 2) 676 {
1342 { 677 gaim_connection_set_state(gc, GAIM_CONNECTED);
1343 char *buf; 678 serv_finish_login(gc);
1344 679 }
1345 /* 680 else
1346 * This can happen if we sent a SYN with an up-to-date 681 {
1347 * buddy list revision, but we send 0 to get a full list. 682 /* syn_table */
1348 * So, error out. 683 MsnSync *sync;
1349 */ 684
1350 buf = g_strdup_printf( 685 sync = msn_sync_new(session);
1351 _("Your MSN buddy list for %s is temporarily unavailable. " 686 sync->total_users = total_users;
1352 "Please wait and try again."), 687 sync->old_cbs_table = cmdproc->cbs_table;
1353 gaim_account_get_username(session->account)); 688
1354 689 session->sync = sync;
1355 gaim_connection_error(gc, buf); 690 cmdproc->cbs_table = sync->cbs_table;
1356
1357 g_free(buf);
1358
1359 return;
1360 }
1361
1362 session->total_users = atoi(cmd->params[2]);
1363 session->total_groups = atoi(cmd->params[3]);
1364
1365 if (session->total_users == 0)
1366 {
1367 gaim_connection_set_state(gc, GAIM_CONNECTED);
1368 serv_finish_login(gc);
1369
1370 session->syncing_lists = FALSE;
1371 session->lists_synced = TRUE;
1372 }
1373 } 691 }
1374 } 692 }
1375 693
1376 /************************************************************************** 694 /**************************************************************************
1377 * Misc commands 695 * Misc commands
1478 * Renaming file with .html extension, so that the 796 * Renaming file with .html extension, so that the
1479 * win32 open_url will work. 797 * win32 open_url will work.
1480 */ 798 */
1481 char *tmp; 799 char *tmp;
1482 800
1483 if ((tmp = g_strdup_printf("%s.html", session->passport_info.file)) != NULL) 801 if ((tmp =
802 g_strdup_printf("%s.html", session->passport_info.file))
803 != NULL)
1484 { 804 {
1485 if (rename(session->passport_info.file, tmp) == 0) 805 if (rename(session->passport_info.file, tmp) == 0)
1486 { 806 {
1487 g_free(session->passport_info.file); 807 g_free(session->passport_info.file);
1488 session->passport_info.file = tmp; 808 session->passport_info.file = tmp;
1499 static void 819 static void
1500 rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 820 rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1501 { 821 {
1502 MsnSession *session; 822 MsnSession *session;
1503 MsnSwitchBoard *swboard; 823 MsnSwitchBoard *swboard;
1504 MsnUser *user;
1505 const char *session_id; 824 const char *session_id;
1506 char *host, *c; 825 char *host;
1507 int port; 826 int port;
1508 827
1509 session = cmdproc->session; 828 session = cmdproc->session;
1510 session_id = cmd->params[0]; 829 session_id = cmd->params[0];
1511 830
1512 host = g_strdup(cmd->params[1]); 831 msn_parse_socket(cmd->params[1], &host, &port);
1513
1514 if ((c = strchr(host, ':')) != NULL)
1515 {
1516 *c = '\0';
1517 port = atoi(c + 1);
1518 }
1519 else
1520 port = 1863;
1521 832
1522 if (session->http_method) 833 if (session->http_method)
1523 port = 80; 834 port = 80;
1524 835
1525 swboard = msn_switchboard_new(session); 836 swboard = msn_switchboard_new(session);
1526
1527 user = msn_user_new(session, cmd->params[4], NULL);
1528 837
1529 msn_switchboard_set_invited(swboard, TRUE); 838 msn_switchboard_set_invited(swboard, TRUE);
1530 msn_switchboard_set_session_id(swboard, cmd->params[0]); 839 msn_switchboard_set_session_id(swboard, cmd->params[0]);
1531 msn_switchboard_set_auth_key(swboard, cmd->params[3]); 840 msn_switchboard_set_auth_key(swboard, cmd->params[3]);
1532 msn_switchboard_set_user(swboard, user); 841 swboard->im_user = g_strdup(cmd->params[4]);
1533 842 /* msn_switchboard_add_user(swboard, cmd->params[4]); */
1534 if (!msn_switchboard_connect(swboard, host, port)) 843
1535 { 844 msn_switchboard_connect(swboard, host, port);
1536 gaim_debug_error("msn", 845
1537 "Unable to connect to switchboard on %s, port %d\n", 846 g_free(host);
1538 host, port); 847 }
1539 848
1540 g_free(host); 849 static void
1541 850 xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
851 {
852 char *host;
853 int port;
854
855 if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
856 {
857 msn_cmdproc_show_error(cmdproc, MSN_ERROR_MISC);
1542 return; 858 return;
1543 } 859 }
1544 860
1545 g_free(host); 861 msn_parse_socket(cmd->params[2], &host, &port);
1546 }
1547
1548 static void
1549 xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1550 {
1551 MsnSession *session;
1552 MsnSwitchBoard *swboard;
1553 GaimConnection *gc;
1554 char *host;
1555 char *c;
1556 int port;
1557
1558 session = cmdproc->session;
1559 gc = session->account->gc;
1560
1561 if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
1562 {
1563 gaim_connection_error(gc, _("Got invalid XFR"));
1564
1565 return;
1566 }
1567
1568 host = g_strdup(cmd->params[2]);
1569
1570 if ((c = strchr(host, ':')) != NULL)
1571 {
1572 *c = '\0';
1573 port = atoi(c + 1);
1574 }
1575 else
1576 port = 1863;
1577 862
1578 if (!strcmp(cmd->params[1], "SB")) 863 if (!strcmp(cmd->params[1], "SB"))
1579 { 864 {
1580 swboard = msn_session_find_unused_switch(session); 865 gaim_debug_error("msn", "This shouldn't be handled here.\n");
1581 866 #if 0
1582 if (swboard == NULL) 867 swboard = cmd->trans->data;
868
869 if (swboard != NULL)
1583 { 870 {
1584 gaim_debug_error("msn", 871 msn_switchboard_set_auth_key(swboard, cmd->params[4]);
1585 "Received an XFR SB request when there's no unused " 872
1586 "switchboards!\n"); 873 if (session->http_method)
1587 return; 874 port = 80;
875
876 msn_switchboard_connect(swboard, host, port);
1588 } 877 }
1589 878 #endif
1590 msn_switchboard_set_auth_key(swboard, cmd->params[4]);
1591
1592 if (session->http_method)
1593 port = 80;
1594
1595 if (!msn_switchboard_connect(swboard, host, port))
1596 {
1597 gaim_debug_error("msn",
1598 "Unable to connect to switchboard on %s, port %d\n",
1599 host, port);
1600
1601 g_free(host);
1602
1603 return;
1604 }
1605 } 879 }
1606 else if (!strcmp(cmd->params[1], "NS")) 880 else if (!strcmp(cmd->params[1], "NS"))
1607 { 881 {
1608 if (!msn_notification_connect(session->notification_conn, host, 882 MsnSession *session;
1609 port)) 883
1610 { 884 session = cmdproc->session;
1611 gaim_connection_error(gc, _("Unable to transfer to " 885
1612 "notification server")); 886 msn_notification_connect(session->notification, host, port);
1613
1614 g_free(host);
1615
1616 return;
1617 }
1618 } 887 }
1619 888
1620 g_free(host); 889 g_free(host);
1621 } 890 }
1622 891
1626 static void 895 static void
1627 profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg) 896 profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1628 { 897 {
1629 MsnSession *session; 898 MsnSession *session;
1630 const char *value; 899 const char *value;
1631 const char *passport; 900
1632 901 session = cmdproc->session;
1633 session = cmdproc->session; 902
1634 passport = msg->passport; 903 if (strcmp(msg->remote_user, "Hotmail"))
1635
1636 if (strcmp(passport, "Hotmail"))
1637 {
1638 /* This isn't an official message. */ 904 /* This isn't an official message. */
1639 return; 905 return;
1640 }
1641 906
1642 if ((value = msn_message_get_attr(msg, "kv")) != NULL) 907 if ((value = msn_message_get_attr(msg, "kv")) != NULL)
1643 session->passport_info.kv = g_strdup(value); 908 session->passport_info.kv = g_strdup(value);
1644 909
1645 if ((value = msn_message_get_attr(msg, "sid")) != NULL) 910 if ((value = msn_message_get_attr(msg, "sid")) != NULL)
1660 { 925 {
1661 MsnSession *session; 926 MsnSession *session;
1662 GaimConnection *gc; 927 GaimConnection *gc;
1663 GHashTable *table; 928 GHashTable *table;
1664 const char *unread; 929 const char *unread;
1665 const char *passport;
1666 930
1667 session = cmdproc->session; 931 session = cmdproc->session;
1668 gc = session->account->gc; 932 gc = session->account->gc;
1669 passport = msg->passport; 933
1670 934 if (strcmp(msg->remote_user, "Hotmail"))
1671 if (strcmp(passport, "Hotmail"))
1672 {
1673 /* This isn't an official message. */ 935 /* This isn't an official message. */
1674 return; 936 return;
1675 }
1676 937
1677 if (!gaim_account_get_check_mail(session->account)) 938 if (!gaim_account_get_check_mail(session->account))
1678 return; 939 return;
1679 940
1680 if (session->passport_info.file == NULL) 941 if (session->passport_info.file == NULL)
1681 { 942 {
1682 msn_cmdproc_send(cmdproc, "URL", "%s", "INBOX"); 943 MsnTransaction *trans;
1683 944 trans = msn_transaction_new("URL", "%s", "INBOX");
1684 msn_cmdproc_queue_message(cmdproc, "URL", msg); 945 msn_transaction_queue_cmd(trans, msg->cmd);
946
947 msn_cmdproc_send_trans(cmdproc, trans);
1685 948
1686 return; 949 return;
1687 } 950 }
1688 951
1689 table = msn_message_get_hashtable_from_body(msg); 952 table = msn_message_get_hashtable_from_body(msg);
1692 955
1693 if (unread != NULL) 956 if (unread != NULL)
1694 { 957 {
1695 int count = atoi(unread); 958 int count = atoi(unread);
1696 959
1697 if (count != 0) 960 if (count > 0)
1698 { 961 {
1699 const char *passport; 962 const char *passport;
1700 const char *file; 963 const char *url;
1701 gchar *url;
1702 964
1703 passport = msn_user_get_passport(session->user); 965 passport = msn_user_get_passport(session->user);
1704 file = session->passport_info.file; 966 url = session->passport_info.file;
1705 while (*file && *file == '/') 967
1706 ++file; 968 gaim_notify_emails(gc, atoi(unread), FALSE, NULL, NULL,
1707 url = g_strconcat ("file:///", file, 0); 969 &passport, &url, NULL, NULL);
1708 gaim_notify_emails(gc, count, FALSE, NULL, NULL,
1709 &passport, (const char **)&url, NULL, NULL);
1710 g_free (url);
1711 } 970 }
1712 } 971 }
1713 972
1714 g_hash_table_destroy(table); 973 g_hash_table_destroy(table);
1715 } 974 }
1719 { 978 {
1720 MsnSession *session; 979 MsnSession *session;
1721 GaimConnection *gc; 980 GaimConnection *gc;
1722 GHashTable *table; 981 GHashTable *table;
1723 char *from, *subject, *tmp; 982 char *from, *subject, *tmp;
1724 const char *passport;
1725 983
1726 session = cmdproc->session; 984 session = cmdproc->session;
1727 gc = session->account->gc; 985 gc = session->account->gc;
1728 passport = msg->passport; 986
1729 987 if (strcmp(msg->remote_user, "Hotmail"))
1730 from = subject = NULL;
1731
1732 if (strcmp(passport, "Hotmail"))
1733 {
1734 /* This isn't an official message. */ 988 /* This isn't an official message. */
1735 return; 989 return;
1736 }
1737 990
1738 if (!gaim_account_get_check_mail(session->account)) 991 if (!gaim_account_get_check_mail(session->account))
1739 return; 992 return;
1740 993
1741 if (session->passport_info.file == NULL) 994 if (session->passport_info.file == NULL)
1742 { 995 {
1743 msn_cmdproc_send(cmdproc, "URL", "%s", "INBOX"); 996 MsnTransaction *trans;
1744 997 trans = msn_transaction_new("URL", "%s", "INBOX");
1745 msn_cmdproc_queue_message(cmdproc, "URL", msg); 998 msn_transaction_queue_cmd(trans, msg->cmd);
999
1000 msn_cmdproc_send_trans(cmdproc, trans);
1746 1001
1747 return; 1002 return;
1748 } 1003 }
1749 1004
1750 table = msn_message_get_hashtable_from_body(msg); 1005 table = msn_message_get_hashtable_from_body(msg);
1006
1007 from = subject = NULL;
1751 1008
1752 tmp = g_hash_table_lookup(table, "From"); 1009 tmp = g_hash_table_lookup(table, "From");
1753 if (tmp != NULL) 1010 if (tmp != NULL)
1754 from = gaim_mime_decode_field(tmp); 1011 from = gaim_mime_decode_field(tmp);
1755 1012
1775 static void 1032 static void
1776 system_msg(MsnCmdProc *cmdproc, MsnMessage *msg) 1033 system_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1777 { 1034 {
1778 GHashTable *table; 1035 GHashTable *table;
1779 const char *type_s; 1036 const char *type_s;
1780 const char *passport; 1037
1781 1038 if (strcmp(msg->remote_user, "Hotmail"))
1782 passport = msg->passport;
1783
1784 if (strcmp(passport, "Hotmail"))
1785 {
1786 /* This isn't an official message. */ 1039 /* This isn't an official message. */
1787 return; 1040 return;
1788 }
1789 1041
1790 table = msn_message_get_hashtable_from_body(msg); 1042 table = msn_message_get_hashtable_from_body(msg);
1791 1043
1792 if ((type_s = g_hash_table_lookup(table, "Type")) != NULL) 1044 if ((type_s = g_hash_table_lookup(table, "Type")) != NULL)
1793 { 1045 {
1822 } 1074 }
1823 1075
1824 g_hash_table_destroy(table); 1076 g_hash_table_destroy(table);
1825 } 1077 }
1826 1078
1827 static gboolean 1079 static void
1828 connect_cb(MsnServConn *servconn) 1080 connect_cb(MsnServConn *servconn)
1829 { 1081 {
1082 MsnNotification *notification;
1830 MsnCmdProc *cmdproc; 1083 MsnCmdProc *cmdproc;
1831 MsnSession *session; 1084 MsnSession *session;
1832 GaimAccount *account; 1085 GaimAccount *account;
1833 GaimConnection *gc; 1086 GaimConnection *gc;
1834 char **a, **c, *vers; 1087 char **a, **c, *vers;
1835 size_t i; 1088 int i;
1836 1089
1837 g_return_val_if_fail(servconn != NULL, FALSE); 1090 g_return_if_fail(servconn != NULL);
1838 1091
1092 notification = servconn->data;
1839 cmdproc = servconn->cmdproc; 1093 cmdproc = servconn->cmdproc;
1840 session = servconn->session; 1094 session = servconn->session;
1841 account = session->account; 1095 account = session->account;
1842 gc = gaim_account_get_connection(account); 1096 gc = gaim_account_get_connection(account);
1843 1097
1855 1109
1856 g_strfreev(a); 1110 g_strfreev(a);
1857 g_free(vers); 1111 g_free(vers);
1858 1112
1859 if (cmdproc->error) 1113 if (cmdproc->error)
1860 return FALSE; 1114 return;
1861 1115
1862 session->user = msn_user_new(session, 1116 session->user = msn_user_new(session->userlist,
1863 gaim_account_get_username(account), NULL); 1117 gaim_account_get_username(account), NULL);
1864 1118
1119 #if 0
1865 gaim_connection_update_progress(gc, _("Syncing with server"), 1120 gaim_connection_update_progress(gc, _("Syncing with server"),
1866 4, MSN_CONNECT_STEPS); 1121 4, MSN_CONNECT_STEPS);
1867 1122 #endif
1868 return TRUE; 1123 }
1124
1125 void
1126 msn_notification_add_buddy(MsnNotification *notification, const char *list,
1127 const char *who, const char *store_name,
1128 int group_id)
1129 {
1130 MsnCmdProc *cmdproc;
1131 cmdproc = notification->servconn->cmdproc;
1132
1133 if (group_id >= 0)
1134 {
1135 msn_cmdproc_send(cmdproc, "ADD", "%s %s %s %d", list, who,
1136 store_name, group_id);
1137 }
1138 else
1139 {
1140 msn_cmdproc_send(cmdproc, "ADD", "%s %s %s", list, who,
1141 store_name);
1142 }
1143 }
1144
1145 void
1146 msn_notification_rem_buddy(MsnNotification *notification, const char *list,
1147 const char *who, int group_id)
1148 {
1149 MsnCmdProc *cmdproc;
1150 cmdproc = notification->servconn->cmdproc;
1151
1152 if (group_id >= 0)
1153 {
1154 msn_cmdproc_send(cmdproc, "REM", "%s %s %d", list, who, group_id);
1155 }
1156 else
1157 {
1158 msn_cmdproc_send(cmdproc, "REM", "%s %s", list, who);
1159 }
1869 } 1160 }
1870 1161
1871 void 1162 void
1872 msn_notification_init(void) 1163 msn_notification_init(void)
1873 { 1164 {
1165 /* TODO: check prp, blp */
1166
1874 cbs_table = msn_table_new(); 1167 cbs_table = msn_table_new();
1875 1168
1876 /* Register the command callbacks. */
1877
1878 /* Syncing */
1879 msn_table_add_cmd(cbs_table, NULL, "GTC", NULL);
1880 msn_table_add_cmd(cbs_table, NULL, "BLP", blp_cmd);
1881 msn_table_add_cmd(cbs_table, NULL, "PRP", prp_cmd);
1882 msn_table_add_cmd(cbs_table, NULL, "LSG", lsg_cmd);
1883 msn_table_add_cmd(cbs_table, NULL, "LST", lst_cmd);
1884 msn_table_add_cmd(cbs_table, NULL, "BPR", bpr_cmd);
1885
1886 /* Syncronous */ 1169 /* Syncronous */
1887 /* msn_table_add_cmd(cbs_table, "CHG", "CHG", chg_cmd); */ 1170 msn_table_add_cmd(cbs_table, "CHG", "CHG", chg_cmd);
1888 msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd); 1171 msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd);
1889 msn_table_add_cmd(cbs_table, "ADD", "ADD", add_cmd); 1172 msn_table_add_cmd(cbs_table, "ADD", "ADD", add_cmd);
1890 msn_table_add_cmd(cbs_table, "ADD", "ILN", iln_cmd); 1173 msn_table_add_cmd(cbs_table, "ADD", "ILN", iln_cmd);
1891 msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd); 1174 msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd);
1892 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); 1175 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd);
1919 msn_table_add_cmd(cbs_table, NULL, "ILN", iln_cmd); 1202 msn_table_add_cmd(cbs_table, NULL, "ILN", iln_cmd);
1920 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); 1203 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd);
1921 msn_table_add_cmd(cbs_table, NULL, "RNG", rng_cmd); 1204 msn_table_add_cmd(cbs_table, NULL, "RNG", rng_cmd);
1922 1205
1923 msn_table_add_cmd(cbs_table, NULL, "URL", url_cmd); 1206 msn_table_add_cmd(cbs_table, NULL, "URL", url_cmd);
1207
1208 /* msn_table_add_cmd(cbs_table, NULL, "XFR", xfr_cmd); */
1924 1209
1925 msn_table_add_error(cbs_table, "ADD", add_error); 1210 msn_table_add_error(cbs_table, "ADD", add_error);
1926 1211 /* msn_table_add_error(cbs_table, "REA", rea_error); */
1927 /* Register the message type callbacks. */ 1212
1928 msn_table_add_msg_type(cbs_table, 1213 msn_table_add_msg_type(cbs_table,
1929 "text/x-msmsgsprofile", 1214 "text/x-msmsgsprofile",
1930 profile_msg); 1215 profile_msg);
1931 msn_table_add_msg_type(cbs_table, 1216 msn_table_add_msg_type(cbs_table,
1932 "text/x-msmsgsinitialemailnotification", 1217 "text/x-msmsgsinitialemailnotification",
1943 msn_notification_end(void) 1228 msn_notification_end(void)
1944 { 1229 {
1945 msn_table_destroy(cbs_table); 1230 msn_table_destroy(cbs_table);
1946 } 1231 }
1947 1232
1948 MsnServConn * 1233 MsnNotification *
1949 msn_notification_new(MsnSession *session) 1234 msn_notification_new(MsnSession *session)
1950 { 1235 {
1951 MsnServConn *notification; 1236 MsnNotification *notification;
1952 MsnCmdProc *cmdproc; 1237 MsnServConn *servconn;
1953 1238
1954 notification = msn_servconn_new(session, MSN_SERVER_NS); 1239 g_return_val_if_fail(session != NULL, NULL);
1955 cmdproc = notification->cmdproc; 1240
1956 1241 notification = g_new0(MsnNotification, 1);
1957 msn_servconn_set_connect_cb(notification, connect_cb); 1242
1243 notification->session = session;
1244 notification->servconn = servconn = msn_servconn_new(session, MSN_SERVER_NS);
1245 notification->cmdproc = servconn->cmdproc;
1246 msn_servconn_set_connect_cb(servconn, connect_cb);
1958 1247
1959 if (session->http_method) 1248 if (session->http_method)
1960 notification->http_data->server_type = "NS"; 1249 servconn->http_data->server_type = "NS";
1961 1250
1962 cmdproc->cbs_table = cbs_table; 1251 servconn->cmdproc->cbs_table = cbs_table;
1963 1252
1964 return notification; 1253 return notification;
1965 } 1254 }
1966 1255
1256 void
1257 msn_notification_destroy(MsnNotification *notification)
1258 {
1259 msn_servconn_destroy(notification->servconn);
1260
1261 g_free(notification);
1262 }
1263
1967 gboolean 1264 gboolean
1968 msn_notification_connect(MsnServConn *notification, const char *host, int port) 1265 msn_notification_connect(MsnNotification *notification, const char *host, int port)
1969 { 1266 {
1267 MsnServConn *servconn;
1268
1970 g_return_val_if_fail(notification != NULL, FALSE); 1269 g_return_val_if_fail(notification != NULL, FALSE);
1971 1270
1972 return msn_servconn_connect(notification, host, port); 1271 servconn = notification->servconn;
1973 } 1272
1273 return (notification->in_use = msn_servconn_connect(servconn, host, port));
1274 }
1275
1276 void
1277 msn_notification_disconnect(MsnNotification *notification)
1278 {
1279 g_return_if_fail(notification != NULL);
1280
1281 notification->in_use = FALSE;
1282
1283 if (notification->servconn->connected)
1284 msn_servconn_disconnect(notification->servconn);
1285 }