comparison src/protocols/msn/notification.c @ 8808:bbd8cdaf0ad5

[gaim-migrate @ 9570] A massive patch by shx to reorganize MSN some more and add command processor support. This allows us to do cool things like produce more detailed error messages. For example, the Invalid Username dialog now shows the username of the invalid user. I modified the aforementioned dialog so it'll look a little nicer looking, and also mention the account this happened on. It also removes the user from your blist, as there's no point to keeping the user on there. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sun, 25 Apr 2004 22:02:06 +0000
parents 06dd136238ab
children c313e3b1f2c0
comparison
equal deleted inserted replaced
8807:482fc53c969d 8808:bbd8cdaf0ad5
30 GaimConnection *gc; 30 GaimConnection *gc;
31 MsnUser *user; 31 MsnUser *user;
32 32
33 } MsnPermitAdd; 33 } MsnPermitAdd;
34 34
35 static GHashTable *notification_commands = NULL; 35 static MsnTable *cbs_table = NULL;
36 static GHashTable *notification_msg_types = NULL;
37 36
38 /************************************************************************** 37 /**************************************************************************
39 * Utility functions 38 * Utility functions
40 **************************************************************************/ 39 **************************************************************************/
41 static gboolean 40 static gboolean
42 add_buddy(MsnServConn *servconn, MsnUser *user) 41 add_buddy(MsnCmdProc *cmdproc, MsnUser *user)
43 { 42 {
44 MsnSession *session = servconn->session; 43 MsnSession *session;
45 GaimAccount *account = session->account; 44 GaimAccount *account;
46 GaimConnection *gc = gaim_account_get_connection(account); 45 GaimConnection *gc;
47 GaimBuddy *b; 46 GaimBuddy *b;
48 MsnGroup *group = NULL; 47 MsnGroup *group = NULL;
49 GaimGroup *g = NULL; 48 GaimGroup *g = NULL;
50 GList *l, *l2; 49 GList *l, *l2;
51 GSList *sl; 50 GSList *sl;
52 GSList *buddies; 51 GSList *buddies;
53 52
53 session = cmdproc->session;
54 account = session->account;
55 gc = gaim_account_get_connection(account);
54 buddies = gaim_find_buddies(account, msn_user_get_passport(user)); 56 buddies = gaim_find_buddies(account, msn_user_get_passport(user));
55 57
56 for (l = msn_user_get_group_ids(user); l != NULL; l = l->next) 58 for (l = msn_user_get_group_ids(user); l != NULL; l = l->next)
57 { 59 {
58 int group_id = GPOINTER_TO_INT(l->data); 60 int group_id = GPOINTER_TO_INT(l->data);
132 * Callbacks 134 * Callbacks
133 **************************************************************************/ 135 **************************************************************************/
134 static void 136 static void
135 msn_accept_add_cb(MsnPermitAdd *pa) 137 msn_accept_add_cb(MsnPermitAdd *pa)
136 { 138 {
137 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) { 139 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL)
138 MsnSession *session = pa->gc->proto_data; 140 {
139 char outparams[MSN_BUF_LEN]; 141 MsnSession *session;
140 142 MsnCmdProc *cmdproc;
141 g_snprintf(outparams, sizeof(outparams), "AL %s %s", 143
142 msn_user_get_passport(pa->user), 144 session = pa->gc->proto_data;
143 gaim_url_encode(msn_user_get_name(pa->user))); 145 cmdproc = session->notification_conn->cmdproc;
144 146
145 if (msn_servconn_send_command(session->notification_conn, 147 msn_cmdproc_send(cmdproc, "ADD", "AL %s %s",
146 "ADD", outparams) <= 0) { 148 msn_user_get_passport(pa->user),
147 gaim_connection_error(pa->gc, _("Write error")); 149 gaim_url_encode(msn_user_get_name(pa->user)));
150
151 if (cmdproc->error)
148 return; 152 return;
149 }
150 153
151 gaim_privacy_permit_add(pa->gc->account, 154 gaim_privacy_permit_add(pa->gc->account,
152 msn_user_get_passport(pa->user), TRUE); 155 msn_user_get_passport(pa->user), TRUE);
153 gaim_account_notify_added(pa->gc->account, NULL, 156 gaim_account_notify_added(pa->gc->account, NULL,
154 msn_user_get_passport(pa->user), 157 msn_user_get_passport(pa->user),
160 } 163 }
161 164
162 static void 165 static void
163 msn_cancel_add_cb(MsnPermitAdd *pa) 166 msn_cancel_add_cb(MsnPermitAdd *pa)
164 { 167 {
165 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) { 168 if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL)
166 MsnSession *session = pa->gc->proto_data; 169 {
167 char outparams[MSN_BUF_LEN]; 170 MsnSession *session;
168 171 MsnCmdProc *cmdproc;
169 g_snprintf(outparams, sizeof(outparams), "BL %s %s", 172
170 msn_user_get_passport(pa->user), 173 session = pa->gc->proto_data;
171 gaim_url_encode(msn_user_get_name(pa->user))); 174 cmdproc = session->notification_conn->cmdproc;
172 175
173 if (msn_servconn_send_command(session->notification_conn, 176 msn_cmdproc_send(cmdproc, "ADD", "BL %s %s",
174 "ADD", outparams) <= 0) { 177 msn_user_get_passport(pa->user),
175 gaim_connection_error(pa->gc, _("Write error")); 178 gaim_url_encode(msn_user_get_name(pa->user)));
179
180 if (cmdproc->error)
176 return; 181 return;
177 }
178 182
179 gaim_privacy_deny_add(pa->gc->account, 183 gaim_privacy_deny_add(pa->gc->account,
180 msn_user_get_passport(pa->user), TRUE); 184 msn_user_get_passport(pa->user), TRUE);
181 } 185 }
182 186
183 msn_user_destroy(pa->user); 187 msn_user_destroy(pa->user);
184 g_free(pa); 188 g_free(pa);
185 } 189 }
186
187 /**************************************************************************
188 * Catch-all commands
189 **************************************************************************/
190 static gboolean
191 blank_cmd(MsnServConn *servconn, const char *command, const char **params,
192 size_t param_count)
193 {
194 return TRUE;
195 }
196
197 static gboolean
198 unknown_cmd(MsnServConn *servconn, const char *command, const char **params,
199 size_t param_count)
200 {
201 int errnum = 0;
202
203 if (isdigit(*command)) {
204 errnum = atoi(command);
205
206 if (errnum == 225) {
207 /*
208 * Ignore this. It happens as a result of moving a buddy from
209 * one group that isn't on the server to another that is.
210 * The user doesn't care if the old group was there or not.
211 */
212 return TRUE;
213 }
214 }
215
216 msn_error_handle(servconn->session, errnum);
217
218 return TRUE;
219 }
220
221 190
222 /************************************************************************** 191 /**************************************************************************
223 * Login 192 * Login
224 **************************************************************************/ 193 **************************************************************************/
225 194
226 195 static void
227 static gboolean 196 cvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
228 cvr_cmd(MsnServConn *servconn, const char *command, const char **params, 197 {
229 size_t param_count) 198 GaimAccount *account;
230 { 199 GaimConnection *gc;
231 GaimAccount *account = servconn->session->account; 200
232 GaimConnection *gc = gaim_account_get_connection(account); 201 account = cmdproc->session->account;
233 char outparams[MSN_BUF_LEN]; 202 gc = gaim_account_get_connection(account);
234 203
235 g_snprintf(outparams, sizeof(outparams), 204 msn_cmdproc_send(cmdproc, "USR", "TWN I %s",
236 "TWN I %s", gaim_account_get_username(account)); 205 gaim_account_get_username(account));
237 206 }
238 if (!msn_servconn_send_command(servconn, "USR", outparams)) 207
239 { 208 static void
240 gaim_connection_error(gc, _("Unable to request USR\n")); 209 inf_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
241 210 {
242 return FALSE; 211 GaimAccount *account;
243 } 212 GaimConnection *gc;
244 213
245 return TRUE; 214 account = cmdproc->session->account;
246 } 215 gc = gaim_account_get_connection(account);
247 216
248 static gboolean 217 if (strcmp(cmd->params[1], "MD5"))
249 inf_cmd(MsnServConn *servconn, const char *command, const char **params, 218 {
250 size_t param_count)
251 {
252 GaimAccount *account = servconn->session->account;
253 GaimConnection *gc = gaim_account_get_connection(account);
254 char outparams[MSN_BUF_LEN];
255
256 if (strcmp(params[1], "MD5")) {
257 gaim_connection_error(gc, _("Unable to login using MD5")); 219 gaim_connection_error(gc, _("Unable to login using MD5"));
258 220
259 return FALSE; 221 return;
260 } 222 }
261 223
262 g_snprintf(outparams, sizeof(outparams), "MD5 I %s", 224 msn_cmdproc_send(cmdproc, "USR", "MD5 I %s",
263 gaim_account_get_username(account)); 225 gaim_account_get_username(account));
264 226
265 if (!msn_servconn_send_command(servconn, "USR", outparams)) { 227 if (cmdproc->error)
266 gaim_connection_error(gc, _("Unable to send USR")); 228 return;
267
268 return FALSE;
269 }
270 229
271 gaim_connection_update_progress(gc, _("Requesting to send password"), 230 gaim_connection_update_progress(gc, _("Requesting to send password"),
272 5, MSN_CONNECT_STEPS); 231 5, MSN_CONNECT_STEPS);
273 232 }
274 return TRUE; 233
275 } 234 static void
276 235 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
277 static gboolean 236 {
278 usr_cmd(MsnServConn *servconn, const char *command, const char **params, 237 MsnSession *session;
279 size_t param_count) 238 GaimAccount *account;
280 { 239 GaimConnection *gc;
281 MsnSession *session = servconn->session;
282 GaimAccount *account = session->account;
283 GaimConnection *gc = gaim_account_get_connection(account);
284 char outparams[MSN_BUF_LEN]; 240 char outparams[MSN_BUF_LEN];
241
242 session = cmdproc->session;
243 account = session->account;
244 gc = gaim_account_get_connection(account);
285 245
286 /* 246 /*
287 * We're either getting the passport connect info (if we're on 247 * We're either getting the passport connect info (if we're on
288 * MSNP8 or higher), or a challenge request (MSNP7 and lower). 248 * MSNP8 or higher), or a challenge request (MSNP7 and lower).
289 * 249 *
290 * Let's find out. 250 * Let's find out.
291 */ 251 */
292 if (!g_ascii_strcasecmp(params[1], "OK")) 252 if (!g_ascii_strcasecmp(cmd->params[1], "OK"))
293 { 253 {
294 const char *friendly = gaim_url_decode(params[3]); 254 const char *friendly = gaim_url_decode(cmd->params[3]);
295 255
296 /* OK */ 256 /* OK */
297 257
298 gaim_connection_set_display_name(gc, friendly); 258 gaim_connection_set_display_name(gc, friendly);
299 259
300 session->syncing_lists = TRUE; 260 session->syncing_lists = TRUE;
301 261
302 if (!msn_servconn_send_command(servconn, "SYN", "0")) 262 msn_cmdproc_send(cmdproc, "SYN", "%s", "0");
303 { 263
304 gaim_connection_error(gc, _("Unable to write")); 264 if (cmdproc->error)
305 265 return;
306 return FALSE;
307 }
308 266
309 gaim_connection_update_progress(gc, _("Retrieving buddy list"), 267 gaim_connection_update_progress(gc, _("Retrieving buddy list"),
310 7, MSN_CONNECT_STEPS); 268 7, MSN_CONNECT_STEPS);
311 } 269 }
312 else if (!g_ascii_strcasecmp(params[1], "TWN")) 270 else if (!g_ascii_strcasecmp(cmd->params[1], "TWN"))
313 { 271 {
314 char **elems, **cur, **tokens; 272 char **elems, **cur, **tokens;
315 273
316 /* Passport authentication */ 274 /* Passport authentication */
317 session->nexus = msn_nexus_new(session); 275 session->nexus = msn_nexus_new(session);
318 276
319 /* Parse the challenge data. */ 277 /* Parse the challenge data. */
320 elems = g_strsplit(params[3], ",", 0); 278 elems = g_strsplit(cmd->params[3], ",", 0);
321 279
322 for (cur = elems; *cur != NULL; cur++) 280 for (cur = elems; *cur != NULL; cur++)
323 { 281 {
324 tokens = g_strsplit(*cur, "=", 2); 282 tokens = g_strsplit(*cur, "=", 2);
325 g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]); 283 g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]);
332 msn_nexus_connect(session->nexus); 290 msn_nexus_connect(session->nexus);
333 291
334 gaim_connection_update_progress(gc, _("Password sent"), 292 gaim_connection_update_progress(gc, _("Password sent"),
335 6, MSN_CONNECT_STEPS); 293 6, MSN_CONNECT_STEPS);
336 } 294 }
337 else if (!g_ascii_strcasecmp(params[1], "MD5")) 295 else if (!g_ascii_strcasecmp(cmd->params[1], "MD5"))
338 { 296 {
339 /* Challenge */ 297 /* Challenge */
340 const char *challenge = params[3]; 298 const char *challenge;
341 char buf[MSN_BUF_LEN]; 299 const char *password;
300 char buf[33];
342 md5_state_t st; 301 md5_state_t st;
343 md5_byte_t di[16]; 302 md5_byte_t di[16];
344 int i; 303 int i;
345 304
346 g_snprintf(buf, sizeof(buf), "%s%s", challenge, 305 challenge = cmd->params[3];
347 gaim_account_get_password(account)); 306 password = gaim_account_get_password(account);
348 307
349 md5_init(&st); 308 md5_init(&st);
350 md5_append(&st, (const md5_byte_t *)buf, strlen(buf)); 309 md5_append(&st, (const md5_byte_t *)challenge, strlen(challenge));
310 md5_append(&st, (const md5_byte_t *)password, strlen(password));
351 md5_finish(&st, di); 311 md5_finish(&st, di);
352 312
353 g_snprintf(outparams, sizeof(outparams), "MD5 S "); 313 g_snprintf(outparams, sizeof(outparams), "MD5 S ");
354 314
355 for (i = 0; i < 16; i++) { 315 for (i = 0; i < 16; i++)
356 g_snprintf(buf, sizeof(buf), "%02x", di[i]); 316 g_snprintf(buf + (i*2), 3, "%02x", di[i]);
357 strcat(outparams, buf); 317
358 } 318 msn_cmdproc_send(cmdproc, "USR", "MD5 S %s", buf);
359 319
360 if (!msn_servconn_send_command(servconn, "USR", outparams)) { 320 if (cmdproc->error)
361 gaim_connection_error(gc, _("Unable to send password")); 321 return;
362
363 return FALSE;
364 }
365 322
366 gaim_connection_update_progress(gc, _("Password sent"), 323 gaim_connection_update_progress(gc, _("Password sent"),
367 6, MSN_CONNECT_STEPS); 324 6, MSN_CONNECT_STEPS);
368 } 325 }
369 326 }
370 return TRUE; 327
371 } 328 static void
372 329 ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
373 static gboolean 330 {
374 ver_cmd(MsnServConn *servconn, const char *command, const char **params, 331 MsnSession *session;
375 size_t param_count) 332 GaimAccount *account;
376 { 333 GaimConnection *gc;
377 MsnSession *session = servconn->session;
378 GaimAccount *account = session->account;
379 GaimConnection *gc = gaim_account_get_connection(account);
380 gboolean protocol_supported = FALSE; 334 gboolean protocol_supported = FALSE;
381 char outparams[MSN_BUF_LEN];
382 char proto_str[8]; 335 char proto_str[8];
383 size_t i; 336 size_t i;
384 337
338 session = cmdproc->session;
339 account = session->account;
340 gc = gaim_account_get_connection(account);
341
385 g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver); 342 g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver);
386 343
387 for (i = 1; i < param_count; i++) 344 for (i = 1; i < cmd->param_count; i++)
388 { 345 {
389 if (!strcmp(params[i], proto_str)) 346 if (!strcmp(cmd->params[i], proto_str))
390 { 347 {
391 protocol_supported = TRUE; 348 protocol_supported = TRUE;
392 break; 349 break;
393 } 350 }
394 } 351 }
395 352
396 if (!protocol_supported) { 353 if (!protocol_supported)
354 {
397 gaim_connection_error(gc, _("Protocol not supported")); 355 gaim_connection_error(gc, _("Protocol not supported"));
398 356
399 return FALSE; 357 return;
400 } 358 }
401 359
402 if (session->protocol_ver >= 8) 360 if (session->protocol_ver >= 8)
403 { 361 {
404 g_snprintf(outparams, sizeof(outparams), 362 msn_cmdproc_send(cmdproc, "CVR",
405 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s", 363 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s",
406 gaim_account_get_username(account)); 364 gaim_account_get_username(account));
407
408 if (!msn_servconn_send_command(servconn, "CVR", outparams))
409 {
410 gaim_connection_error(gc, _("Unable to request CVR\n"));
411
412 return FALSE;
413 }
414 } 365 }
415 else 366 else
416 { 367 {
417 if (!msn_servconn_send_command(servconn, "INF", NULL)) 368 msn_cmdproc_send(cmdproc, "INF", NULL, NULL);
418 { 369 }
419 gaim_connection_error(gc, _("Unable to request INF\n"));
420
421 return FALSE;
422 }
423 }
424
425 return TRUE;
426 } 370 }
427 371
428 /************************************************************************** 372 /**************************************************************************
429 * Log out 373 * Log out
430 **************************************************************************/ 374 **************************************************************************/
431 static gboolean 375 static void
432 out_cmd(MsnServConn *servconn, const char *command, const char **params, 376 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
433 size_t param_count) 377 {
434 { 378 GaimConnection *gc;
435 GaimConnection *gc = servconn->session->account->gc; 379
436 380 gc = cmdproc->session->account->gc;
437 if (!g_ascii_strcasecmp(params[0], "OTH")) { 381
382 if (!g_ascii_strcasecmp(cmd->params[0], "OTH"))
383 {
438 gc->wants_to_die = TRUE; 384 gc->wants_to_die = TRUE;
439 gaim_connection_error(gc, 385 gaim_connection_error(gc,
440 _("You have been disconnected. You have " 386 _("You have been disconnected. You have "
441 "signed on from another location.")); 387 "signed on from another location."));
442 } 388 }
443 else if (!g_ascii_strcasecmp(params[0], "SSD")) { 389 else if (!g_ascii_strcasecmp(cmd->params[0], "SSD"))
390 {
444 gaim_connection_error(gc, 391 gaim_connection_error(gc,
445 _("You have been disconnected. The MSN servers " 392 _("You have been disconnected. The MSN servers "
446 "are going down temporarily.")); 393 "are going down temporarily."));
447 } 394 }
448
449 return FALSE;
450 } 395 }
451 396
452 /************************************************************************** 397 /**************************************************************************
453 * Messages 398 * Messages
454 **************************************************************************/ 399 **************************************************************************/
455 static void 400 static void
456 msg_cmd_post(MsnServConn *servconn, char *payload, size_t len) 401 msg_cmd_post(MsnCmdProc *cmdproc, char *payload, size_t len)
457 { 402 {
458 MsnMessage *msg = msn_message_new(); 403 MsnMessage *msg;
459 404
460 msg->passport = servconn->msg_passport; 405 msg = msn_message_new();
461 406
462 msn_message_parse_payload(msg, payload, len); 407 msn_message_parse_payload(msg, payload, len);
463 408
464 msn_servconn_process_message(servconn, msg); 409 msg->passport = cmdproc->temp;
410 msn_cmdproc_process_msg(cmdproc, msg);
411 g_free(cmdproc->temp);
412 cmdproc->temp = NULL;
465 413
466 msn_message_destroy(msg); 414 msn_message_destroy(msg);
467 } 415 }
468 416
469 static gboolean 417 static void
470 msg_cmd(MsnServConn *servconn, const char *command, const char **params, 418 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
471 size_t param_count)
472 { 419 {
473 gaim_debug(GAIM_DEBUG_INFO, "msn", "Found message. Parsing.\n"); 420 gaim_debug(GAIM_DEBUG_INFO, "msn", "Found message. Parsing.\n");
474 421
475 servconn->payload_cb = msg_cmd_post; 422 cmdproc->payload_cb = msg_cmd_post;
476 servconn->payload_len = atoi(params[2]); 423 cmdproc->servconn->payload_len = atoi(cmd->params[2]);
477 424 cmdproc->temp = g_strdup(cmd->params[0]);
478 servconn->msg_passport = g_strdup(params[0]);
479
480 return TRUE;
481 } 425 }
482 426
483 /************************************************************************** 427 /**************************************************************************
484 * Challenges 428 * Challenges
485 **************************************************************************/ 429 **************************************************************************/
486 static gboolean 430 static void
487 chl_cmd(MsnServConn *servconn, const char *command, const char **params, 431 chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
488 size_t param_count) 432 {
489 { 433 MsnSession *session;
490 MsnSession *session = servconn->session; 434 GaimConnection *gc;
491 GaimConnection *gc = session->account->gc; 435 MsnTransaction *trans;
492 char buf[MSN_BUF_LEN]; 436 char buf[MSN_BUF_LEN];
493 char buf2[3];
494 const char *challenge_resp; 437 const char *challenge_resp;
438 const char *challenge_str;
495 md5_state_t st; 439 md5_state_t st;
496 md5_byte_t di[16]; 440 md5_byte_t di[16];
497 int i; 441 int i;
498 442
443 session = cmdproc->session;
444 gc = session->account->gc;
445
499 md5_init(&st); 446 md5_init(&st);
500 md5_append(&st, (const md5_byte_t *)params[1], strlen(params[1])); 447 md5_append(&st, (const md5_byte_t *)cmd->params[1], strlen(cmd->params[1]));
501 448
502 if (session->protocol_ver >= 8) 449 if (session->protocol_ver >= 8)
503 { 450 {
504 challenge_resp = "VT6PX?UQTM4WM%YR"; 451 challenge_resp = "VT6PX?UQTM4WM%YR";
452 challenge_str = "PROD0038W!61ZTF9";
505 } 453 }
506 else 454 else
507 { 455 {
508 challenge_resp = "Q1P7W2E4J9R8U3S5"; 456 challenge_resp = "Q1P7W2E4J9R8U3S5";
457 challenge_str = "msmsgs@msnmsgr.com";
509 } 458 }
510 459
511 md5_append(&st, (const md5_byte_t *)challenge_resp, 460 md5_append(&st, (const md5_byte_t *)challenge_resp,
512 strlen(challenge_resp)); 461 strlen(challenge_resp));
513 md5_finish(&st, di); 462 md5_finish(&st, di);
514 463
515 g_snprintf(buf, sizeof(buf), 464 for (i = 0; i < 16; i++)
516 "QRY %u %s 32\r\n", 465 g_snprintf(buf + (i*2), 3, "%02x", di[i]);
517 servconn->session->trId++, 466
518 (session->protocol_ver >= 8 467 trans = msn_transaction_new("QRY", "%s 32", challenge_str);
519 ? "PROD0038W!61ZTF9" 468
520 : "msmsgs@msnmsgr.com")); 469 msn_transaction_set_payload(trans, buf, 32);
521 470
522 for (i = 0; i < 16; i++) { 471 msn_cmdproc_send_trans(cmdproc, trans);
523 g_snprintf(buf2, sizeof(buf2), "%02x", di[i]);
524 strcat(buf, buf2);
525 }
526
527 if (msn_servconn_write(servconn, buf, strlen(buf)) <= 0) {
528 gaim_connection_error(gc, _("Unable to write to server"));
529 }
530
531 return TRUE;
532 } 472 }
533 473
534 /************************************************************************** 474 /**************************************************************************
535 * Buddy Lists 475 * Buddy Lists
536 **************************************************************************/ 476 **************************************************************************/
537 static gboolean 477 static void
538 add_cmd(MsnServConn *servconn, const char *command, const char **params, 478 add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
539 size_t param_count) 479 {
540 { 480 MsnSession *session;
541 MsnSession *session = servconn->session;
542 MsnUser *user; 481 MsnUser *user;
543 GaimAccount *account = session->account; 482 GaimAccount *account;
544 GaimConnection *gc = gaim_account_get_connection(account); 483 GaimConnection *gc;
545 MsnPermitAdd *pa; 484 MsnPermitAdd *pa;
546 GSList *sl; 485 GSList *sl;
547 const char *list, *passport, *group_id = NULL; 486 const char *list, *passport, *group_id = NULL;
548 const char *friend; 487 const char *friend;
549 char msg[MSN_BUF_LEN]; 488 char msg[MSN_BUF_LEN];
550 489
551 list = params[1]; 490 session = cmdproc->session;
552 passport = params[3]; 491 account = session->account;
553 friend = gaim_url_decode(params[4]); 492 gc = gaim_account_get_connection(account);
554 493
555 if (param_count >= 6) 494 list = cmd->params[1];
556 group_id = params[5]; 495 passport = cmd->params[3];
557 496 friend = gaim_url_decode(cmd->params[4]);
558 if (!g_ascii_strcasecmp(list, "FL")) { 497
498 if (cmd->param_count >= 6)
499 group_id = cmd->params[5];
500
501 if (!g_ascii_strcasecmp(list, "FL"))
502 {
559 user = msn_user_new(session, passport, NULL); 503 user = msn_user_new(session, passport, NULL);
560 504
561 if (group_id != NULL) 505 if (group_id != NULL)
562 msn_user_add_group_id(user, atoi(group_id)); 506 msn_user_add_group_id(user, atoi(group_id));
563 507
564 add_buddy(servconn, user); 508 add_buddy(cmdproc, user);
565 509
566 return TRUE; 510 return;
567 } 511 }
568 else if (g_ascii_strcasecmp(list, "RL")) 512 else if (g_ascii_strcasecmp(list, "RL"))
569 return TRUE; 513 return;
570 514
571 for (sl = gc->account->permit; sl != NULL; sl = sl->next) { 515 for (sl = gc->account->permit; sl != NULL; sl = sl->next)
572 if (!gaim_utf8_strcasecmp(sl->data, passport)) 516 if (!gaim_utf8_strcasecmp(sl->data, passport))
573 return TRUE; 517 return;
574 }
575 518
576 user = msn_user_new(session, passport, friend); 519 user = msn_user_new(session, passport, friend);
577 msn_user_set_name(user, friend); 520 msn_user_set_name(user, friend);
578 521
579 pa = g_new0(MsnPermitAdd, 1); 522 pa = g_new0(MsnPermitAdd, 1);
585 passport, friend, gaim_account_get_username(account)); 528 passport, friend, gaim_account_get_username(account));
586 529
587 gaim_request_action(gc, NULL, msg, NULL, 0, pa, 2, 530 gaim_request_action(gc, NULL, msg, NULL, 0, pa, 2,
588 _("Authorize"), G_CALLBACK(msn_accept_add_cb), 531 _("Authorize"), G_CALLBACK(msn_accept_add_cb),
589 _("Deny"), G_CALLBACK(msn_cancel_add_cb)); 532 _("Deny"), G_CALLBACK(msn_cancel_add_cb));
590 533 }
591 return TRUE; 534
592 } 535 static void
593 536 add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
594 static gboolean 537 {
595 adg_cmd(MsnServConn *servconn, const char *command, const char **params, 538 MsnSession *session;
596 size_t param_count) 539 GaimAccount *account;
540 GaimConnection *gc;
541 const char *list, *passport;
542 char *reason;
543 char *msg = NULL;
544 char **params;
545
546 session = cmdproc->session;
547 account = session->account;
548 gc = gaim_account_get_connection(account);
549 params = g_strsplit(trans->params, " ", 0);
550
551 list = params[0];
552 passport = params[1];
553
554 reason = "invalid user";
555
556 if (!strcmp(list, "FL"))
557 msg = g_strdup("Unable to add user on MSN");
558 else if (!strcmp(list, "BL"))
559 msg = g_strdup("Unable to block user on MSN");
560 else if (!strcmp(list, "AL"))
561 msg = g_strdup("Unable to permit user on MSN");
562
563 if (!strcmp(list, "FL"))
564 {
565 reason = g_strdup_printf("%s is not a valid passport account.\n\n"
566 "This user will be automatically removed "
567 "from your %s account's buddy list, so this "
568 "won't appear again.",
569 passport, gaim_account_get_username(account));
570 }
571 else
572 {
573 reason = g_strdup_printf("%s is not a valid passport account.",
574 passport);
575 }
576
577 if (msg != NULL)
578 {
579 gaim_notify_error(gc, NULL, msg, reason);
580 g_free(msg);
581 }
582
583 if (!strcmp(list, "FL"))
584 {
585 GaimBuddy *buddy;
586
587 buddy = gaim_find_buddy(account, passport);
588
589 if (buddy != NULL)
590 gaim_blist_remove_buddy(buddy);
591 }
592
593 g_free(reason);
594
595 g_strfreev(params);
596 }
597
598 static void
599 adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
597 { 600 {
598 MsnGroup *group; 601 MsnGroup *group;
599 MsnSession *session = servconn->session; 602 MsnSession *session;
600 gint group_id; 603 gint group_id;
601 const char *group_name; 604 const char *group_name;
602 605
603 group_id = atoi(params[3]); 606 session = cmdproc->session;
604 607
605 group_name = gaim_url_decode(params[2]); 608 group_id = atoi(cmd->params[3]);
609
610 group_name = gaim_url_decode(cmd->params[2]);
606 611
607 group = msn_group_new(session, group_id, group_name); 612 group = msn_group_new(session, group_id, group_name);
608 613
609 msn_groups_add(session->groups, group); 614 msn_groups_add(session->groups, group);
610 615 }
611 return TRUE; 616
612 } 617 static void
613 618 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
614 static gboolean 619 {
615 blp_cmd(MsnServConn *servconn, const char *command, const char **params, 620 GaimConnection *gc;
616 size_t param_count)
617 {
618 GaimConnection *gc = servconn->session->account->gc;
619 const char *list_name; 621 const char *list_name;
620 622
621 if (servconn->session->protocol_ver >= 8) 623 gc = cmdproc->session->account->gc;
622 list_name = params[0]; 624
625 if (cmdproc->session->protocol_ver >= 8)
626 list_name = cmd->params[0];
623 else 627 else
624 list_name = params[2]; 628 list_name = cmd->params[2];
625 629
626 if (!g_ascii_strcasecmp(list_name, "AL")) { 630 if (!g_ascii_strcasecmp(list_name, "AL"))
631 {
627 /* 632 /*
628 * If the current setting is AL, messages from users who 633 * If the current setting is AL, messages from users who
629 * are not in BL will be delivered. 634 * are not in BL will be delivered.
630 * 635 *
631 * In other words, deny some. 636 * In other words, deny some.
632 */ 637 */
633 gc->account->perm_deny = GAIM_PRIVACY_DENY_USERS; 638 gc->account->perm_deny = GAIM_PRIVACY_DENY_USERS;
634 } 639 }
635 else { 640 else
641 {
636 /* If the current setting is BL, only messages from people 642 /* If the current setting is BL, only messages from people
637 * who are in the AL will be delivered. 643 * who are in the AL will be delivered.
638 * 644 *
639 * In other words, permit some. 645 * In other words, permit some.
640 */ 646 */
641 gc->account->perm_deny = GAIM_PRIVACY_ALLOW_USERS; 647 gc->account->perm_deny = GAIM_PRIVACY_ALLOW_USERS;
642 } 648 }
643 649 }
644 return TRUE; 650
645 } 651 static void
646 652 bpr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
647 static gboolean 653 {
648 bpr_cmd(MsnServConn *servconn, const char *command, const char **params, 654 MsnSession *session;
649 size_t param_count) 655 GaimConnection *gc;
650 {
651 MsnSession *session = servconn->session;
652 GaimConnection *gc = session->account->gc;
653 const char *passport, *type, *value; 656 const char *passport, *type, *value;
654 GaimBuddy *b; 657 GaimBuddy *b;
655 MsnUser *user; 658 MsnUser *user;
656 659
657 if (param_count == 4) 660 session = cmdproc->session;
658 { 661 gc = session->account->gc;
659 passport = params[1]; 662
660 type = params[2]; 663 if (cmd->param_count == 4)
661 value = params[3]; 664 {
662 } 665 passport = cmd->params[1];
663 else if (param_count == 2) 666 type = cmd->params[2];
667 value = cmd->params[3];
668 }
669 else if (cmd->param_count == 2)
664 { 670 {
665 passport = msn_user_get_passport(session->last_user_added); 671 passport = msn_user_get_passport(session->last_user_added);
666 type = params[0]; 672 type = cmd->params[0];
667 value = params[1]; 673 value = cmd->params[1];
668 } 674 }
669 else 675 else
670 return TRUE; 676 return;
671 677
672 user = msn_users_find_with_passport(session->users, passport); 678 user = msn_users_find_with_passport(session->users, passport);
673 679
674 if (value != NULL) { 680 if (value != NULL)
675 if (!strcmp(type, "MOB")) { 681 {
676 if (!strcmp(value, "Y") || !strcmp(value, "N")) { 682 if (!strcmp(type, "MOB"))
683 {
684 if (!strcmp(value, "Y") || !strcmp(value, "N"))
685 {
677 user->mobile = (!strcmp(value, "Y") ? TRUE : FALSE); 686 user->mobile = (!strcmp(value, "Y") ? TRUE : FALSE);
678 687
679 if ((b = gaim_find_buddy(gc->account, passport)) != NULL) { 688 if ((b = gaim_find_buddy(gc->account, passport)) != NULL)
680 if (GAIM_BUDDY_IS_ONLINE(b)) { 689 {
690 if (GAIM_BUDDY_IS_ONLINE(b))
691 {
681 serv_got_update(gc, (char *)passport, 692 serv_got_update(gc, (char *)passport,
682 1, 0, 0, 0, b->uc); 693 1, 0, 0, 0, b->uc);
683 } 694 }
684 } 695 }
685 } 696 }
689 else if (!strcmp(type, "PHW")) 700 else if (!strcmp(type, "PHW"))
690 msn_user_set_work_phone(user, gaim_url_decode(value)); 701 msn_user_set_work_phone(user, gaim_url_decode(value));
691 else if (!strcmp(type, "PHM")) 702 else if (!strcmp(type, "PHM"))
692 msn_user_set_mobile_phone(user, gaim_url_decode(value)); 703 msn_user_set_mobile_phone(user, gaim_url_decode(value));
693 } 704 }
694 705 }
695 return TRUE; 706
696 } 707 static void
697 708 fln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
698 static gboolean 709 {
699 fln_cmd(MsnServConn *servconn, const char *command, const char **params, 710 GaimConnection *gc;
700 size_t param_count) 711
701 { 712 gc = cmdproc->session->account->gc;
702 GaimConnection *gc = servconn->session->account->gc; 713
703 714 serv_got_update(gc, (char *)cmd->params[0], 0, 0, 0, 0, 0);
704 serv_got_update(gc, (char *)params[0], 0, 0, 0, 0, 0); 715 }
705 716
706 return TRUE; 717 static void
707 } 718 iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
708 719 {
709 static gboolean 720 MsnSession *session;
710 iln_cmd(MsnServConn *servconn, const char *command, const char **params, 721 GaimConnection *gc;
711 size_t param_count)
712 {
713 MsnSession *session = servconn->session;
714 GaimConnection *gc = session->account->gc;
715 MsnUser *user; 722 MsnUser *user;
716 MsnObject *msnobj; 723 MsnObject *msnobj;
717 int status = 0; 724 int status = 0;
718 const char *state, *passport, *friend; 725 const char *state, *passport, *friend;
719 GaimBuddy *b; 726 GaimBuddy *b;
720 727
721 state = params[1]; 728 session = cmdproc->session;
722 passport = params[2]; 729 gc = session->account->gc;
723 friend = gaim_url_decode(params[3]); 730
731 state = cmd->params[1];
732 passport = cmd->params[2];
733 friend = gaim_url_decode(cmd->params[3]);
724 734
725 user = msn_users_find_with_passport(session->users, passport); 735 user = msn_users_find_with_passport(session->users, passport);
726 736
727 serv_got_alias(gc, (char *)passport, (char *)friend); 737 serv_got_alias(gc, (char *)passport, (char *)friend);
728 738
729 msn_user_set_name(user, friend); 739 msn_user_set_name(user, friend);
730 740
731 if (session->protocol_ver >= 9 && param_count == 6) 741 if (session->protocol_ver >= 9 && cmd->param_count == 6)
732 { 742 {
733 msnobj = msn_object_new_from_string(gaim_url_decode(params[5])); 743 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[5]));
734 msn_user_set_object(user, msnobj); 744 msn_user_set_object(user, msnobj);
735 } 745 }
736 746
737 if ((b = gaim_find_buddy(gc->account, passport)) != NULL) 747 if ((b = gaim_find_buddy(gc->account, passport)) != NULL)
738 status |= ((((b->uc) >> 1) & 0xF0) << 1); 748 status |= ((((b->uc) >> 1) & 0xF0) << 1);
749 status |= UC_UNAVAILABLE | (MSN_PHONE << 1); 759 status |= UC_UNAVAILABLE | (MSN_PHONE << 1);
750 else if (!g_ascii_strcasecmp(state, "LUN")) 760 else if (!g_ascii_strcasecmp(state, "LUN"))
751 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1); 761 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1);
752 762
753 serv_got_update(gc, (char *)passport, 1, 0, 0, 0, status); 763 serv_got_update(gc, (char *)passport, 1, 0, 0, 0, status);
754 764 }
755 return TRUE; 765
756 } 766 static void
757 767 ipg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
758 static gboolean 768 {
759 ipg_cmd(MsnServConn *servconn, const char *command, const char **params, 769 cmdproc->payload_cb = NULL;
760 size_t param_count) 770 cmdproc->servconn->payload_len = atoi(cmd->params[2]);
761 { 771 }
762 servconn->payload_cb = NULL; 772
763 servconn->payload_len = atoi(params[2]); 773 static void
764 774 lsg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
765 return TRUE; 775 {
766 } 776 MsnSession *session;
767
768 static gboolean
769 lsg_cmd(MsnServConn *servconn, const char *command, const char **params,
770 size_t param_count)
771 {
772 MsnSession *session = servconn->session;
773 MsnGroup *group; 777 MsnGroup *group;
774 GaimGroup *g; 778 GaimGroup *g;
775 const char *name; 779 const char *name;
776 int num_groups, group_id; 780 int num_groups, group_id;
777 781
782 session = cmdproc->session;
783
778 if (session->protocol_ver >= 8) 784 if (session->protocol_ver >= 8)
779 { 785 {
780 group_id = atoi(params[0]); 786 group_id = atoi(cmd->params[0]);
781 name = gaim_url_decode(params[1]); 787 name = gaim_url_decode(cmd->params[1]);
782 } 788 }
783 else 789 else
784 { 790 {
785 num_groups = atoi(params[3]); 791 num_groups = atoi(cmd->params[3]);
786 group_id = atoi(params[4]); 792 group_id = atoi(cmd->params[4]);
787 name = gaim_url_decode(params[5]); 793 name = gaim_url_decode(cmd->params[5]);
788 794
789 if (num_groups == 0) 795 if (num_groups == 0)
790 return TRUE; 796 return;
791 797
792 if (!strcmp(name, "~")) 798 if (!strcmp(name, "~"))
793 name = _("Buddies"); 799 name = _("Buddies");
794 } 800 }
795 801
796 group = msn_group_new(session, group_id, name); 802 group = msn_group_new(session, group_id, name);
797 803
798 msn_groups_add(session->groups, group); 804 msn_groups_add(session->groups, group);
799 805
800 if ((g = gaim_find_group(name)) == NULL) { 806 if ((g = gaim_find_group(name)) == NULL)
807 {
801 g = gaim_group_new(name); 808 g = gaim_group_new(name);
802 gaim_blist_add_group(g, NULL); 809 gaim_blist_add_group(g, NULL);
803 } 810 }
804 811 }
805 return TRUE; 812
806 } 813 static void
807 814 lst_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
808 static gboolean 815 {
809 lst_cmd(MsnServConn *servconn, const char *command, const char **params, 816 MsnSession *session;
810 size_t param_count) 817 GaimAccount *account;
811 { 818 GaimConnection *gc;
812 MsnSession *session = servconn->session;
813 GaimAccount *account = session->account;
814 GaimConnection *gc = gaim_account_get_connection(account);
815 const char *passport = NULL; 819 const char *passport = NULL;
816 const char *friend = NULL; 820 const char *friend = NULL;
817 821
822 session = cmdproc->session;
823 account = session->account;
824 gc = gaim_account_get_connection(account);
825
818 if (session->protocol_ver >= 8) 826 if (session->protocol_ver >= 8)
819 { 827 {
820 const char *group_nums; 828 const char *group_nums;
821 int list_op; 829 int list_op;
822 830
823 passport = params[0]; 831 passport = cmd->params[0];
824 friend = gaim_url_decode(params[1]); 832 friend = gaim_url_decode(cmd->params[1]);
825 list_op = atoi(params[2]); 833 list_op = atoi(cmd->params[2]);
826 group_nums = params[3]; 834 group_nums = cmd->params[3];
827 835
828 if (list_op & MSN_LIST_FL_OP) 836 if (list_op & MSN_LIST_FL_OP)
829 { 837 {
830 MsnUser *user; 838 MsnUser *user;
831 char **c; 839 char **c;
919 { 927 {
920 msn_user_set_buddy_icon(session->user, 928 msn_user_set_buddy_icon(session->user,
921 gaim_account_get_buddy_icon(session->account)); 929 gaim_account_get_buddy_icon(session->account));
922 930
923 if (!msn_session_change_status(session, "NLN")) 931 if (!msn_session_change_status(session, "NLN"))
924 return FALSE; 932 return;
925 933
926 gaim_connection_set_state(gc, GAIM_CONNECTED); 934 gaim_connection_set_state(gc, GAIM_CONNECTED);
927 serv_finish_login(gc); 935 serv_finish_login(gc);
928 936
929 if (session->lists.allow == NULL) 937 if (session->lists.allow == NULL)
945 GSList *sl; 953 GSList *sl;
946 954
947 session->lists.forward = 955 session->lists.forward =
948 g_slist_remove(session->lists.forward, user); 956 g_slist_remove(session->lists.forward, user);
949 957
950 add_buddy(servconn, user); 958 add_buddy(cmdproc, user);
951 959
952 buddies = gaim_find_buddies(account, 960 buddies = gaim_find_buddies(account,
953 msn_user_get_passport(user)); 961 msn_user_get_passport(user));
954 962
955 /* Find all occurrences of this buddy in the wrong place. */ 963 /* Find all occurrences of this buddy in the wrong place. */
979 { 987 {
980 const char *list_name; 988 const char *list_name;
981 int user_num; 989 int user_num;
982 int num_users; 990 int num_users;
983 991
984 list_name = params[1]; 992 list_name = cmd->params[1];
985 user_num = atoi(params[3]); 993 user_num = atoi(cmd->params[3]);
986 num_users = atoi(params[4]); 994 num_users = atoi(cmd->params[4]);
987 995
988 if (g_ascii_strcasecmp(list_name, "RL") && 996 if (g_ascii_strcasecmp(list_name, "RL") &&
989 user_num == 0 && num_users == 0) 997 user_num == 0 && num_users == 0)
990 { 998 {
991 return TRUE; /* There are no users on this list. */ 999 return; /* There are no users on this list. */
992 } 1000 }
993 1001
994 if (num_users > 0) 1002 if (num_users > 0)
995 { 1003 {
996 passport = params[5]; 1004 passport = cmd->params[5];
997 friend = gaim_url_decode(params[6]); 1005 friend = gaim_url_decode(cmd->params[6]);
998 } 1006 }
999 1007
1000 if (session->syncing_lists && session->lists_synced) 1008 if (session->syncing_lists && session->lists_synced)
1001 return TRUE; 1009 return;
1002 1010
1003 if (!g_ascii_strcasecmp(list_name, "FL") && user_num != 0) 1011 if (!g_ascii_strcasecmp(list_name, "FL") && user_num != 0)
1004 { 1012 {
1005 /* These are users on our contact list. */ 1013 /* These are users on our contact list. */
1006 MsnUser *user; 1014 MsnUser *user;
1007 1015
1008 user = msn_user_new(session, passport, friend); 1016 user = msn_user_new(session, passport, friend);
1009 1017
1010 if (param_count == 8) 1018 if (cmd->param_count == 8)
1011 msn_user_add_group_id(user, atoi(params[7])); 1019 msn_user_add_group_id(user, atoi(cmd->params[7]));
1012 1020
1013 session->lists.forward = 1021 session->lists.forward =
1014 g_slist_append(session->lists.forward, user); 1022 g_slist_append(session->lists.forward, user);
1015 } 1023 }
1016 else if (!g_ascii_strcasecmp(list_name, "AL") && user_num != 0) 1024 else if (!g_ascii_strcasecmp(list_name, "AL") && user_num != 0)
1079 G_CALLBACK(msn_cancel_add_cb)); 1087 G_CALLBACK(msn_cancel_add_cb));
1080 } 1088 }
1081 } 1089 }
1082 1090
1083 if (user_num != num_users) 1091 if (user_num != num_users)
1084 return TRUE; /* This isn't the last one in the RL. */ 1092 return; /* This isn't the last one in the RL. */
1085 1093
1086 /* Now we're at the last one, so we can do final work. */ 1094 /* Now we're at the last one, so we can do final work. */
1087 if (!session->lists_synced) 1095 if (!session->lists_synced)
1088 { 1096 {
1089 if (!msn_session_change_status(session, "NLN")) 1097 if (!msn_session_change_status(session, "NLN"))
1090 return FALSE; 1098 return;
1091 1099
1092 gaim_connection_set_state(gc, GAIM_CONNECTED); 1100 gaim_connection_set_state(gc, GAIM_CONNECTED);
1093 serv_finish_login(gc); 1101 serv_finish_login(gc);
1094 } 1102 }
1095 1103
1110 MsnUser *user = session->lists.forward->data; 1118 MsnUser *user = session->lists.forward->data;
1111 1119
1112 session->lists.forward = 1120 session->lists.forward =
1113 g_slist_remove(session->lists.forward, user); 1121 g_slist_remove(session->lists.forward, user);
1114 1122
1115 add_buddy(servconn, user); 1123 add_buddy(cmdproc, user);
1116 } 1124 }
1117 1125
1118 session->syncing_lists = FALSE; 1126 session->syncing_lists = FALSE;
1119 session->lists_synced = TRUE; 1127 session->lists_synced = TRUE;
1120 } 1128 }
1121 } 1129 }
1122 1130 }
1123 return TRUE; 1131
1124 } 1132 static void
1125 1133 nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1126 static gboolean 1134 {
1127 nln_cmd(MsnServConn *servconn, const char *command, const char **params, 1135 MsnSession *session;
1128 size_t param_count) 1136 GaimConnection *gc;
1129 {
1130 MsnSession *session = servconn->session;
1131 GaimConnection *gc = session->account->gc;
1132 MsnUser *user; 1137 MsnUser *user;
1133 MsnObject *msnobj; 1138 MsnObject *msnobj;
1134 const char *state; 1139 const char *state;
1135 const char *passport; 1140 const char *passport;
1136 const char *friend; 1141 const char *friend;
1137 int status = 0; 1142 int status = 0;
1138 1143
1139 state = params[0]; 1144 session = cmdproc->session;
1140 passport = params[1]; 1145 gc = session->account->gc;
1141 friend = gaim_url_decode(params[2]); 1146
1147 state = cmd->params[0];
1148 passport = cmd->params[1];
1149 friend = gaim_url_decode(cmd->params[2]);
1142 1150
1143 user = msn_users_find_with_passport(session->users, passport); 1151 user = msn_users_find_with_passport(session->users, passport);
1144 1152
1145 serv_got_alias(gc, (char *)passport, (char *)friend); 1153 serv_got_alias(gc, (char *)passport, (char *)friend);
1146 1154
1147 msn_user_set_name(user, friend); 1155 msn_user_set_name(user, friend);
1148 1156
1149 if (session->protocol_ver >= 9 && param_count == 5) 1157 if (session->protocol_ver >= 9 && cmd->param_count == 5)
1150 { 1158 {
1151 msnobj = msn_object_new_from_string(gaim_url_decode(params[4])); 1159 msnobj = msn_object_new_from_string(gaim_url_decode(cmd->params[4]));
1152 msn_user_set_object(user, msnobj); 1160 msn_user_set_object(user, msnobj);
1153 } 1161 }
1154 1162
1155 if (!g_ascii_strcasecmp(state, "BSY")) 1163 if (!g_ascii_strcasecmp(state, "BSY"))
1156 status |= UC_UNAVAILABLE | (MSN_BUSY << 1); 1164 status |= UC_UNAVAILABLE | (MSN_BUSY << 1);
1164 status |= UC_UNAVAILABLE | (MSN_PHONE << 1); 1172 status |= UC_UNAVAILABLE | (MSN_PHONE << 1);
1165 else if (!g_ascii_strcasecmp(state, "LUN")) 1173 else if (!g_ascii_strcasecmp(state, "LUN"))
1166 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1); 1174 status |= UC_UNAVAILABLE | (MSN_LUNCH << 1);
1167 1175
1168 serv_got_update(gc, (char *)passport, 1, 0, 0, 0, status); 1176 serv_got_update(gc, (char *)passport, 1, 0, 0, 0, status);
1169 1177 }
1170 return TRUE; 1178
1171 } 1179 static void
1172 1180 not_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1173 static gboolean 1181 {
1174 not_cmd(MsnServConn *servconn, const char *command, const char **params, 1182 cmdproc->payload_cb = NULL;
1175 size_t param_count) 1183 cmdproc->servconn->payload_len = atoi(cmd->params[1]);
1176 { 1184 }
1177 servconn->payload_cb = NULL; 1185
1178 servconn->payload_len = atoi(params[1]); 1186 static void
1179 1187 prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1180 return TRUE; 1188 {
1181 } 1189 MsnSession *session;
1182
1183 static gboolean
1184 prp_cmd(MsnServConn *servconn, const char *command, const char **params,
1185 size_t param_count)
1186 {
1187 MsnSession *session = servconn->session;
1188 const char *type, *value; 1190 const char *type, *value;
1189 1191
1190 type = params[2]; 1192 session = cmdproc->session;
1191 value = params[3]; 1193
1192 1194 type = cmd->params[2];
1193 if (param_count == 4) { 1195 value = cmd->params[3];
1196
1197 if (cmd->param_count == 4)
1198 {
1194 if (!strcmp(type, "PHH")) 1199 if (!strcmp(type, "PHH"))
1195 msn_user_set_home_phone(session->user, gaim_url_decode(value)); 1200 msn_user_set_home_phone(session->user, gaim_url_decode(value));
1196 else if (!strcmp(type, "PHW")) 1201 else if (!strcmp(type, "PHW"))
1197 msn_user_set_work_phone(session->user, gaim_url_decode(value)); 1202 msn_user_set_work_phone(session->user, gaim_url_decode(value));
1198 else if (!strcmp(type, "PHM")) 1203 else if (!strcmp(type, "PHM"))
1199 msn_user_set_mobile_phone(session->user, gaim_url_decode(value)); 1204 msn_user_set_mobile_phone(session->user, gaim_url_decode(value));
1200 } 1205 }
1201 1206 }
1202 return TRUE; 1207
1203 } 1208 static void
1204 1209 rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1205 static gboolean 1210 {
1206 rea_cmd(MsnServConn *servconn, const char *command, const char **params, 1211 MsnSession *session;
1207 size_t param_count) 1212 GaimConnection *gc;
1208 {
1209 MsnSession *session = servconn->session;
1210 GaimConnection *gc = session->account->gc;
1211 const char *friend; 1213 const char *friend;
1212 1214
1213 friend = gaim_url_decode(params[3]); 1215 session = cmdproc->session;
1216 gc = session->account->gc;
1217 friend = gaim_url_decode(cmd->params[3]);
1214 1218
1215 gaim_connection_set_display_name(gc, friend); 1219 gaim_connection_set_display_name(gc, friend);
1216 1220 }
1217 return TRUE; 1221
1218 } 1222 static void
1219 1223 reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1220 static gboolean 1224 {
1221 reg_cmd(MsnServConn *servconn, const char *command, const char **params, 1225 MsnSession *session;
1222 size_t param_count)
1223 {
1224 MsnSession *session = servconn->session;
1225 MsnGroup *group; 1226 MsnGroup *group;
1226 int group_id; 1227 int group_id;
1227 const char *group_name; 1228 const char *group_name;
1228 1229
1229 group_id = atoi(params[2]); 1230 session = cmdproc->session;
1230 1231 group_id = atoi(cmd->params[2]);
1231 group_name = gaim_url_decode(params[3]); 1232
1233 group_name = gaim_url_decode(cmd->params[3]);
1232 1234
1233 group = msn_groups_find_with_id(session->groups, group_id); 1235 group = msn_groups_find_with_id(session->groups, group_id);
1234 1236
1235 gaim_debug(GAIM_DEBUG_INFO, "msn", "Renamed group %s to %s\n", 1237 gaim_debug(GAIM_DEBUG_INFO, "msn", "Renamed group %s to %s\n",
1236 msn_group_get_name(group), group_name); 1238 msn_group_get_name(group), group_name);
1237 1239
1238 if (group != NULL) 1240 if (group != NULL)
1239 msn_group_set_name(group, group_name); 1241 msn_group_set_name(group, group_name);
1240 1242 }
1241 return TRUE; 1243
1242 } 1244 static void
1243 1245 rem_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1244 static gboolean 1246 {
1245 rem_cmd(MsnServConn *servconn, const char *command, const char **params, 1247 MsnSession *session;
1246 size_t param_count) 1248 const char *passport;
1247 { 1249
1248 MsnSession *session = servconn->session; 1250 session = cmdproc->session;
1249 const char *passport = params[3]; 1251 passport = cmd->params[3];
1250 1252
1251 if (param_count == 5) 1253 if (cmd->param_count == 5)
1252 { 1254 {
1253 MsnUser *user; 1255 MsnUser *user;
1254 int group_id = atoi(params[4]); 1256 int group_id = atoi(cmd->params[4]);
1255 1257
1256 user = msn_users_find_with_passport(session->users, passport); 1258 user = msn_users_find_with_passport(session->users, passport);
1257 1259
1258 msn_user_remove_group_id(user, group_id); 1260 msn_user_remove_group_id(user, group_id);
1259 } 1261 }
1260 1262
1261 /* I hate this. */ 1263 /* I hate this. */
1262 if (session->moving_buddy) { 1264 /* shx: it won't be here for long. */
1265 if (session->moving_buddy)
1266 {
1263 MsnGroup *group, *old_group; 1267 MsnGroup *group, *old_group;
1264 GaimConnection *gc = session->account->gc;
1265 const char *friendly; 1268 const char *friendly;
1266 char outparams[MSN_BUF_LEN];
1267 1269
1268 group = msn_groups_find_with_name(session->groups, 1270 group = msn_groups_find_with_name(session->groups,
1269 session->dest_group_name); 1271 session->dest_group_name);
1270 1272
1271 old_group = session->old_group; 1273 old_group = session->old_group;
1272 1274
1273 session->moving_buddy = FALSE; 1275 session->moving_buddy = FALSE;
1274 session->old_group = NULL; 1276 session->old_group = NULL;
1275 1277
1276 if (group == NULL) { 1278 if (group == NULL)
1279 {
1277 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1280 gaim_debug(GAIM_DEBUG_ERROR, "msn",
1278 "Still don't have a group ID for %s while moving %s!\n", 1281 "Still don't have a group ID for %s while moving %s!\n",
1279 session->dest_group_name, passport); 1282 session->dest_group_name, passport);
1280 1283
1281 g_free(session->dest_group_name); 1284 g_free(session->dest_group_name);
1282 session->dest_group_name = NULL; 1285 session->dest_group_name = NULL;
1283
1284 return TRUE;
1285 } 1286 }
1286 1287
1287 g_free(session->dest_group_name); 1288 g_free(session->dest_group_name);
1288 session->dest_group_name = NULL; 1289 session->dest_group_name = NULL;
1289 1290
1290 if ((friendly = msn_user_get_name(session->moving_user)) == NULL) 1291 if ((friendly = msn_user_get_name(session->moving_user)) == NULL)
1291 friendly = passport; 1292 friendly = passport;
1292 1293
1293 g_snprintf(outparams, sizeof(outparams), "FL %s %s %d", 1294 msn_cmdproc_send(cmdproc, "ADD", "FL %s %s %d",
1294 passport, gaim_url_encode(friendly), 1295 passport, gaim_url_encode(friendly),
1295 msn_group_get_id(group)); 1296 msn_group_get_id(group));
1296 1297
1297 if (!msn_servconn_send_command(session->notification_conn, 1298 if (cmdproc->error)
1298 "ADD", outparams)) { 1299 return;
1299 gaim_connection_error(gc, _("Write error"));
1300 return FALSE;
1301 }
1302 1300
1303 if (old_group != NULL) 1301 if (old_group != NULL)
1304 msn_group_remove_user(old_group, session->moving_user); 1302 msn_group_remove_user(old_group, session->moving_user);
1305 1303
1306 msn_user_unref(session->moving_user); 1304 msn_user_unref(session->moving_user);
1307 1305
1308 session->moving_user = NULL; 1306 session->moving_user = NULL;
1309 1307
1310 if (old_group != NULL && 1308 if (old_group != NULL &&
1311 msn_users_get_count(msn_group_get_users(old_group)) <= 0) { 1309 msn_users_get_count(msn_group_get_users(old_group)) <= 0)
1312 1310 {
1313 g_snprintf(outparams, sizeof(outparams), "%d", 1311 msn_cmdproc_send(cmdproc, "REM", "%s", "%d",
1314 msn_group_get_id(old_group)); 1312 msn_group_get_id(old_group));
1315 1313 }
1316 if (!msn_servconn_send_command(session->notification_conn, 1314 }
1317 "RMG", outparams)) { 1315 }
1318 1316
1319 gaim_connection_error(gc, _("Write error")); 1317 static void
1320 return FALSE; 1318 rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1321 } 1319 {
1322 } 1320 MsnSession *session;
1323 }
1324
1325 return TRUE;
1326 }
1327
1328 static gboolean
1329 rmg_cmd(MsnServConn *servconn, const char *command, const char **params,
1330 size_t param_count)
1331 {
1332 MsnSession *session = servconn->session;
1333 MsnGroup *group; 1321 MsnGroup *group;
1334 1322
1335 group = msn_groups_find_with_id(session->groups, atoi(params[2])); 1323 session = cmdproc->session;
1324 group = msn_groups_find_with_id(session->groups, atoi(cmd->params[2]));
1336 1325
1337 if (group != NULL) 1326 if (group != NULL)
1338 msn_groups_remove(session->groups, group); 1327 msn_groups_remove(session->groups, group);
1339 1328 }
1340 return TRUE; 1329
1341 } 1330 static void
1342 1331 syn_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1343 static gboolean 1332 {
1344 syn_cmd(MsnServConn *servconn, const char *command, const char **params, 1333 MsnSession *session;
1345 size_t param_count) 1334 GaimConnection *gc;
1346 { 1335
1347 MsnSession *session = servconn->session; 1336 session = cmdproc->session;
1348 GaimConnection *gc = gaim_account_get_connection(session->account); 1337 gc = gaim_account_get_connection(session->account);
1349 1338
1350 if (session->protocol_ver >= 8) 1339 if (session->protocol_ver >= 8)
1351 { 1340 {
1352 if (param_count == 2) 1341 if (cmd->param_count == 2)
1353 { 1342 {
1354 char buf[256]; 1343 char *buf;
1355 1344
1356 /* 1345 /*
1357 * This can happen if we sent a SYN with an up-to-date 1346 * This can happen if we sent a SYN with an up-to-date
1358 * buddy list revision, but we send 0 to get a full list. 1347 * buddy list revision, but we send 0 to get a full list.
1359 * So, error out. 1348 * So, error out.
1360 */ 1349 */
1361 snprintf(buf, sizeof(buf), 1350 buf = g_strdup_printf(
1362 _("Your MSN buddy list for %s is temporarily unavailable. " 1351 _("Your MSN buddy list for %s is temporarily unavailable. "
1363 "Please wait and try again."), 1352 "Please wait and try again."),
1364 gaim_account_get_username(session->account)); 1353 gaim_account_get_username(session->account));
1354
1365 gaim_connection_error(gc, buf); 1355 gaim_connection_error(gc, buf);
1366 1356
1367 return FALSE; 1357 g_free(buf);
1368 } 1358
1369 1359 return;
1370 session->total_users = atoi(params[2]); 1360 }
1371 session->total_groups = atoi(params[3]); 1361
1362 session->total_users = atoi(cmd->params[2]);
1363 session->total_groups = atoi(cmd->params[3]);
1372 1364
1373 if (session->total_users == 0) 1365 if (session->total_users == 0)
1374 { 1366 {
1375 gaim_connection_set_state(gc, GAIM_CONNECTED); 1367 gaim_connection_set_state(gc, GAIM_CONNECTED);
1376 serv_finish_login(gc); 1368 serv_finish_login(gc);
1377 1369
1378 session->syncing_lists = FALSE; 1370 session->syncing_lists = FALSE;
1379 session->lists_synced = TRUE; 1371 session->lists_synced = TRUE;
1380 } 1372 }
1381 } 1373 }
1382
1383 return TRUE;
1384 } 1374 }
1385 1375
1386 /************************************************************************** 1376 /**************************************************************************
1387 * Misc commands 1377 * Misc commands
1388 **************************************************************************/ 1378 **************************************************************************/
1389 static gboolean 1379 static void
1390 url_cmd(MsnServConn *servconn, const char *command, const char **params, 1380 url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1391 size_t param_count) 1381 {
1392 { 1382 MsnSession *session;
1393 MsnSession *session = servconn->session; 1383 GaimAccount *account;
1394 GaimAccount *account = session->account;
1395 const char *rru; 1384 const char *rru;
1396 const char *url; 1385 const char *url;
1397 md5_state_t st; 1386 md5_state_t st;
1398 md5_byte_t di[16]; 1387 md5_byte_t di[16];
1399 FILE *fd; 1388 FILE *fd;
1400 char buf[2048]; 1389 char buf[2048];
1401 char buf2[3]; 1390 char buf2[3];
1402 char sendbuf[64]; 1391 char sendbuf[64];
1403 int i; 1392 int i;
1404 1393
1405 rru = params[1]; 1394 session = cmdproc->session;
1406 url = params[2]; 1395 account = session->account;
1396
1397 rru = cmd->params[1];
1398 url = cmd->params[2];
1407 1399
1408 g_snprintf(buf, sizeof(buf), "%s%lu%s", 1400 g_snprintf(buf, sizeof(buf), "%s%lu%s",
1409 session->passport_info.mspauth, 1401 session->passport_info.mspauth,
1410 time(NULL) - session->passport_info.sl, 1402 time(NULL) - session->passport_info.sl,
1411 gaim_account_get_password(account)); 1403 gaim_account_get_password(account));
1414 md5_append(&st, (const md5_byte_t *)buf, strlen(buf)); 1406 md5_append(&st, (const md5_byte_t *)buf, strlen(buf));
1415 md5_finish(&st, di); 1407 md5_finish(&st, di);
1416 1408
1417 memset(sendbuf, 0, sizeof(sendbuf)); 1409 memset(sendbuf, 0, sizeof(sendbuf));
1418 1410
1419 for (i = 0; i < 16; i++) { 1411 for (i = 0; i < 16; i++)
1412 {
1420 g_snprintf(buf2, sizeof(buf2), "%02x", di[i]); 1413 g_snprintf(buf2, sizeof(buf2), "%02x", di[i]);
1421 strcat(sendbuf, buf2); 1414 strcat(sendbuf, buf2);
1422 } 1415 }
1423 1416
1424 if (session->passport_info.file != NULL) { 1417 if (session->passport_info.file != NULL)
1418 {
1425 unlink(session->passport_info.file); 1419 unlink(session->passport_info.file);
1426 g_free(session->passport_info.file); 1420 g_free(session->passport_info.file);
1427 } 1421 }
1428 1422
1429 if ((fd = gaim_mkstemp(&session->passport_info.file)) == NULL) { 1423 if ((fd = gaim_mkstemp(&session->passport_info.file)) == NULL)
1424 {
1430 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1425 gaim_debug(GAIM_DEBUG_ERROR, "msn",
1431 "Error opening temp passport file: %s\n", 1426 "Error opening temp passport file: %s\n",
1432 strerror(errno)); 1427 strerror(errno));
1433 } 1428 }
1434 else { 1429 else
1430 {
1435 fputs("<html>\n" 1431 fputs("<html>\n"
1436 "<head>\n" 1432 "<head>\n"
1437 "<noscript>\n" 1433 "<noscript>\n"
1438 "<meta http-equiv=\"Refresh\" content=\"0; " 1434 "<meta http-equiv=\"Refresh\" content=\"0; "
1439 "url=http://www.hotmail.com\">\n" 1435 "url=http://www.hotmail.com\">\n"
1465 fprintf(fd, "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n"); 1461 fprintf(fd, "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n");
1466 fprintf(fd, "<input type=\"hidden\" name=\"js\" value=\"yes\">\n"); 1462 fprintf(fd, "<input type=\"hidden\" name=\"js\" value=\"yes\">\n");
1467 fprintf(fd, "</form></body>\n"); 1463 fprintf(fd, "</form></body>\n");
1468 fprintf(fd, "</html>\n"); 1464 fprintf(fd, "</html>\n");
1469 1465
1470 if (fclose(fd)) { 1466 if (fclose(fd))
1467 {
1471 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1468 gaim_debug(GAIM_DEBUG_ERROR, "msn",
1472 "Error closing temp passport file: %s\n", 1469 "Error closing temp passport file: %s\n",
1473 strerror(errno)); 1470 strerror(errno));
1474 1471
1475 unlink(session->passport_info.file); 1472 unlink(session->passport_info.file);
1476 g_free(session->passport_info.file); 1473 g_free(session->passport_info.file);
1477 } 1474 }
1478 else { 1475 else
1476 {
1479 /* 1477 /*
1480 * Renaming file with .html extension, so that the 1478 * Renaming file with .html extension, so that the
1481 * win32 open_url will work. 1479 * win32 open_url will work.
1482 */ 1480 */
1483 char *tmp; 1481 char *tmp;
1484 1482
1485 if ((tmp = g_strdup_printf("%s.html", 1483 if ((tmp = g_strdup_printf("%s.html",
1486 session->passport_info.file)) != NULL) { 1484 session->passport_info.file)) != NULL)
1487 1485 {
1488 if (rename(session->passport_info.file, tmp) == 0) { 1486 if (rename(session->passport_info.file, tmp) == 0)
1487 {
1489 g_free(session->passport_info.file); 1488 g_free(session->passport_info.file);
1490 session->passport_info.file = tmp; 1489 session->passport_info.file = tmp;
1491 } 1490 }
1492 else 1491 else
1493 g_free(tmp); 1492 g_free(tmp);
1494 } 1493 }
1495 } 1494 }
1496 } 1495 }
1497
1498 return TRUE;
1499 } 1496 }
1500 /************************************************************************** 1497 /**************************************************************************
1501 * Switchboards 1498 * Switchboards
1502 **************************************************************************/ 1499 **************************************************************************/
1503 static gboolean 1500 static void
1504 rng_cmd(MsnServConn *servconn, const char *command, const char **params, 1501 rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1505 size_t param_count) 1502 {
1506 { 1503 MsnSession *session;
1507 MsnSession *session = servconn->session;
1508 MsnSwitchBoard *swboard; 1504 MsnSwitchBoard *swboard;
1509 MsnUser *user; 1505 MsnUser *user;
1510 const char *session_id; 1506 const char *session_id;
1511 char *host, *c; 1507 char *host, *c;
1512 int port; 1508 int port;
1513 1509
1514 session_id = params[0]; 1510 session = cmdproc->session;
1515 1511 session_id = cmd->params[0];
1516 host = g_strdup(params[1]); 1512
1517 1513 host = g_strdup(cmd->params[1]);
1518 if ((c = strchr(host, ':')) != NULL) { 1514
1515 if ((c = strchr(host, ':')) != NULL)
1516 {
1519 *c = '\0'; 1517 *c = '\0';
1520 port = atoi(c + 1); 1518 port = atoi(c + 1);
1521 } 1519 }
1522 else 1520 else
1523 port = 1863; 1521 port = 1863;
1525 if (session->http_method) 1523 if (session->http_method)
1526 port = 80; 1524 port = 80;
1527 1525
1528 swboard = msn_switchboard_new(session); 1526 swboard = msn_switchboard_new(session);
1529 1527
1530 user = msn_user_new(session, params[4], NULL); 1528 user = msn_user_new(session, cmd->params[4], NULL);
1531 1529
1532 msn_switchboard_set_invited(swboard, TRUE); 1530 msn_switchboard_set_invited(swboard, TRUE);
1533 msn_switchboard_set_session_id(swboard, params[0]); 1531 msn_switchboard_set_session_id(swboard, cmd->params[0]);
1534 msn_switchboard_set_auth_key(swboard, params[3]); 1532 msn_switchboard_set_auth_key(swboard, cmd->params[3]);
1535 msn_switchboard_set_user(swboard, user); 1533 msn_switchboard_set_user(swboard, user);
1536 1534
1537 if (!msn_switchboard_connect(swboard, host, port)) { 1535 if (!msn_switchboard_connect(swboard, host, port))
1536 {
1538 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1537 gaim_debug(GAIM_DEBUG_ERROR, "msn",
1539 "Unable to connect to switchboard on %s, port %d\n", 1538 "Unable to connect to switchboard on %s, port %d\n",
1540 host, port); 1539 host, port);
1541 1540
1542 g_free(host); 1541 g_free(host);
1543 1542
1544 return FALSE; 1543 return;
1545 } 1544 }
1546 1545
1547 g_free(host); 1546 g_free(host);
1548 1547 }
1549 return TRUE; 1548
1550 } 1549 static void
1551 1550 xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1552 static gboolean 1551 {
1553 xfr_cmd(MsnServConn *servconn, const char *command, const char **params, 1552 MsnSession *session;
1554 size_t param_count)
1555 {
1556 MsnSession *session = servconn->session;
1557 MsnSwitchBoard *swboard; 1553 MsnSwitchBoard *swboard;
1558 GaimConnection *gc = session->account->gc; 1554 GaimConnection *gc;
1559 char *host; 1555 char *host;
1560 char *c; 1556 char *c;
1561 int port; 1557 int port;
1562 1558
1563 if (strcmp(params[1], "SB") && strcmp(params[1], "NS")) { 1559 session = cmdproc->session;
1560 gc = session->account->gc;
1561
1562 if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
1563 {
1564 gaim_connection_error(gc, _("Got invalid XFR")); 1564 gaim_connection_error(gc, _("Got invalid XFR"));
1565 1565
1566 return FALSE; 1566 return;
1567 } 1567 }
1568 1568
1569 host = g_strdup(params[2]); 1569 host = g_strdup(cmd->params[2]);
1570 1570
1571 if ((c = strchr(host, ':')) != NULL) { 1571 if ((c = strchr(host, ':')) != NULL)
1572 {
1572 *c = '\0'; 1573 *c = '\0';
1573 port = atoi(c + 1); 1574 port = atoi(c + 1);
1574 } 1575 }
1575 else 1576 else
1576 port = 1863; 1577 port = 1863;
1577 1578
1578 if (!strcmp(params[1], "SB")) { 1579 if (!strcmp(cmd->params[1], "SB"))
1580 {
1579 swboard = msn_session_find_unused_switch(session); 1581 swboard = msn_session_find_unused_switch(session);
1580 1582
1581 if (swboard == NULL) { 1583 if (swboard == NULL)
1582 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1584 {
1583 "Received an XFR SB request when there's no unused " 1585 gaim_debug_error("msn",
1584 "switchboards!\n"); 1586 "Received an XFR SB request when there's no unused "
1585 return FALSE; 1587 "switchboards!\n");
1586 } 1588 return;
1587 1589 }
1588 msn_switchboard_set_auth_key(swboard, params[4]); 1590
1591 msn_switchboard_set_auth_key(swboard, cmd->params[4]);
1589 1592
1590 if (session->http_method) 1593 if (session->http_method)
1591 port = 80; 1594 port = 80;
1592 1595
1593 if (!msn_switchboard_connect(swboard, host, port)) { 1596 if (!msn_switchboard_connect(swboard, host, port))
1594 gaim_debug(GAIM_DEBUG_ERROR, "msn", 1597 {
1595 "Unable to connect to switchboard on %s, port %d\n", 1598 gaim_debug_error("msn",
1596 host, port); 1599 "Unable to connect to switchboard on %s, port %d\n",
1600 host, port);
1597 1601
1598 g_free(host); 1602 g_free(host);
1599 1603
1600 return FALSE; 1604 return;
1601 } 1605 }
1602 } 1606 }
1603 else if (!strcmp(params[1], "NS")) { 1607 else if (!strcmp(cmd->params[1], "NS"))
1608 {
1604 if (!msn_notification_connect(session->notification_conn, host, 1609 if (!msn_notification_connect(session->notification_conn, host,
1605 port)) 1610 port))
1606 { 1611 {
1607 gaim_connection_error(gc, _("Unable to transfer to " 1612 gaim_connection_error(gc, _("Unable to transfer to "
1608 "notification server")); 1613 "notification server"));
1609 1614
1610 g_free(host); 1615 g_free(host);
1611 1616
1612 return FALSE; 1617 return;
1613 } 1618 }
1614 } 1619 }
1615 1620
1616 g_free(host); 1621 g_free(host);
1617
1618 return TRUE;
1619 } 1622 }
1620 1623
1621 /************************************************************************** 1624 /**************************************************************************
1622 * Message Types 1625 * Message Types
1623 **************************************************************************/ 1626 **************************************************************************/
1624 static gboolean 1627 static void
1625 profile_msg(MsnServConn *servconn, MsnMessage *msg) 1628 profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1626 { 1629 {
1627 MsnSession *session = servconn->session; 1630 MsnSession *session;
1628 const char *value; 1631 const char *value;
1629 1632 const char *passport;
1630 if (strcmp(msg->passport, "Hotmail")) { 1633
1634 session = cmdproc->session;
1635 passport = msg->passport;
1636
1637 if (strcmp(passport, "Hotmail"))
1638 {
1631 /* This isn't an official message. */ 1639 /* This isn't an official message. */
1632 return TRUE; 1640 return;
1633 } 1641 }
1634 1642
1635 if ((value = msn_message_get_attr(msg, "kv")) != NULL) 1643 if ((value = msn_message_get_attr(msg, "kv")) != NULL)
1636 session->passport_info.kv = g_strdup(value); 1644 session->passport_info.kv = g_strdup(value);
1637 1645
1644 if ((value = msn_message_get_attr(msg, "ClientIP")) != NULL) 1652 if ((value = msn_message_get_attr(msg, "ClientIP")) != NULL)
1645 session->passport_info.client_ip = g_strdup(value); 1653 session->passport_info.client_ip = g_strdup(value);
1646 1654
1647 if ((value = msn_message_get_attr(msg, "ClientPort")) != NULL) 1655 if ((value = msn_message_get_attr(msg, "ClientPort")) != NULL)
1648 session->passport_info.client_port = ntohs(atoi(value)); 1656 session->passport_info.client_port = ntohs(atoi(value));
1649 1657 }
1650 return TRUE; 1658
1651 } 1659 static void
1652 1660 initial_email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1653 static gboolean 1661 {
1654 initial_email_msg(MsnServConn *servconn, MsnMessage *msg) 1662 MsnSession *session;
1655 { 1663 GaimConnection *gc;
1656 MsnSession *session = servconn->session;
1657 GaimConnection *gc = session->account->gc;
1658 GHashTable *table; 1664 GHashTable *table;
1659 const char *unread; 1665 const char *unread;
1660 1666 const char *passport;
1661 if (strcmp(msg->passport, "Hotmail")) { 1667
1668 session = cmdproc->session;
1669 gc = session->account->gc;
1670 passport = msg->passport;
1671
1672 if (strcmp(passport, "Hotmail"))
1673 {
1662 /* This isn't an official message. */ 1674 /* This isn't an official message. */
1663 return TRUE; 1675 return;
1664 } 1676 }
1665 1677
1666 if (!gaim_account_get_check_mail(session->account)) 1678 if (!gaim_account_get_check_mail(session->account))
1667 return TRUE; 1679 return;
1668 1680
1669 if (session->passport_info.file == NULL) { 1681 if (session->passport_info.file == NULL)
1670 msn_servconn_send_command(servconn, "URL", "INBOX"); 1682 {
1671 1683 msn_cmdproc_send(cmdproc, "URL", "%s", "INBOX");
1672 msn_servconn_queue_message(servconn, "URL", msg); 1684
1673 1685 msn_cmdproc_queue_message(cmdproc, "URL", msg);
1674 return TRUE; 1686
1687 return;
1675 } 1688 }
1676 1689
1677 table = msn_message_get_hashtable_from_body(msg); 1690 table = msn_message_get_hashtable_from_body(msg);
1678 1691
1679 unread = g_hash_table_lookup(table, "Inbox-Unread"); 1692 unread = g_hash_table_lookup(table, "Inbox-Unread");
1680 1693
1681 if (unread != NULL) { 1694 if (unread != NULL)
1695 {
1682 int count = atoi(unread); 1696 int count = atoi(unread);
1683 1697
1684 if (count != 0) 1698 if (count != 0)
1685 { 1699 {
1686 const char *passport = msn_user_get_passport(session->user); 1700 const char *passport = msn_user_get_passport(session->user);
1694 g_free (url); 1708 g_free (url);
1695 } 1709 }
1696 } 1710 }
1697 1711
1698 g_hash_table_destroy(table); 1712 g_hash_table_destroy(table);
1699 1713 }
1700 return TRUE; 1714
1701 } 1715 static void
1702 1716 email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1703 static gboolean 1717 {
1704 email_msg(MsnServConn *servconn, MsnMessage *msg) 1718 MsnSession *session;
1705 { 1719 GaimConnection *gc;
1706 MsnSession *session = servconn->session;
1707 GaimConnection *gc = session->account->gc;
1708 GHashTable *table; 1720 GHashTable *table;
1709 char *from, *subject, *tmp; 1721 char *from, *subject, *tmp;
1722 const char *passport;
1723
1724 session = cmdproc->session;
1725 gc = session->account->gc;
1726 passport = msg->passport;
1710 1727
1711 from = subject = NULL; 1728 from = subject = NULL;
1712 1729
1713 if (strcmp(msg->passport, "Hotmail")) { 1730 if (strcmp(passport, "Hotmail"))
1731 {
1714 /* This isn't an official message. */ 1732 /* This isn't an official message. */
1715 return TRUE; 1733 return;
1716 } 1734 }
1717 1735
1718 if (!gaim_account_get_check_mail(session->account)) 1736 if (!gaim_account_get_check_mail(session->account))
1719 return TRUE; 1737 return;
1720 1738
1721 if (session->passport_info.file == NULL) { 1739 if (session->passport_info.file == NULL)
1722 msn_servconn_send_command(servconn, "URL", "INBOX"); 1740 {
1723 1741 msn_cmdproc_send(cmdproc, "URL", "%s", "INBOX");
1724 msn_servconn_queue_message(servconn, "URL", msg); 1742
1725 1743 msn_cmdproc_queue_message(cmdproc, "URL", msg);
1726 return TRUE; 1744
1745 return;
1727 } 1746 }
1728 1747
1729 table = msn_message_get_hashtable_from_body(msg); 1748 table = msn_message_get_hashtable_from_body(msg);
1730 1749
1731 tmp = g_hash_table_lookup(table, "From"); 1750 tmp = g_hash_table_lookup(table, "From");
1745 1764
1746 if (subject != NULL) 1765 if (subject != NULL)
1747 g_free(subject); 1766 g_free(subject);
1748 1767
1749 g_hash_table_destroy(table); 1768 g_hash_table_destroy(table);
1750 1769 }
1751 return TRUE; 1770
1752 } 1771 static void
1753 1772 system_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
1754 static gboolean
1755 system_msg(MsnServConn *servconn, MsnMessage *msg)
1756 { 1773 {
1757 GHashTable *table; 1774 GHashTable *table;
1758 const char *type_s; 1775 const char *type_s;
1759 1776 const char *passport;
1760 if (strcmp(msg->passport, "Hotmail")) { 1777
1778 passport = msg->passport;
1779
1780 if (strcmp(passport, "Hotmail"))
1781 {
1761 /* This isn't an official message. */ 1782 /* This isn't an official message. */
1762 return TRUE; 1783 return;
1763 } 1784 }
1764 1785
1765 table = msn_message_get_hashtable_from_body(msg); 1786 table = msn_message_get_hashtable_from_body(msg);
1766 1787
1767 if ((type_s = g_hash_table_lookup(table, "Type")) != NULL) { 1788 if ((type_s = g_hash_table_lookup(table, "Type")) != NULL)
1789 {
1768 int type = atoi(type_s); 1790 int type = atoi(type_s);
1769 char buf[MSN_BUF_LEN]; 1791 char buf[MSN_BUF_LEN];
1770 int minutes; 1792 int minutes;
1771 1793
1772 switch (type) { 1794 switch (type)
1795 {
1773 case 1: 1796 case 1:
1774 minutes = atoi(g_hash_table_lookup(table, "Arg1")); 1797 minutes = atoi(g_hash_table_lookup(table, "Arg1"));
1775 g_snprintf(buf, sizeof(buf), ngettext( 1798 g_snprintf(buf, sizeof(buf), ngettext(
1776 "The MSN server will shut down for maintenance " 1799 "The MSN server will shut down for maintenance "
1777 "in %d minute. You will automatically be " 1800 "in %d minute. You will automatically be "
1789 default: 1812 default:
1790 break; 1813 break;
1791 } 1814 }
1792 1815
1793 if (*buf != '\0') 1816 if (*buf != '\0')
1794 gaim_notify_info(servconn->session->account->gc, NULL, buf, NULL); 1817 gaim_notify_info(cmdproc->session->account->gc, NULL, buf, NULL);
1795 } 1818 }
1796 1819
1797 g_hash_table_destroy(table); 1820 g_hash_table_destroy(table);
1798
1799 return TRUE;
1800 } 1821 }
1801 1822
1802 static gboolean 1823 static gboolean
1803 connect_cb(MsnServConn *servconn) 1824 connect_cb(MsnServConn *servconn)
1804 { 1825 {
1805 MsnSession *session = servconn->session; 1826 MsnCmdProc *cmdproc;
1806 GaimAccount *account = session->account; 1827 MsnSession *session;
1807 GaimConnection *gc = gaim_account_get_connection(account); 1828 GaimAccount *account;
1808 char proto_vers[256]; 1829 GaimConnection *gc;
1830 char **a, **c, *vers;
1809 size_t i; 1831 size_t i;
1810 1832
1811 proto_vers[0] = '\0'; 1833 g_return_val_if_fail(servconn != NULL, FALSE);
1812 1834
1813 for (i = 7; i <= session->protocol_ver; i++) 1835 cmdproc = servconn->cmdproc;
1814 { 1836 session = servconn->session;
1815 char old_buf[256]; 1837 account = session->account;
1816 1838 gc = gaim_account_get_connection(account);
1817 strcpy(old_buf, proto_vers); 1839
1818 1840 /* Allocate an array for CVR0, NULL, and all the versions */
1819 g_snprintf(proto_vers, sizeof(proto_vers), "MSNP%d %s", (int)i, old_buf); 1841 a = c = g_new0(char *, session->protocol_ver - 8 + 3);
1820 } 1842
1821 1843 for (i = session->protocol_ver; i >= 8; i--)
1822 strncat(proto_vers, "CVR0", sizeof(proto_vers)); 1844 *c++ = g_strdup_printf("MSNP%d", i);
1823 1845
1824 if (!msn_servconn_send_command(servconn, "VER", proto_vers)) 1846 *c++ = g_strdup("CVR0");
1825 { 1847
1826 gaim_connection_error(gc, _("Unable to write to server")); 1848 vers = g_strjoinv(" ", a);
1849
1850 msn_cmdproc_send(cmdproc, "VER", "%s", vers);
1851
1852 g_strfreev(a);
1853 g_free(vers);
1854
1855 if (cmdproc->error)
1827 return FALSE; 1856 return FALSE;
1828 }
1829 1857
1830 session->user = msn_user_new(session, 1858 session->user = msn_user_new(session,
1831 gaim_account_get_username(account), NULL); 1859 gaim_account_get_username(account), NULL);
1832 1860
1833 gaim_connection_update_progress(gc, _("Syncing with server"), 1861 gaim_connection_update_progress(gc, _("Syncing with server"),
1834 4, MSN_CONNECT_STEPS); 1862 4, MSN_CONNECT_STEPS);
1835 1863
1836 return TRUE; 1864 return TRUE;
1837 } 1865 }
1838 1866
1867 void
1868 msn_notification_init(void)
1869 {
1870 cbs_table = msn_table_new();
1871
1872 /* Register the command callbacks. */
1873
1874 /* Syncing */
1875 msn_table_add_cmd(cbs_table, NULL, "GTC", NULL);
1876 msn_table_add_cmd(cbs_table, NULL, "BLP", blp_cmd);
1877 msn_table_add_cmd(cbs_table, NULL, "PRP", prp_cmd);
1878 msn_table_add_cmd(cbs_table, NULL, "LSG", lsg_cmd);
1879 msn_table_add_cmd(cbs_table, NULL, "LST", lst_cmd);
1880 msn_table_add_cmd(cbs_table, NULL, "BPR", bpr_cmd);
1881
1882 /* Syncronous */
1883 /* msn_table_add_cmd(cbs_table, "CHG", "CHG", chg_cmd); */
1884 msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd);
1885 msn_table_add_cmd(cbs_table, "ADD", "ADD", add_cmd);
1886 msn_table_add_cmd(cbs_table, "ADD", "ILN", iln_cmd);
1887 msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd);
1888 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd);
1889 msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd);
1890 msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd);
1891 msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd);
1892 msn_table_add_cmd(cbs_table, "INF", "INF", inf_cmd);
1893 msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd);
1894 msn_table_add_cmd(cbs_table, "REA", "REA", rea_cmd);
1895 /* msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd); */
1896 /* msn_table_add_cmd(cbs_table, "BLP", "BLP", blp_cmd); */
1897 msn_table_add_cmd(cbs_table, "REG", "REG", reg_cmd);
1898 msn_table_add_cmd(cbs_table, "ADG", "ADG", adg_cmd);
1899 msn_table_add_cmd(cbs_table, "RMG", "RMG", rmg_cmd);
1900 msn_table_add_cmd(cbs_table, "XFR", "XFR", xfr_cmd);
1901
1902 /* Asyncronous */
1903 msn_table_add_cmd(cbs_table, NULL, "IPG", ipg_cmd);
1904 msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd);
1905 msn_table_add_cmd(cbs_table, NULL, "NOT", not_cmd);
1906
1907 msn_table_add_cmd(cbs_table, NULL, "CHL", chl_cmd);
1908 msn_table_add_cmd(cbs_table, NULL, "REM", rem_cmd);
1909 msn_table_add_cmd(cbs_table, NULL, "ADD", add_cmd);
1910
1911 msn_table_add_cmd(cbs_table, NULL, "QRY", NULL);
1912 msn_table_add_cmd(cbs_table, NULL, "QNG", NULL);
1913 msn_table_add_cmd(cbs_table, NULL, "FLN", fln_cmd);
1914 msn_table_add_cmd(cbs_table, NULL, "NLN", nln_cmd);
1915 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd);
1916 msn_table_add_cmd(cbs_table, NULL, "RNG", rng_cmd);
1917
1918 msn_table_add_cmd(cbs_table, NULL, "URL", url_cmd);
1919
1920 msn_table_add_error(cbs_table, "ADD", add_error);
1921
1922 /* Register the message type callbacks. */
1923 msn_table_add_msg_type(cbs_table,
1924 "text/x-msmsgsprofile",
1925 profile_msg);
1926 msn_table_add_msg_type(cbs_table,
1927 "text/x-msmsgsinitialemailnotification",
1928 initial_email_msg);
1929 msn_table_add_msg_type(cbs_table,
1930 "text/x-msmsgsemailnotification",
1931 email_msg);
1932 msn_table_add_msg_type(cbs_table,
1933 "application/x-msmsgssystemmessage",
1934 system_msg);
1935 }
1936
1937 void
1938 msn_notification_end(void)
1939 {
1940 msn_table_destroy(cbs_table);
1941 }
1942
1839 MsnServConn * 1943 MsnServConn *
1840 msn_notification_new(MsnSession *session) 1944 msn_notification_new(MsnSession *session)
1841 { 1945 {
1842 MsnServConn *notification; 1946 MsnServConn *notification;
1843 1947 MsnCmdProc *cmdproc;
1844 notification = msn_servconn_new(session); 1948
1949 notification = msn_servconn_new(session, MSN_SERVER_NS);
1950 cmdproc = notification->cmdproc;
1845 1951
1846 msn_servconn_set_connect_cb(notification, connect_cb); 1952 msn_servconn_set_connect_cb(notification, connect_cb);
1847 1953
1848 if (session->http_method) 1954 if (session->http_method)
1849 notification->http_data->server_type = "NS"; 1955 notification->http_data->server_type = "NS";
1850 1956
1851 if (notification_commands == NULL) { 1957 cmdproc->cbs_table = cbs_table;
1852 /* Register the command callbacks. */
1853 msn_servconn_register_command(notification, "ADD", add_cmd);
1854 msn_servconn_register_command(notification, "ADG", adg_cmd);
1855 msn_servconn_register_command(notification, "BLP", blp_cmd);
1856 msn_servconn_register_command(notification, "BPR", bpr_cmd);
1857 msn_servconn_register_command(notification, "CHG", blank_cmd);
1858 msn_servconn_register_command(notification, "CHL", chl_cmd);
1859 msn_servconn_register_command(notification, "CVR", cvr_cmd);
1860 msn_servconn_register_command(notification, "FLN", fln_cmd);
1861 msn_servconn_register_command(notification, "GTC", blank_cmd);
1862 msn_servconn_register_command(notification, "ILN", iln_cmd);
1863 msn_servconn_register_command(notification, "INF", inf_cmd);
1864 msn_servconn_register_command(notification, "IPG", ipg_cmd);
1865 msn_servconn_register_command(notification, "LSG", lsg_cmd);
1866 msn_servconn_register_command(notification, "LST", lst_cmd);
1867 msn_servconn_register_command(notification, "MSG", msg_cmd);
1868 msn_servconn_register_command(notification, "NLN", nln_cmd);
1869 msn_servconn_register_command(notification, "NOT", not_cmd);
1870 msn_servconn_register_command(notification, "OUT", out_cmd);
1871 msn_servconn_register_command(notification, "PRP", prp_cmd);
1872 msn_servconn_register_command(notification, "QNG", blank_cmd);
1873 msn_servconn_register_command(notification, "QRY", blank_cmd);
1874 msn_servconn_register_command(notification, "REA", rea_cmd);
1875 msn_servconn_register_command(notification, "REG", reg_cmd);
1876 msn_servconn_register_command(notification, "REM", rem_cmd);
1877 msn_servconn_register_command(notification, "RMG", rmg_cmd);
1878 msn_servconn_register_command(notification, "RNG", rng_cmd);
1879 msn_servconn_register_command(notification, "SYN", syn_cmd);
1880 msn_servconn_register_command(notification, "URL", url_cmd);
1881 msn_servconn_register_command(notification, "USR", usr_cmd);
1882 msn_servconn_register_command(notification, "VER", ver_cmd);
1883 msn_servconn_register_command(notification, "XFR", xfr_cmd);
1884 msn_servconn_register_command(notification, "_UNKNOWN_", unknown_cmd);
1885
1886 /* Register the message type callbacks. */
1887 msn_servconn_register_msg_type(notification, "text/x-msmsgsprofile",
1888 profile_msg);
1889 msn_servconn_register_msg_type(notification,
1890 "text/x-msmsgsinitialemailnotification",
1891 initial_email_msg);
1892 msn_servconn_register_msg_type(notification,
1893 "text/x-msmsgsemailnotification",
1894 email_msg);
1895 msn_servconn_register_msg_type(notification,
1896 "application/x-msmsgssystemmessage",
1897 system_msg);
1898
1899 /* Save these for future use. */
1900 notification_commands = notification->commands;
1901 notification_msg_types = notification->msg_types;
1902 }
1903 else {
1904 g_hash_table_destroy(notification->commands);
1905 g_hash_table_destroy(notification->msg_types);
1906
1907 notification->commands = notification_commands;
1908 notification->msg_types = notification_msg_types;
1909 }
1910 1958
1911 return notification; 1959 return notification;
1912 } 1960 }
1913 1961
1914 gboolean 1962 gboolean