| |
1 /** |
| |
2 * @file notification.c Notification server functions |
| |
3 * |
| |
4 * purple |
| |
5 * |
| |
6 * Purple is the legal property of its developers, whose names are too numerous |
| |
7 * to list here. Please refer to the COPYRIGHT file distributed with this |
| |
8 * source distribution. |
| |
9 * |
| |
10 * This program is free software; you can redistribute it and/or modify |
| |
11 * it under the terms of the GNU General Public License as published by |
| |
12 * the Free Software Foundation; either version 2 of the License, or |
| |
13 * (at your option) any later version. |
| |
14 * |
| |
15 * This program is distributed in the hope that it will be useful, |
| |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
18 * GNU General Public License for more details. |
| |
19 * |
| |
20 * You should have received a copy of the GNU General Public License |
| |
21 * along with this program; if not, write to the Free Software |
| |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| |
23 */ |
| |
24 #include "msn.h" |
| |
25 #include "notification.h" |
| |
26 #include "state.h" |
| |
27 #include "error.h" |
| |
28 #include "msn-utils.h" |
| |
29 #include "page.h" |
| |
30 |
| |
31 #include "userlist.h" |
| |
32 #include "sync.h" |
| |
33 #include "slplink.h" |
| |
34 |
| |
35 static MsnTable *cbs_table; |
| |
36 |
| |
37 /************************************************************************** |
| |
38 * Main |
| |
39 **************************************************************************/ |
| |
40 |
| |
41 static void |
| |
42 destroy_cb(MsnServConn *servconn) |
| |
43 { |
| |
44 MsnNotification *notification; |
| |
45 |
| |
46 notification = servconn->cmdproc->data; |
| |
47 g_return_if_fail(notification != NULL); |
| |
48 |
| |
49 msn_notification_destroy(notification); |
| |
50 } |
| |
51 |
| |
52 MsnNotification * |
| |
53 msn_notification_new(MsnSession *session) |
| |
54 { |
| |
55 MsnNotification *notification; |
| |
56 MsnServConn *servconn; |
| |
57 |
| |
58 g_return_val_if_fail(session != NULL, NULL); |
| |
59 |
| |
60 notification = g_new0(MsnNotification, 1); |
| |
61 |
| |
62 notification->session = session; |
| |
63 notification->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_NS); |
| |
64 msn_servconn_set_destroy_cb(servconn, destroy_cb); |
| |
65 |
| |
66 notification->cmdproc = servconn->cmdproc; |
| |
67 notification->cmdproc->data = notification; |
| |
68 notification->cmdproc->cbs_table = cbs_table; |
| |
69 |
| |
70 return notification; |
| |
71 } |
| |
72 |
| |
73 void |
| |
74 msn_notification_destroy(MsnNotification *notification) |
| |
75 { |
| |
76 notification->cmdproc->data = NULL; |
| |
77 |
| |
78 msn_servconn_set_destroy_cb(notification->servconn, NULL); |
| |
79 |
| |
80 msn_servconn_destroy(notification->servconn); |
| |
81 |
| |
82 g_free(notification); |
| |
83 } |
| |
84 |
| |
85 /************************************************************************** |
| |
86 * Connect |
| |
87 **************************************************************************/ |
| |
88 |
| |
89 static void |
| |
90 connect_cb(MsnServConn *servconn) |
| |
91 { |
| |
92 MsnCmdProc *cmdproc; |
| |
93 MsnSession *session; |
| |
94 PurpleAccount *account; |
| |
95 char **a, **c, *vers; |
| |
96 int i; |
| |
97 |
| |
98 g_return_if_fail(servconn != NULL); |
| |
99 |
| |
100 cmdproc = servconn->cmdproc; |
| |
101 session = servconn->session; |
| |
102 account = session->account; |
| |
103 |
| |
104 /* Allocate an array for CVR0, NULL, and all the versions */ |
| |
105 a = c = g_new0(char *, session->protocol_ver - 8 + 3); |
| |
106 |
| |
107 for (i = session->protocol_ver; i >= 8; i--) |
| |
108 *c++ = g_strdup_printf("MSNP%d", i); |
| |
109 |
| |
110 *c++ = g_strdup("CVR0"); |
| |
111 |
| |
112 vers = g_strjoinv(" ", a); |
| |
113 |
| |
114 if (session->login_step == MSN_LOGIN_STEP_START) |
| |
115 msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE); |
| |
116 else |
| |
117 msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE2); |
| |
118 |
| |
119 msn_cmdproc_send(cmdproc, "VER", "%s", vers); |
| |
120 |
| |
121 g_strfreev(a); |
| |
122 g_free(vers); |
| |
123 } |
| |
124 |
| |
125 gboolean |
| |
126 msn_notification_connect(MsnNotification *notification, const char *host, int port) |
| |
127 { |
| |
128 MsnServConn *servconn; |
| |
129 |
| |
130 g_return_val_if_fail(notification != NULL, FALSE); |
| |
131 |
| |
132 servconn = notification->servconn; |
| |
133 |
| |
134 msn_servconn_set_connect_cb(servconn, connect_cb); |
| |
135 notification->in_use = msn_servconn_connect(servconn, host, port); |
| |
136 |
| |
137 return notification->in_use; |
| |
138 } |
| |
139 |
| |
140 void |
| |
141 msn_notification_disconnect(MsnNotification *notification) |
| |
142 { |
| |
143 g_return_if_fail(notification != NULL); |
| |
144 g_return_if_fail(notification->in_use); |
| |
145 |
| |
146 msn_servconn_disconnect(notification->servconn); |
| |
147 |
| |
148 notification->in_use = FALSE; |
| |
149 } |
| |
150 |
| |
151 /************************************************************************** |
| |
152 * Util |
| |
153 **************************************************************************/ |
| |
154 |
| |
155 static void |
| |
156 group_error_helper(MsnSession *session, const char *msg, int group_id, int error) |
| |
157 { |
| |
158 PurpleAccount *account; |
| |
159 PurpleConnection *gc; |
| |
160 char *reason = NULL; |
| |
161 char *title = NULL; |
| |
162 |
| |
163 account = session->account; |
| |
164 gc = purple_account_get_connection(account); |
| |
165 |
| |
166 if (error == 224) |
| |
167 { |
| |
168 if (group_id == 0) |
| |
169 { |
| |
170 return; |
| |
171 } |
| |
172 else |
| |
173 { |
| |
174 const char *group_name; |
| |
175 group_name = |
| |
176 msn_userlist_find_group_name(session->userlist, |
| |
177 group_id); |
| |
178 reason = g_strdup_printf(_("%s is not a valid group."), |
| |
179 group_name); |
| |
180 } |
| |
181 } |
| |
182 else |
| |
183 { |
| |
184 reason = g_strdup(_("Unknown error.")); |
| |
185 } |
| |
186 |
| |
187 title = g_strdup_printf(_("%s on %s (%s)"), msg, |
| |
188 purple_account_get_username(account), |
| |
189 purple_account_get_protocol_name(account)); |
| |
190 purple_notify_error(gc, NULL, title, reason); |
| |
191 g_free(title); |
| |
192 g_free(reason); |
| |
193 } |
| |
194 |
| |
195 /************************************************************************** |
| |
196 * Login |
| |
197 **************************************************************************/ |
| |
198 |
| |
199 void |
| |
200 msn_got_login_params(MsnSession *session, const char *login_params) |
| |
201 { |
| |
202 MsnCmdProc *cmdproc; |
| |
203 |
| |
204 cmdproc = session->notification->cmdproc; |
| |
205 |
| |
206 msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END); |
| |
207 |
| |
208 msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params); |
| |
209 } |
| |
210 |
| |
211 static void |
| |
212 cvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
213 { |
| |
214 PurpleAccount *account; |
| |
215 |
| |
216 account = cmdproc->session->account; |
| |
217 |
| |
218 msn_cmdproc_send(cmdproc, "USR", "TWN I %s", |
| |
219 purple_account_get_username(account)); |
| |
220 } |
| |
221 |
| |
222 static void |
| |
223 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
224 { |
| |
225 MsnSession *session; |
| |
226 PurpleAccount *account; |
| |
227 PurpleConnection *gc; |
| |
228 |
| |
229 session = cmdproc->session; |
| |
230 account = session->account; |
| |
231 gc = purple_account_get_connection(account); |
| |
232 |
| |
233 if (!g_ascii_strcasecmp(cmd->params[1], "OK")) |
| |
234 { |
| |
235 /* OK */ |
| |
236 const char *friendly = purple_url_decode(cmd->params[3]); |
| |
237 |
| |
238 purple_connection_set_display_name(gc, friendly); |
| |
239 |
| |
240 msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN); |
| |
241 |
| |
242 msn_cmdproc_send(cmdproc, "SYN", "%s", "0"); |
| |
243 } |
| |
244 else if (!g_ascii_strcasecmp(cmd->params[1], "TWN")) |
| |
245 { |
| |
246 /* Passport authentication */ |
| |
247 char **elems, **cur, **tokens; |
| |
248 |
| |
249 session->nexus = msn_nexus_new(session); |
| |
250 |
| |
251 /* Parse the challenge data. */ |
| |
252 |
| |
253 elems = g_strsplit(cmd->params[3], ",", 0); |
| |
254 |
| |
255 for (cur = elems; *cur != NULL; cur++) |
| |
256 { |
| |
257 tokens = g_strsplit(*cur, "=", 2); |
| |
258 g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]); |
| |
259 /* Don't free each of the tokens, only the array. */ |
| |
260 g_free(tokens); |
| |
261 } |
| |
262 |
| |
263 g_strfreev(elems); |
| |
264 |
| |
265 msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START); |
| |
266 |
| |
267 msn_nexus_connect(session->nexus); |
| |
268 } |
| |
269 } |
| |
270 |
| |
271 static void |
| |
272 usr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
273 { |
| |
274 MsnErrorType msnerr = 0; |
| |
275 |
| |
276 switch (error) |
| |
277 { |
| |
278 case 500: |
| |
279 case 601: |
| |
280 case 910: |
| |
281 case 921: |
| |
282 msnerr = MSN_ERROR_SERV_UNAVAILABLE; |
| |
283 break; |
| |
284 case 911: |
| |
285 msnerr = MSN_ERROR_AUTH; |
| |
286 break; |
| |
287 default: |
| |
288 return; |
| |
289 break; |
| |
290 } |
| |
291 |
| |
292 msn_session_set_error(cmdproc->session, msnerr, NULL); |
| |
293 } |
| |
294 |
| |
295 static void |
| |
296 ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
297 { |
| |
298 MsnSession *session; |
| |
299 PurpleAccount *account; |
| |
300 gboolean protocol_supported = FALSE; |
| |
301 char proto_str[8]; |
| |
302 size_t i; |
| |
303 |
| |
304 session = cmdproc->session; |
| |
305 account = session->account; |
| |
306 |
| |
307 g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver); |
| |
308 |
| |
309 for (i = 1; i < cmd->param_count; i++) |
| |
310 { |
| |
311 if (!strcmp(cmd->params[i], proto_str)) |
| |
312 { |
| |
313 protocol_supported = TRUE; |
| |
314 break; |
| |
315 } |
| |
316 } |
| |
317 |
| |
318 if (!protocol_supported) |
| |
319 { |
| |
320 msn_session_set_error(session, MSN_ERROR_UNSUPPORTED_PROTOCOL, |
| |
321 NULL); |
| |
322 return; |
| |
323 } |
| |
324 |
| |
325 msn_cmdproc_send(cmdproc, "CVR", |
| |
326 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s", |
| |
327 purple_account_get_username(account)); |
| |
328 } |
| |
329 |
| |
330 /************************************************************************** |
| |
331 * Log out |
| |
332 **************************************************************************/ |
| |
333 |
| |
334 static void |
| |
335 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
336 { |
| |
337 if (!g_ascii_strcasecmp(cmd->params[0], "OTH")) |
| |
338 msn_session_set_error(cmdproc->session, MSN_ERROR_SIGN_OTHER, |
| |
339 NULL); |
| |
340 else if (!g_ascii_strcasecmp(cmd->params[0], "SSD")) |
| |
341 msn_session_set_error(cmdproc->session, MSN_ERROR_SERV_DOWN, NULL); |
| |
342 } |
| |
343 |
| |
344 void |
| |
345 msn_notification_close(MsnNotification *notification) |
| |
346 { |
| |
347 g_return_if_fail(notification != NULL); |
| |
348 |
| |
349 if (!notification->in_use) |
| |
350 return; |
| |
351 |
| |
352 msn_cmdproc_send_quick(notification->cmdproc, "OUT", NULL, NULL); |
| |
353 |
| |
354 msn_notification_disconnect(notification); |
| |
355 } |
| |
356 |
| |
357 /************************************************************************** |
| |
358 * Messages |
| |
359 **************************************************************************/ |
| |
360 |
| |
361 static void |
| |
362 msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, |
| |
363 size_t len) |
| |
364 { |
| |
365 MsnMessage *msg; |
| |
366 |
| |
367 msg = msn_message_new_from_cmd(cmdproc->session, cmd); |
| |
368 |
| |
369 msn_message_parse_payload(msg, payload, len); |
| |
370 #ifdef MSN_DEBUG_NS |
| |
371 msn_message_show_readable(msg, "Notification", TRUE); |
| |
372 #endif |
| |
373 |
| |
374 msn_cmdproc_process_msg(cmdproc, msg); |
| |
375 |
| |
376 msn_message_destroy(msg); |
| |
377 } |
| |
378 |
| |
379 static void |
| |
380 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
381 { |
| |
382 /* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued |
| |
383 * command and we are processing it */ |
| |
384 |
| |
385 if (cmd->payload == NULL) |
| |
386 { |
| |
387 cmdproc->last_cmd->payload_cb = msg_cmd_post; |
| |
388 cmdproc->servconn->payload_len = atoi(cmd->params[2]); |
| |
389 } |
| |
390 else |
| |
391 { |
| |
392 g_return_if_fail(cmd->payload_cb != NULL); |
| |
393 |
| |
394 cmd->payload_cb(cmdproc, cmd, cmd->payload, cmd->payload_len); |
| |
395 } |
| |
396 } |
| |
397 |
| |
398 /************************************************************************** |
| |
399 * Challenges |
| |
400 **************************************************************************/ |
| |
401 |
| |
402 static void |
| |
403 chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
404 { |
| |
405 MsnTransaction *trans; |
| |
406 char buf[33]; |
| |
407 const char *challenge_resp; |
| |
408 PurpleCipher *cipher; |
| |
409 PurpleCipherContext *context; |
| |
410 guchar digest[16]; |
| |
411 int i; |
| |
412 |
| |
413 cipher = purple_ciphers_find_cipher("md5"); |
| |
414 context = purple_cipher_context_new(cipher, NULL); |
| |
415 |
| |
416 purple_cipher_context_append(context, (const guchar *)cmd->params[1], |
| |
417 strlen(cmd->params[1])); |
| |
418 |
| |
419 challenge_resp = "VT6PX?UQTM4WM%YR"; |
| |
420 |
| |
421 purple_cipher_context_append(context, (const guchar *)challenge_resp, |
| |
422 strlen(challenge_resp)); |
| |
423 purple_cipher_context_digest(context, sizeof(digest), digest, NULL); |
| |
424 purple_cipher_context_destroy(context); |
| |
425 |
| |
426 for (i = 0; i < 16; i++) |
| |
427 g_snprintf(buf + (i*2), 3, "%02x", digest[i]); |
| |
428 |
| |
429 trans = msn_transaction_new(cmdproc, "QRY", "%s 32", "PROD0038W!61ZTF9"); |
| |
430 |
| |
431 msn_transaction_set_payload(trans, buf, 32); |
| |
432 |
| |
433 msn_cmdproc_send_trans(cmdproc, trans); |
| |
434 } |
| |
435 |
| |
436 /************************************************************************** |
| |
437 * Buddy Lists |
| |
438 **************************************************************************/ |
| |
439 |
| |
440 static void |
| |
441 add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
442 { |
| |
443 MsnSession *session; |
| |
444 MsnUser *user; |
| |
445 const char *list; |
| |
446 const char *passport; |
| |
447 const char *friendly; |
| |
448 MsnListId list_id; |
| |
449 int group_id; |
| |
450 |
| |
451 list = cmd->params[1]; |
| |
452 passport = cmd->params[3]; |
| |
453 friendly = purple_url_decode(cmd->params[4]); |
| |
454 |
| |
455 session = cmdproc->session; |
| |
456 |
| |
457 user = msn_userlist_find_user(session->userlist, passport); |
| |
458 |
| |
459 if (user == NULL) |
| |
460 { |
| |
461 user = msn_user_new(session->userlist, passport, friendly); |
| |
462 msn_userlist_add_user(session->userlist, user); |
| |
463 } |
| |
464 else |
| |
465 msn_user_set_friendly_name(user, friendly); |
| |
466 |
| |
467 list_id = msn_get_list_id(list); |
| |
468 |
| |
469 if (cmd->param_count >= 6) |
| |
470 group_id = atoi(cmd->params[5]); |
| |
471 else |
| |
472 group_id = -1; |
| |
473 |
| |
474 msn_got_add_user(session, user, list_id, group_id); |
| |
475 msn_user_update(user); |
| |
476 } |
| |
477 |
| |
478 static void |
| |
479 add_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
480 { |
| |
481 MsnSession *session; |
| |
482 PurpleAccount *account; |
| |
483 PurpleConnection *gc; |
| |
484 const char *list, *passport; |
| |
485 char *reason = NULL; |
| |
486 char *msg = NULL; |
| |
487 char **params; |
| |
488 |
| |
489 session = cmdproc->session; |
| |
490 account = session->account; |
| |
491 gc = purple_account_get_connection(account); |
| |
492 params = g_strsplit(trans->params, " ", 0); |
| |
493 |
| |
494 list = params[0]; |
| |
495 passport = params[1]; |
| |
496 |
| |
497 if (!strcmp(list, "FL")) |
| |
498 msg = g_strdup_printf(_("Unable to add user on %s (%s)"), |
| |
499 purple_account_get_username(account), |
| |
500 purple_account_get_protocol_name(account)); |
| |
501 else if (!strcmp(list, "BL")) |
| |
502 msg = g_strdup_printf(_("Unable to block user on %s (%s)"), |
| |
503 purple_account_get_username(account), |
| |
504 purple_account_get_protocol_name(account)); |
| |
505 else if (!strcmp(list, "AL")) |
| |
506 msg = g_strdup_printf(_("Unable to permit user on %s (%s)"), |
| |
507 purple_account_get_username(account), |
| |
508 purple_account_get_protocol_name(account)); |
| |
509 |
| |
510 if (!strcmp(list, "FL")) |
| |
511 { |
| |
512 if (error == 210) |
| |
513 { |
| |
514 reason = g_strdup_printf(_("%s could not be added because " |
| |
515 "your buddy list is full."), passport); |
| |
516 } |
| |
517 } |
| |
518 |
| |
519 if (reason == NULL) |
| |
520 { |
| |
521 if (error == 208) |
| |
522 { |
| |
523 reason = g_strdup_printf(_("%s is not a valid passport account."), |
| |
524 passport); |
| |
525 } |
| |
526 else if (error == 500) |
| |
527 { |
| |
528 reason = g_strdup(_("Service Temporarily Unavailable.")); |
| |
529 } |
| |
530 else |
| |
531 { |
| |
532 reason = g_strdup(_("Unknown error.")); |
| |
533 } |
| |
534 } |
| |
535 |
| |
536 if (msg != NULL) |
| |
537 { |
| |
538 purple_notify_error(gc, NULL, msg, reason); |
| |
539 g_free(msg); |
| |
540 } |
| |
541 |
| |
542 if (!strcmp(list, "FL")) |
| |
543 { |
| |
544 PurpleBuddy *buddy; |
| |
545 |
| |
546 buddy = purple_find_buddy(account, passport); |
| |
547 |
| |
548 if (buddy != NULL) |
| |
549 purple_blist_remove_buddy(buddy); |
| |
550 } |
| |
551 |
| |
552 g_free(reason); |
| |
553 |
| |
554 g_strfreev(params); |
| |
555 } |
| |
556 |
| |
557 static void |
| |
558 adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
559 { |
| |
560 MsnSession *session; |
| |
561 gint group_id; |
| |
562 const char *group_name; |
| |
563 |
| |
564 session = cmdproc->session; |
| |
565 |
| |
566 group_id = atoi(cmd->params[3]); |
| |
567 |
| |
568 group_name = purple_url_decode(cmd->params[2]); |
| |
569 |
| |
570 msn_group_new(session->userlist, group_id, group_name); |
| |
571 |
| |
572 /* There is a user that must me moved to this group */ |
| |
573 if (cmd->trans->data) |
| |
574 { |
| |
575 /* msn_userlist_move_buddy(); */ |
| |
576 MsnUserList *userlist = cmdproc->session->userlist; |
| |
577 MsnMoveBuddy *data = cmd->trans->data; |
| |
578 |
| |
579 if (data->old_group_name != NULL) |
| |
580 { |
| |
581 msn_userlist_rem_buddy(userlist, data->who, MSN_LIST_FL, data->old_group_name); |
| |
582 g_free(data->old_group_name); |
| |
583 } |
| |
584 |
| |
585 msn_userlist_add_buddy(userlist, data->who, MSN_LIST_FL, group_name); |
| |
586 g_free(data->who); |
| |
587 |
| |
588 } |
| |
589 } |
| |
590 |
| |
591 static void |
| |
592 qng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
593 { |
| |
594 MsnSession *session; |
| |
595 static int count = 0; |
| |
596 const char *passport; |
| |
597 PurpleAccount *account; |
| |
598 |
| |
599 session = cmdproc->session; |
| |
600 account = session->account; |
| |
601 |
| |
602 if (session->passport_info.file == NULL) |
| |
603 return; |
| |
604 |
| |
605 passport = purple_normalize(account, purple_account_get_username(account)); |
| |
606 |
| |
607 if ((strstr(passport, "@hotmail.") != NULL) || |
| |
608 (strstr(passport, "@msn.com") != NULL)) |
| |
609 return; |
| |
610 |
| |
611 if (count++ < 26) |
| |
612 return; |
| |
613 |
| |
614 count = 0; |
| |
615 msn_cmdproc_send(cmdproc, "URL", "%s", "INBOX"); |
| |
616 } |
| |
617 |
| |
618 |
| |
619 static void |
| |
620 fln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
621 { |
| |
622 MsnSlpLink *slplink; |
| |
623 MsnUser *user; |
| |
624 |
| |
625 user = msn_userlist_find_user(cmdproc->session->userlist, cmd->params[0]); |
| |
626 |
| |
627 user->status = "offline"; |
| |
628 msn_user_update(user); |
| |
629 |
| |
630 slplink = msn_session_find_slplink(cmdproc->session, cmd->params[0]); |
| |
631 |
| |
632 if (slplink != NULL) |
| |
633 msn_slplink_destroy(slplink); |
| |
634 |
| |
635 } |
| |
636 |
| |
637 static void |
| |
638 iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
639 { |
| |
640 MsnSession *session; |
| |
641 PurpleAccount *account; |
| |
642 PurpleConnection *gc; |
| |
643 MsnUser *user; |
| |
644 MsnObject *msnobj; |
| |
645 const char *state, *passport, *friendly; |
| |
646 |
| |
647 session = cmdproc->session; |
| |
648 account = session->account; |
| |
649 gc = purple_account_get_connection(account); |
| |
650 |
| |
651 state = cmd->params[1]; |
| |
652 passport = cmd->params[2]; |
| |
653 friendly = purple_url_decode(cmd->params[3]); |
| |
654 |
| |
655 user = msn_userlist_find_user(session->userlist, passport); |
| |
656 |
| |
657 serv_got_alias(gc, passport, friendly); |
| |
658 |
| |
659 msn_user_set_friendly_name(user, friendly); |
| |
660 |
| |
661 if (session->protocol_ver >= 9 && cmd->param_count == 6) |
| |
662 { |
| |
663 msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[5])); |
| |
664 msn_user_set_object(user, msnobj); |
| |
665 } |
| |
666 |
| |
667 msn_user_set_state(user, state); |
| |
668 msn_user_update(user); |
| |
669 } |
| |
670 |
| |
671 static void |
| |
672 ipg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) |
| |
673 { |
| |
674 #if 0 |
| |
675 purple_debug_misc("msn", "Incoming Page: {%s}\n", payload); |
| |
676 #endif |
| |
677 } |
| |
678 |
| |
679 static void |
| |
680 ipg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
681 { |
| |
682 cmdproc->servconn->payload_len = atoi(cmd->params[0]); |
| |
683 cmdproc->last_cmd->payload_cb = ipg_cmd_post; |
| |
684 } |
| |
685 |
| |
686 static void |
| |
687 nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
688 { |
| |
689 MsnSession *session; |
| |
690 PurpleAccount *account; |
| |
691 PurpleConnection *gc; |
| |
692 MsnUser *user; |
| |
693 MsnObject *msnobj; |
| |
694 int clientid; |
| |
695 const char *state, *passport, *friendly, *old_friendly; |
| |
696 |
| |
697 session = cmdproc->session; |
| |
698 account = session->account; |
| |
699 gc = purple_account_get_connection(account); |
| |
700 |
| |
701 state = cmd->params[0]; |
| |
702 passport = cmd->params[1]; |
| |
703 friendly = purple_url_decode(cmd->params[2]); |
| |
704 |
| |
705 user = msn_userlist_find_user(session->userlist, passport); |
| |
706 |
| |
707 old_friendly = msn_user_get_friendly_name(user); |
| |
708 if (!old_friendly || (old_friendly && (!friendly || strcmp(old_friendly, friendly)))) |
| |
709 { |
| |
710 serv_got_alias(gc, passport, friendly); |
| |
711 msn_user_set_friendly_name(user, friendly); |
| |
712 } |
| |
713 |
| |
714 if (session->protocol_ver >= 9) |
| |
715 { |
| |
716 if (cmd->param_count == 5) |
| |
717 { |
| |
718 msnobj = |
| |
719 msn_object_new_from_string(purple_url_decode(cmd->params[4])); |
| |
720 msn_user_set_object(user, msnobj); |
| |
721 } |
| |
722 else |
| |
723 { |
| |
724 msn_user_set_object(user, NULL); |
| |
725 } |
| |
726 } |
| |
727 |
| |
728 clientid = atoi(cmd->params[3]); |
| |
729 user->mobile = (clientid & MSN_CLIENT_CAP_MSNMOBILE); |
| |
730 |
| |
731 msn_user_set_state(user, state); |
| |
732 msn_user_update(user); |
| |
733 } |
| |
734 |
| |
735 #if 0 |
| |
736 static void |
| |
737 chg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
738 { |
| |
739 char *state = cmd->params[1]; |
| |
740 int state_id = 0; |
| |
741 |
| |
742 if (!strcmp(state, "NLN")) |
| |
743 state_id = MSN_ONLINE; |
| |
744 else if (!strcmp(state, "BSY")) |
| |
745 state_id = MSN_BUSY; |
| |
746 else if (!strcmp(state, "IDL")) |
| |
747 state_id = MSN_IDLE; |
| |
748 else if (!strcmp(state, "BRB")) |
| |
749 state_id = MSN_BRB; |
| |
750 else if (!strcmp(state, "AWY")) |
| |
751 state_id = MSN_AWAY; |
| |
752 else if (!strcmp(state, "PHN")) |
| |
753 state_id = MSN_PHONE; |
| |
754 else if (!strcmp(state, "LUN")) |
| |
755 state_id = MSN_LUNCH; |
| |
756 else if (!strcmp(state, "HDN")) |
| |
757 state_id = MSN_HIDDEN; |
| |
758 |
| |
759 cmdproc->session->state = state_id; |
| |
760 } |
| |
761 #endif |
| |
762 |
| |
763 |
| |
764 static void |
| |
765 not_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) |
| |
766 { |
| |
767 #if 0 |
| |
768 MSN_SET_PARAMS("NOT %d\r\n%s", cmdproc->servconn->payload, payload); |
| |
769 purple_debug_misc("msn", "Notification: {%s}\n", payload); |
| |
770 #endif |
| |
771 } |
| |
772 |
| |
773 static void |
| |
774 not_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
775 { |
| |
776 cmdproc->servconn->payload_len = atoi(cmd->params[0]); |
| |
777 cmdproc->last_cmd->payload_cb = not_cmd_post; |
| |
778 } |
| |
779 |
| |
780 static void |
| |
781 rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
782 { |
| |
783 /* TODO: This might be for us too */ |
| |
784 |
| |
785 MsnSession *session; |
| |
786 PurpleConnection *gc; |
| |
787 const char *friendly; |
| |
788 |
| |
789 session = cmdproc->session; |
| |
790 gc = session->account->gc; |
| |
791 friendly = purple_url_decode(cmd->params[3]); |
| |
792 |
| |
793 purple_connection_set_display_name(gc, friendly); |
| |
794 } |
| |
795 |
| |
796 static void |
| |
797 prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
798 { |
| |
799 MsnSession *session = cmdproc->session; |
| |
800 const char *type, *value; |
| |
801 |
| |
802 g_return_if_fail(cmd->param_count >= 3); |
| |
803 |
| |
804 type = cmd->params[2]; |
| |
805 |
| |
806 if (cmd->param_count == 4) |
| |
807 { |
| |
808 value = cmd->params[3]; |
| |
809 if (!strcmp(type, "PHH")) |
| |
810 msn_user_set_home_phone(session->user, purple_url_decode(value)); |
| |
811 else if (!strcmp(type, "PHW")) |
| |
812 msn_user_set_work_phone(session->user, purple_url_decode(value)); |
| |
813 else if (!strcmp(type, "PHM")) |
| |
814 msn_user_set_mobile_phone(session->user, purple_url_decode(value)); |
| |
815 } |
| |
816 else |
| |
817 { |
| |
818 if (!strcmp(type, "PHH")) |
| |
819 msn_user_set_home_phone(session->user, NULL); |
| |
820 else if (!strcmp(type, "PHW")) |
| |
821 msn_user_set_work_phone(session->user, NULL); |
| |
822 else if (!strcmp(type, "PHM")) |
| |
823 msn_user_set_mobile_phone(session->user, NULL); |
| |
824 } |
| |
825 } |
| |
826 |
| |
827 static void |
| |
828 reg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
829 { |
| |
830 MsnSession *session; |
| |
831 int group_id; |
| |
832 const char *group_name; |
| |
833 |
| |
834 session = cmdproc->session; |
| |
835 group_id = atoi(cmd->params[2]); |
| |
836 group_name = purple_url_decode(cmd->params[3]); |
| |
837 |
| |
838 msn_userlist_rename_group_id(session->userlist, group_id, group_name); |
| |
839 } |
| |
840 |
| |
841 static void |
| |
842 reg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
843 { |
| |
844 int group_id; |
| |
845 char **params; |
| |
846 |
| |
847 params = g_strsplit(trans->params, " ", 0); |
| |
848 |
| |
849 group_id = atoi(params[0]); |
| |
850 |
| |
851 group_error_helper(cmdproc->session, _("Unable to rename group"), group_id, error); |
| |
852 |
| |
853 g_strfreev(params); |
| |
854 } |
| |
855 |
| |
856 static void |
| |
857 rem_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
858 { |
| |
859 MsnSession *session; |
| |
860 MsnUser *user; |
| |
861 const char *list; |
| |
862 const char *passport; |
| |
863 MsnListId list_id; |
| |
864 int group_id; |
| |
865 |
| |
866 session = cmdproc->session; |
| |
867 list = cmd->params[1]; |
| |
868 passport = cmd->params[3]; |
| |
869 user = msn_userlist_find_user(session->userlist, passport); |
| |
870 |
| |
871 g_return_if_fail(user != NULL); |
| |
872 |
| |
873 list_id = msn_get_list_id(list); |
| |
874 |
| |
875 if (cmd->param_count == 5) |
| |
876 group_id = atoi(cmd->params[4]); |
| |
877 else |
| |
878 group_id = -1; |
| |
879 |
| |
880 msn_got_rem_user(session, user, list_id, group_id); |
| |
881 msn_user_update(user); |
| |
882 } |
| |
883 |
| |
884 static void |
| |
885 rmg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
886 { |
| |
887 MsnSession *session; |
| |
888 int group_id; |
| |
889 |
| |
890 session = cmdproc->session; |
| |
891 group_id = atoi(cmd->params[2]); |
| |
892 |
| |
893 msn_userlist_remove_group_id(session->userlist, group_id); |
| |
894 } |
| |
895 |
| |
896 static void |
| |
897 rmg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
898 { |
| |
899 int group_id; |
| |
900 char **params; |
| |
901 |
| |
902 params = g_strsplit(trans->params, " ", 0); |
| |
903 |
| |
904 group_id = atoi(params[0]); |
| |
905 |
| |
906 group_error_helper(cmdproc->session, _("Unable to delete group"), group_id, error); |
| |
907 |
| |
908 g_strfreev(params); |
| |
909 } |
| |
910 |
| |
911 static void |
| |
912 syn_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
913 { |
| |
914 MsnSession *session; |
| |
915 MsnSync *sync; |
| |
916 int total_users; |
| |
917 |
| |
918 session = cmdproc->session; |
| |
919 |
| |
920 if (cmd->param_count == 2) |
| |
921 { |
| |
922 /* |
| |
923 * This can happen if we sent a SYN with an up-to-date |
| |
924 * buddy list revision, but we send 0 to get a full list. |
| |
925 * So, error out. |
| |
926 */ |
| |
927 |
| |
928 msn_session_set_error(cmdproc->session, MSN_ERROR_BAD_BLIST, NULL); |
| |
929 return; |
| |
930 } |
| |
931 |
| |
932 total_users = atoi(cmd->params[2]); |
| |
933 |
| |
934 sync = msn_sync_new(session); |
| |
935 sync->total_users = total_users; |
| |
936 sync->old_cbs_table = cmdproc->cbs_table; |
| |
937 |
| |
938 session->sync = sync; |
| |
939 cmdproc->cbs_table = sync->cbs_table; |
| |
940 } |
| |
941 |
| |
942 /************************************************************************** |
| |
943 * Misc commands |
| |
944 **************************************************************************/ |
| |
945 |
| |
946 static void |
| |
947 url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
948 { |
| |
949 MsnSession *session; |
| |
950 PurpleAccount *account; |
| |
951 const char *rru; |
| |
952 const char *url; |
| |
953 PurpleCipher *cipher; |
| |
954 PurpleCipherContext *context; |
| |
955 guchar digest[16]; |
| |
956 FILE *fd; |
| |
957 char *buf; |
| |
958 char buf2[3]; |
| |
959 char sendbuf[64]; |
| |
960 int i; |
| |
961 |
| |
962 session = cmdproc->session; |
| |
963 account = session->account; |
| |
964 |
| |
965 rru = cmd->params[1]; |
| |
966 url = cmd->params[2]; |
| |
967 |
| |
968 buf = g_strdup_printf("%s%lu%s", |
| |
969 session->passport_info.mspauth ? session->passport_info.mspauth : "BOGUS", |
| |
970 time(NULL) - session->passport_info.sl, |
| |
971 purple_connection_get_password(account->gc)); |
| |
972 |
| |
973 cipher = purple_ciphers_find_cipher("md5"); |
| |
974 context = purple_cipher_context_new(cipher, NULL); |
| |
975 |
| |
976 purple_cipher_context_append(context, (const guchar *)buf, strlen(buf)); |
| |
977 purple_cipher_context_digest(context, sizeof(digest), digest, NULL); |
| |
978 purple_cipher_context_destroy(context); |
| |
979 |
| |
980 g_free(buf); |
| |
981 |
| |
982 memset(sendbuf, 0, sizeof(sendbuf)); |
| |
983 |
| |
984 for (i = 0; i < 16; i++) |
| |
985 { |
| |
986 g_snprintf(buf2, sizeof(buf2), "%02x", digest[i]); |
| |
987 strcat(sendbuf, buf2); |
| |
988 } |
| |
989 |
| |
990 if (session->passport_info.file != NULL) |
| |
991 { |
| |
992 g_unlink(session->passport_info.file); |
| |
993 g_free(session->passport_info.file); |
| |
994 } |
| |
995 |
| |
996 if ((fd = purple_mkstemp(&session->passport_info.file, FALSE)) == NULL) |
| |
997 { |
| |
998 purple_debug_error("msn", |
| |
999 "Error opening temp passport file: %s\n", |
| |
1000 strerror(errno)); |
| |
1001 } |
| |
1002 else |
| |
1003 { |
| |
1004 #ifdef _WIN32 |
| |
1005 fputs("<!-- saved from url=(0013)about:internet -->\n", fd); |
| |
1006 #endif |
| |
1007 fputs("<html>\n" |
| |
1008 "<head>\n" |
| |
1009 "<noscript>\n" |
| |
1010 "<meta http-equiv=\"Refresh\" content=\"0; " |
| |
1011 "url=http://www.hotmail.com\">\n" |
| |
1012 "</noscript>\n" |
| |
1013 "</head>\n\n", |
| |
1014 fd); |
| |
1015 |
| |
1016 fprintf(fd, "<body onload=\"document.pform.submit(); \">\n"); |
| |
1017 fprintf(fd, "<form name=\"pform\" action=\"%s\" method=\"POST\">\n\n", |
| |
1018 url); |
| |
1019 fprintf(fd, "<input type=\"hidden\" name=\"mode\" value=\"ttl\">\n"); |
| |
1020 fprintf(fd, "<input type=\"hidden\" name=\"login\" value=\"%s\">\n", |
| |
1021 purple_account_get_username(account)); |
| |
1022 fprintf(fd, "<input type=\"hidden\" name=\"username\" value=\"%s\">\n", |
| |
1023 purple_account_get_username(account)); |
| |
1024 if (session->passport_info.sid != NULL) |
| |
1025 fprintf(fd, "<input type=\"hidden\" name=\"sid\" value=\"%s\">\n", |
| |
1026 session->passport_info.sid); |
| |
1027 if (session->passport_info.kv != NULL) |
| |
1028 fprintf(fd, "<input type=\"hidden\" name=\"kv\" value=\"%s\">\n", |
| |
1029 session->passport_info.kv); |
| |
1030 fprintf(fd, "<input type=\"hidden\" name=\"id\" value=\"2\">\n"); |
| |
1031 fprintf(fd, "<input type=\"hidden\" name=\"sl\" value=\"%ld\">\n", |
| |
1032 time(NULL) - session->passport_info.sl); |
| |
1033 fprintf(fd, "<input type=\"hidden\" name=\"rru\" value=\"%s\">\n", |
| |
1034 rru); |
| |
1035 if (session->passport_info.mspauth != NULL) |
| |
1036 fprintf(fd, "<input type=\"hidden\" name=\"auth\" value=\"%s\">\n", |
| |
1037 session->passport_info.mspauth); |
| |
1038 fprintf(fd, "<input type=\"hidden\" name=\"creds\" value=\"%s\">\n", |
| |
1039 sendbuf); /* TODO Digest me (huh? -- ChipX86) */ |
| |
1040 fprintf(fd, "<input type=\"hidden\" name=\"svc\" value=\"mail\">\n"); |
| |
1041 fprintf(fd, "<input type=\"hidden\" name=\"js\" value=\"yes\">\n"); |
| |
1042 fprintf(fd, "</form></body>\n"); |
| |
1043 fprintf(fd, "</html>\n"); |
| |
1044 |
| |
1045 if (fclose(fd)) |
| |
1046 { |
| |
1047 purple_debug_error("msn", |
| |
1048 "Error closing temp passport file: %s\n", |
| |
1049 strerror(errno)); |
| |
1050 |
| |
1051 g_unlink(session->passport_info.file); |
| |
1052 g_free(session->passport_info.file); |
| |
1053 session->passport_info.file = NULL; |
| |
1054 } |
| |
1055 #ifdef _WIN32 |
| |
1056 else |
| |
1057 { |
| |
1058 /* |
| |
1059 * Renaming file with .html extension, so that the |
| |
1060 * win32 open_url will work. |
| |
1061 */ |
| |
1062 char *tmp; |
| |
1063 |
| |
1064 if ((tmp = |
| |
1065 g_strdup_printf("%s.html", |
| |
1066 session->passport_info.file)) != NULL) |
| |
1067 { |
| |
1068 if (g_rename(session->passport_info.file, |
| |
1069 tmp) == 0) |
| |
1070 { |
| |
1071 g_free(session->passport_info.file); |
| |
1072 session->passport_info.file = tmp; |
| |
1073 } |
| |
1074 else |
| |
1075 g_free(tmp); |
| |
1076 } |
| |
1077 } |
| |
1078 #endif |
| |
1079 } |
| |
1080 } |
| |
1081 /************************************************************************** |
| |
1082 * Switchboards |
| |
1083 **************************************************************************/ |
| |
1084 |
| |
1085 static void |
| |
1086 rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
1087 { |
| |
1088 MsnSession *session; |
| |
1089 MsnSwitchBoard *swboard; |
| |
1090 const char *session_id; |
| |
1091 char *host; |
| |
1092 int port; |
| |
1093 |
| |
1094 session = cmdproc->session; |
| |
1095 session_id = cmd->params[0]; |
| |
1096 |
| |
1097 msn_parse_socket(cmd->params[1], &host, &port); |
| |
1098 |
| |
1099 if (session->http_method) |
| |
1100 port = 80; |
| |
1101 |
| |
1102 swboard = msn_switchboard_new(session); |
| |
1103 |
| |
1104 msn_switchboard_set_invited(swboard, TRUE); |
| |
1105 msn_switchboard_set_session_id(swboard, cmd->params[0]); |
| |
1106 msn_switchboard_set_auth_key(swboard, cmd->params[3]); |
| |
1107 swboard->im_user = g_strdup(cmd->params[4]); |
| |
1108 /* msn_switchboard_add_user(swboard, cmd->params[4]); */ |
| |
1109 |
| |
1110 if (!msn_switchboard_connect(swboard, host, port)) |
| |
1111 msn_switchboard_destroy(swboard); |
| |
1112 |
| |
1113 g_free(host); |
| |
1114 } |
| |
1115 |
| |
1116 static void |
| |
1117 xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
1118 { |
| |
1119 char *host; |
| |
1120 int port; |
| |
1121 |
| |
1122 if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS")) |
| |
1123 { |
| |
1124 /* Maybe we can have a generic bad command error. */ |
| |
1125 purple_debug_error("msn", "Bad XFR command (%s)\n", cmd->params[1]); |
| |
1126 return; |
| |
1127 } |
| |
1128 |
| |
1129 msn_parse_socket(cmd->params[2], &host, &port); |
| |
1130 |
| |
1131 if (!strcmp(cmd->params[1], "SB")) |
| |
1132 { |
| |
1133 purple_debug_error("msn", "This shouldn't be handled here.\n"); |
| |
1134 } |
| |
1135 else if (!strcmp(cmd->params[1], "NS")) |
| |
1136 { |
| |
1137 MsnSession *session; |
| |
1138 |
| |
1139 session = cmdproc->session; |
| |
1140 |
| |
1141 msn_session_set_login_step(session, MSN_LOGIN_STEP_TRANSFER); |
| |
1142 |
| |
1143 msn_notification_connect(session->notification, host, port); |
| |
1144 } |
| |
1145 |
| |
1146 g_free(host); |
| |
1147 } |
| |
1148 |
| |
1149 /************************************************************************** |
| |
1150 * Message Types |
| |
1151 **************************************************************************/ |
| |
1152 |
| |
1153 static void |
| |
1154 profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
1155 { |
| |
1156 MsnSession *session; |
| |
1157 const char *value; |
| |
1158 |
| |
1159 session = cmdproc->session; |
| |
1160 |
| |
1161 if (strcmp(msg->remote_user, "Hotmail")) |
| |
1162 /* This isn't an official message. */ |
| |
1163 return; |
| |
1164 |
| |
1165 if ((value = msn_message_get_attr(msg, "kv")) != NULL) |
| |
1166 { |
| |
1167 g_free(session->passport_info.kv); |
| |
1168 session->passport_info.kv = g_strdup(value); |
| |
1169 } |
| |
1170 |
| |
1171 if ((value = msn_message_get_attr(msg, "sid")) != NULL) |
| |
1172 { |
| |
1173 g_free(session->passport_info.sid); |
| |
1174 session->passport_info.sid = g_strdup(value); |
| |
1175 } |
| |
1176 |
| |
1177 if ((value = msn_message_get_attr(msg, "MSPAuth")) != NULL) |
| |
1178 { |
| |
1179 g_free(session->passport_info.mspauth); |
| |
1180 session->passport_info.mspauth = g_strdup(value); |
| |
1181 } |
| |
1182 |
| |
1183 if ((value = msn_message_get_attr(msg, "ClientIP")) != NULL) |
| |
1184 { |
| |
1185 g_free(session->passport_info.client_ip); |
| |
1186 session->passport_info.client_ip = g_strdup(value); |
| |
1187 } |
| |
1188 |
| |
1189 if ((value = msn_message_get_attr(msg, "ClientPort")) != NULL) |
| |
1190 session->passport_info.client_port = ntohs(atoi(value)); |
| |
1191 |
| |
1192 if ((value = msn_message_get_attr(msg, "LoginTime")) != NULL) |
| |
1193 session->passport_info.sl = atol(value); |
| |
1194 } |
| |
1195 |
| |
1196 static void |
| |
1197 initial_email_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
1198 { |
| |
1199 MsnSession *session; |
| |
1200 PurpleConnection *gc; |
| |
1201 GHashTable *table; |
| |
1202 const char *unread; |
| |
1203 |
| |
1204 session = cmdproc->session; |
| |
1205 gc = session->account->gc; |
| |
1206 |
| |
1207 if (strcmp(msg->remote_user, "Hotmail")) |
| |
1208 /* This isn't an official message. */ |
| |
1209 return; |
| |
1210 |
| |
1211 if (session->passport_info.file == NULL) |
| |
1212 { |
| |
1213 MsnTransaction *trans; |
| |
1214 trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX"); |
| |
1215 msn_transaction_queue_cmd(trans, msg->cmd); |
| |
1216 |
| |
1217 msn_cmdproc_send_trans(cmdproc, trans); |
| |
1218 |
| |
1219 return; |
| |
1220 } |
| |
1221 |
| |
1222 if (!purple_account_get_check_mail(session->account)) |
| |
1223 return; |
| |
1224 |
| |
1225 table = msn_message_get_hashtable_from_body(msg); |
| |
1226 |
| |
1227 unread = g_hash_table_lookup(table, "Inbox-Unread"); |
| |
1228 |
| |
1229 if (unread != NULL) |
| |
1230 { |
| |
1231 int count = atoi(unread); |
| |
1232 |
| |
1233 if (count > 0) |
| |
1234 { |
| |
1235 const char *passport; |
| |
1236 const char *url; |
| |
1237 |
| |
1238 passport = msn_user_get_passport(session->user); |
| |
1239 url = session->passport_info.file; |
| |
1240 |
| |
1241 purple_notify_emails(gc, atoi(unread), FALSE, NULL, NULL, |
| |
1242 &passport, &url, NULL, NULL); |
| |
1243 } |
| |
1244 } |
| |
1245 |
| |
1246 g_hash_table_destroy(table); |
| |
1247 } |
| |
1248 |
| |
1249 static void |
| |
1250 email_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
1251 { |
| |
1252 MsnSession *session; |
| |
1253 PurpleConnection *gc; |
| |
1254 GHashTable *table; |
| |
1255 char *from, *subject, *tmp; |
| |
1256 |
| |
1257 session = cmdproc->session; |
| |
1258 gc = session->account->gc; |
| |
1259 |
| |
1260 if (strcmp(msg->remote_user, "Hotmail")) |
| |
1261 /* This isn't an official message. */ |
| |
1262 return; |
| |
1263 |
| |
1264 if (session->passport_info.file == NULL) |
| |
1265 { |
| |
1266 MsnTransaction *trans; |
| |
1267 trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX"); |
| |
1268 msn_transaction_queue_cmd(trans, msg->cmd); |
| |
1269 |
| |
1270 msn_cmdproc_send_trans(cmdproc, trans); |
| |
1271 |
| |
1272 return; |
| |
1273 } |
| |
1274 |
| |
1275 if (!purple_account_get_check_mail(session->account)) |
| |
1276 return; |
| |
1277 |
| |
1278 table = msn_message_get_hashtable_from_body(msg); |
| |
1279 |
| |
1280 from = subject = NULL; |
| |
1281 |
| |
1282 tmp = g_hash_table_lookup(table, "From"); |
| |
1283 if (tmp != NULL) |
| |
1284 from = purple_mime_decode_field(tmp); |
| |
1285 |
| |
1286 tmp = g_hash_table_lookup(table, "Subject"); |
| |
1287 if (tmp != NULL) |
| |
1288 subject = purple_mime_decode_field(tmp); |
| |
1289 |
| |
1290 purple_notify_email(gc, |
| |
1291 (subject != NULL ? subject : ""), |
| |
1292 (from != NULL ? from : ""), |
| |
1293 msn_user_get_passport(session->user), |
| |
1294 session->passport_info.file, NULL, NULL); |
| |
1295 |
| |
1296 g_free(from); |
| |
1297 g_free(subject); |
| |
1298 |
| |
1299 g_hash_table_destroy(table); |
| |
1300 } |
| |
1301 |
| |
1302 static void |
| |
1303 system_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
1304 { |
| |
1305 GHashTable *table; |
| |
1306 const char *type_s; |
| |
1307 |
| |
1308 if (strcmp(msg->remote_user, "Hotmail")) |
| |
1309 /* This isn't an official message. */ |
| |
1310 return; |
| |
1311 |
| |
1312 table = msn_message_get_hashtable_from_body(msg); |
| |
1313 |
| |
1314 if ((type_s = g_hash_table_lookup(table, "Type")) != NULL) |
| |
1315 { |
| |
1316 int type = atoi(type_s); |
| |
1317 char buf[MSN_BUF_LEN]; |
| |
1318 int minutes; |
| |
1319 |
| |
1320 switch (type) |
| |
1321 { |
| |
1322 case 1: |
| |
1323 minutes = atoi(g_hash_table_lookup(table, "Arg1")); |
| |
1324 g_snprintf(buf, sizeof(buf), dngettext(PACKAGE, |
| |
1325 "The MSN server will shut down for maintenance " |
| |
1326 "in %d minute. You will automatically be " |
| |
1327 "signed out at that time. Please finish any " |
| |
1328 "conversations in progress.\n\nAfter the " |
| |
1329 "maintenance has been completed, you will be " |
| |
1330 "able to successfully sign in.", |
| |
1331 "The MSN server will shut down for maintenance " |
| |
1332 "in %d minutes. You will automatically be " |
| |
1333 "signed out at that time. Please finish any " |
| |
1334 "conversations in progress.\n\nAfter the " |
| |
1335 "maintenance has been completed, you will be " |
| |
1336 "able to successfully sign in.", minutes), |
| |
1337 minutes); |
| |
1338 default: |
| |
1339 break; |
| |
1340 } |
| |
1341 |
| |
1342 if (*buf != '\0') |
| |
1343 purple_notify_info(cmdproc->session->account->gc, NULL, buf, NULL); |
| |
1344 } |
| |
1345 |
| |
1346 g_hash_table_destroy(table); |
| |
1347 } |
| |
1348 |
| |
1349 void |
| |
1350 msn_notification_add_buddy(MsnNotification *notification, const char *list, |
| |
1351 const char *who, const char *store_name, |
| |
1352 int group_id) |
| |
1353 { |
| |
1354 MsnCmdProc *cmdproc; |
| |
1355 cmdproc = notification->servconn->cmdproc; |
| |
1356 |
| |
1357 if (group_id < 0 && !strcmp(list, "FL")) |
| |
1358 group_id = 0; |
| |
1359 |
| |
1360 if (group_id >= 0) |
| |
1361 { |
| |
1362 msn_cmdproc_send(cmdproc, "ADD", "%s %s %s %d", |
| |
1363 list, who, store_name, group_id); |
| |
1364 } |
| |
1365 else |
| |
1366 { |
| |
1367 msn_cmdproc_send(cmdproc, "ADD", "%s %s %s", list, who, store_name); |
| |
1368 } |
| |
1369 } |
| |
1370 |
| |
1371 void |
| |
1372 msn_notification_rem_buddy(MsnNotification *notification, const char *list, |
| |
1373 const char *who, int group_id) |
| |
1374 { |
| |
1375 MsnCmdProc *cmdproc; |
| |
1376 cmdproc = notification->servconn->cmdproc; |
| |
1377 |
| |
1378 if (group_id >= 0) |
| |
1379 { |
| |
1380 msn_cmdproc_send(cmdproc, "REM", "%s %s %d", list, who, group_id); |
| |
1381 } |
| |
1382 else |
| |
1383 { |
| |
1384 msn_cmdproc_send(cmdproc, "REM", "%s %s", list, who); |
| |
1385 } |
| |
1386 } |
| |
1387 |
| |
1388 /************************************************************************** |
| |
1389 * Init |
| |
1390 **************************************************************************/ |
| |
1391 |
| |
1392 void |
| |
1393 msn_notification_init(void) |
| |
1394 { |
| |
1395 /* TODO: check prp, blp */ |
| |
1396 |
| |
1397 cbs_table = msn_table_new(); |
| |
1398 |
| |
1399 /* Synchronous */ |
| |
1400 msn_table_add_cmd(cbs_table, "CHG", "CHG", NULL); |
| |
1401 msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd); |
| |
1402 msn_table_add_cmd(cbs_table, "ADD", "ADD", add_cmd); |
| |
1403 msn_table_add_cmd(cbs_table, "ADD", "ILN", iln_cmd); |
| |
1404 msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd); |
| |
1405 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); |
| |
1406 msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd); |
| |
1407 msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd); |
| |
1408 msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd); |
| |
1409 msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd); |
| |
1410 msn_table_add_cmd(cbs_table, "REA", "REA", rea_cmd); |
| |
1411 msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd); |
| |
1412 /* msn_table_add_cmd(cbs_table, "BLP", "BLP", blp_cmd); */ |
| |
1413 msn_table_add_cmd(cbs_table, "BLP", "BLP", NULL); |
| |
1414 msn_table_add_cmd(cbs_table, "REG", "REG", reg_cmd); |
| |
1415 msn_table_add_cmd(cbs_table, "ADG", "ADG", adg_cmd); |
| |
1416 msn_table_add_cmd(cbs_table, "RMG", "RMG", rmg_cmd); |
| |
1417 msn_table_add_cmd(cbs_table, "XFR", "XFR", xfr_cmd); |
| |
1418 |
| |
1419 /* Asynchronous */ |
| |
1420 msn_table_add_cmd(cbs_table, NULL, "IPG", ipg_cmd); |
| |
1421 msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd); |
| |
1422 msn_table_add_cmd(cbs_table, NULL, "NOT", not_cmd); |
| |
1423 |
| |
1424 msn_table_add_cmd(cbs_table, NULL, "CHL", chl_cmd); |
| |
1425 msn_table_add_cmd(cbs_table, NULL, "REM", rem_cmd); |
| |
1426 msn_table_add_cmd(cbs_table, NULL, "ADD", add_cmd); |
| |
1427 |
| |
1428 msn_table_add_cmd(cbs_table, NULL, "QRY", NULL); |
| |
1429 msn_table_add_cmd(cbs_table, NULL, "QNG", qng_cmd); |
| |
1430 msn_table_add_cmd(cbs_table, NULL, "FLN", fln_cmd); |
| |
1431 msn_table_add_cmd(cbs_table, NULL, "NLN", nln_cmd); |
| |
1432 msn_table_add_cmd(cbs_table, NULL, "ILN", iln_cmd); |
| |
1433 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); |
| |
1434 msn_table_add_cmd(cbs_table, NULL, "RNG", rng_cmd); |
| |
1435 |
| |
1436 msn_table_add_cmd(cbs_table, NULL, "URL", url_cmd); |
| |
1437 |
| |
1438 msn_table_add_cmd(cbs_table, "fallback", "XFR", xfr_cmd); |
| |
1439 |
| |
1440 msn_table_add_error(cbs_table, "ADD", add_error); |
| |
1441 msn_table_add_error(cbs_table, "REG", reg_error); |
| |
1442 msn_table_add_error(cbs_table, "RMG", rmg_error); |
| |
1443 /* msn_table_add_error(cbs_table, "REA", rea_error); */ |
| |
1444 msn_table_add_error(cbs_table, "USR", usr_error); |
| |
1445 |
| |
1446 msn_table_add_msg_type(cbs_table, |
| |
1447 "text/x-msmsgsprofile", |
| |
1448 profile_msg); |
| |
1449 msn_table_add_msg_type(cbs_table, |
| |
1450 "text/x-msmsgsinitialemailnotification", |
| |
1451 initial_email_msg); |
| |
1452 msn_table_add_msg_type(cbs_table, |
| |
1453 "text/x-msmsgsemailnotification", |
| |
1454 email_msg); |
| |
1455 msn_table_add_msg_type(cbs_table, |
| |
1456 "application/x-msmsgssystemmessage", |
| |
1457 system_msg); |
| |
1458 } |
| |
1459 |
| |
1460 void |
| |
1461 msn_notification_end(void) |
| |
1462 { |
| |
1463 msn_table_destroy(cbs_table); |
| |
1464 } |