| |
1 /** |
| |
2 * @file switchboard.c MSN switchboard functions |
| |
3 * |
| |
4 * gaim |
| |
5 * |
| |
6 * Gaim 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
23 */ |
| |
24 #include "msn.h" |
| |
25 #include "prefs.h" |
| |
26 #include "switchboard.h" |
| |
27 #include "notification.h" |
| |
28 #include "msn-utils.h" |
| |
29 |
| |
30 #include "error.h" |
| |
31 |
| |
32 static MsnTable *cbs_table; |
| |
33 |
| |
34 static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, |
| |
35 MsnMsgErrorType error); |
| |
36 |
| |
37 /************************************************************************** |
| |
38 * Main |
| |
39 **************************************************************************/ |
| |
40 |
| |
41 MsnSwitchBoard * |
| |
42 msn_switchboard_new(MsnSession *session) |
| |
43 { |
| |
44 MsnSwitchBoard *swboard; |
| |
45 MsnServConn *servconn; |
| |
46 |
| |
47 g_return_val_if_fail(session != NULL, NULL); |
| |
48 |
| |
49 swboard = g_new0(MsnSwitchBoard, 1); |
| |
50 |
| |
51 swboard->session = session; |
| |
52 swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_SB); |
| |
53 swboard->cmdproc = servconn->cmdproc; |
| |
54 |
| |
55 swboard->msg_queue = g_queue_new(); |
| |
56 swboard->empty = TRUE; |
| |
57 |
| |
58 swboard->cmdproc->data = swboard; |
| |
59 swboard->cmdproc->cbs_table = cbs_table; |
| |
60 |
| |
61 session->switches = g_list_append(session->switches, swboard); |
| |
62 |
| |
63 return swboard; |
| |
64 } |
| |
65 |
| |
66 void |
| |
67 msn_switchboard_destroy(MsnSwitchBoard *swboard) |
| |
68 { |
| |
69 MsnSession *session; |
| |
70 MsnMessage *msg; |
| |
71 GList *l; |
| |
72 |
| |
73 #ifdef MSN_DEBUG_SB |
| |
74 gaim_debug_info("msn", "switchboard_destroy: swboard(%p)\n", swboard); |
| |
75 #endif |
| |
76 |
| |
77 g_return_if_fail(swboard != NULL); |
| |
78 |
| |
79 if (swboard->destroying) |
| |
80 return; |
| |
81 |
| |
82 swboard->destroying = TRUE; |
| |
83 |
| |
84 /* If it linked us is because its looking for trouble */ |
| |
85 while (swboard->slplinks != NULL) |
| |
86 msn_slplink_destroy(swboard->slplinks->data); |
| |
87 |
| |
88 /* Destroy the message queue */ |
| |
89 while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL) |
| |
90 { |
| |
91 if (swboard->error != MSN_SB_ERROR_NONE) |
| |
92 { |
| |
93 /* The messages could not be sent due to a switchboard error */ |
| |
94 msg_error_helper(swboard->cmdproc, msg, |
| |
95 MSN_MSG_ERROR_SB); |
| |
96 } |
| |
97 msn_message_unref(msg); |
| |
98 } |
| |
99 |
| |
100 g_queue_free(swboard->msg_queue); |
| |
101 |
| |
102 /* msg_error_helper will both remove the msg from ack_list and |
| |
103 unref it, so we don't need to do either here */ |
| |
104 while ((l = swboard->ack_list) != NULL) |
| |
105 msg_error_helper(swboard->cmdproc, l->data, MSN_MSG_ERROR_SB); |
| |
106 |
| |
107 g_free(swboard->im_user); |
| |
108 g_free(swboard->auth_key); |
| |
109 g_free(swboard->session_id); |
| |
110 |
| |
111 for (l = swboard->users; l != NULL; l = l->next) |
| |
112 g_free(l->data); |
| |
113 |
| |
114 session = swboard->session; |
| |
115 session->switches = g_list_remove(session->switches, swboard); |
| |
116 |
| |
117 #if 0 |
| |
118 /* This should never happen or we are in trouble. */ |
| |
119 if (swboard->servconn != NULL) |
| |
120 msn_servconn_destroy(swboard->servconn); |
| |
121 #endif |
| |
122 |
| |
123 swboard->cmdproc->data = NULL; |
| |
124 |
| |
125 msn_servconn_set_disconnect_cb(swboard->servconn, NULL); |
| |
126 |
| |
127 msn_servconn_destroy(swboard->servconn); |
| |
128 |
| |
129 g_free(swboard); |
| |
130 } |
| |
131 |
| |
132 void |
| |
133 msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) |
| |
134 { |
| |
135 g_return_if_fail(swboard != NULL); |
| |
136 g_return_if_fail(key != NULL); |
| |
137 |
| |
138 swboard->auth_key = g_strdup(key); |
| |
139 } |
| |
140 |
| |
141 const char * |
| |
142 msn_switchboard_get_auth_key(MsnSwitchBoard *swboard) |
| |
143 { |
| |
144 g_return_val_if_fail(swboard != NULL, NULL); |
| |
145 |
| |
146 return swboard->auth_key; |
| |
147 } |
| |
148 |
| |
149 void |
| |
150 msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) |
| |
151 { |
| |
152 g_return_if_fail(swboard != NULL); |
| |
153 g_return_if_fail(id != NULL); |
| |
154 |
| |
155 if (swboard->session_id != NULL) |
| |
156 g_free(swboard->session_id); |
| |
157 |
| |
158 swboard->session_id = g_strdup(id); |
| |
159 } |
| |
160 |
| |
161 const char * |
| |
162 msn_switchboard_get_session_id(MsnSwitchBoard *swboard) |
| |
163 { |
| |
164 g_return_val_if_fail(swboard != NULL, NULL); |
| |
165 |
| |
166 return swboard->session_id; |
| |
167 } |
| |
168 |
| |
169 void |
| |
170 msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) |
| |
171 { |
| |
172 g_return_if_fail(swboard != NULL); |
| |
173 |
| |
174 swboard->invited = invited; |
| |
175 } |
| |
176 |
| |
177 gboolean |
| |
178 msn_switchboard_is_invited(MsnSwitchBoard *swboard) |
| |
179 { |
| |
180 g_return_val_if_fail(swboard != NULL, FALSE); |
| |
181 |
| |
182 return swboard->invited; |
| |
183 } |
| |
184 |
| |
185 /************************************************************************** |
| |
186 * Utility |
| |
187 **************************************************************************/ |
| |
188 |
| |
189 static void |
| |
190 send_clientcaps(MsnSwitchBoard *swboard) |
| |
191 { |
| |
192 MsnMessage *msg; |
| |
193 |
| |
194 msg = msn_message_new(MSN_MSG_CAPS); |
| |
195 msn_message_set_content_type(msg, "text/x-clientcaps"); |
| |
196 msn_message_set_flag(msg, 'U'); |
| |
197 msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO)); |
| |
198 |
| |
199 msn_switchboard_send_msg(swboard, msg, TRUE); |
| |
200 |
| |
201 msn_message_destroy(msg); |
| |
202 } |
| |
203 |
| |
204 static void |
| |
205 msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user) |
| |
206 { |
| |
207 MsnCmdProc *cmdproc; |
| |
208 GaimAccount *account; |
| |
209 |
| |
210 g_return_if_fail(swboard != NULL); |
| |
211 |
| |
212 cmdproc = swboard->cmdproc; |
| |
213 account = cmdproc->session->account; |
| |
214 |
| |
215 swboard->users = g_list_prepend(swboard->users, g_strdup(user)); |
| |
216 swboard->current_users++; |
| |
217 swboard->empty = FALSE; |
| |
218 |
| |
219 #ifdef MSN_DEBUG_CHAT |
| |
220 gaim_debug_info("msn", "user=[%s], total=%d\n", user, |
| |
221 swboard->current_users); |
| |
222 #endif |
| |
223 |
| |
224 if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) |
| |
225 { |
| |
226 /* This is a helper switchboard. */ |
| |
227 gaim_debug_error("msn", "switchboard_add_user: conv != NULL\n"); |
| |
228 return; |
| |
229 } |
| |
230 |
| |
231 if ((swboard->conv != NULL) && |
| |
232 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) |
| |
233 { |
| |
234 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), user, NULL, |
| |
235 GAIM_CBFLAGS_NONE, TRUE); |
| |
236 } |
| |
237 else if (swboard->current_users > 1 || swboard->total_users > 1) |
| |
238 { |
| |
239 if (swboard->conv == NULL || |
| |
240 gaim_conversation_get_type(swboard->conv) != GAIM_CONV_TYPE_CHAT) |
| |
241 { |
| |
242 GList *l; |
| |
243 |
| |
244 #ifdef MSN_DEBUG_CHAT |
| |
245 gaim_debug_info("msn", "[chat] Switching to chat.\n"); |
| |
246 #endif |
| |
247 |
| |
248 #if 0 |
| |
249 /* this is bad - it causes msn_switchboard_close to be called on the |
| |
250 * switchboard we're in the middle of using :( */ |
| |
251 if (swboard->conv != NULL) |
| |
252 gaim_conversation_destroy(swboard->conv); |
| |
253 #endif |
| |
254 |
| |
255 cmdproc->session->conv_seq++; |
| |
256 swboard->chat_id = cmdproc->session->conv_seq; |
| |
257 swboard->flag |= MSN_SB_FLAG_IM; |
| |
258 swboard->conv = serv_got_joined_chat(account->gc, |
| |
259 swboard->chat_id, |
| |
260 "MSN Chat"); |
| |
261 |
| |
262 for (l = swboard->users; l != NULL; l = l->next) |
| |
263 { |
| |
264 const char *tmp_user; |
| |
265 |
| |
266 tmp_user = l->data; |
| |
267 |
| |
268 #ifdef MSN_DEBUG_CHAT |
| |
269 gaim_debug_info("msn", "[chat] Adding [%s].\n", tmp_user); |
| |
270 #endif |
| |
271 |
| |
272 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), |
| |
273 tmp_user, NULL, GAIM_CBFLAGS_NONE, TRUE); |
| |
274 } |
| |
275 |
| |
276 #ifdef MSN_DEBUG_CHAT |
| |
277 gaim_debug_info("msn", "[chat] We add ourselves.\n"); |
| |
278 #endif |
| |
279 |
| |
280 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->conv), |
| |
281 gaim_account_get_username(account), |
| |
282 NULL, GAIM_CBFLAGS_NONE, TRUE); |
| |
283 |
| |
284 g_free(swboard->im_user); |
| |
285 swboard->im_user = NULL; |
| |
286 } |
| |
287 } |
| |
288 else if (swboard->conv == NULL) |
| |
289 { |
| |
290 swboard->conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| |
291 user, account); |
| |
292 } |
| |
293 else |
| |
294 { |
| |
295 gaim_debug_warning("msn", "switchboard_add_user: This should not happen!\n"); |
| |
296 } |
| |
297 } |
| |
298 |
| |
299 static GaimConversation * |
| |
300 msn_switchboard_get_conv(MsnSwitchBoard *swboard) |
| |
301 { |
| |
302 GaimAccount *account; |
| |
303 |
| |
304 g_return_val_if_fail(swboard != NULL, NULL); |
| |
305 |
| |
306 if (swboard->conv != NULL) |
| |
307 return swboard->conv; |
| |
308 |
| |
309 gaim_debug_error("msn", "Switchboard with unassigned conversation\n"); |
| |
310 |
| |
311 account = swboard->session->account; |
| |
312 |
| |
313 return (swboard->conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, |
| |
314 account, swboard->im_user)); |
| |
315 } |
| |
316 |
| |
317 static void |
| |
318 msn_switchboard_report_user(MsnSwitchBoard *swboard, GaimMessageFlags flags, const char *msg) |
| |
319 { |
| |
320 GaimConversation *conv; |
| |
321 |
| |
322 g_return_if_fail(swboard != NULL); |
| |
323 g_return_if_fail(msg != NULL); |
| |
324 |
| |
325 if ((conv = msn_switchboard_get_conv(swboard)) != NULL) |
| |
326 { |
| |
327 gaim_conversation_write(conv, NULL, msg, flags, time(NULL)); |
| |
328 } |
| |
329 } |
| |
330 |
| |
331 static void |
| |
332 swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport) |
| |
333 { |
| |
334 g_return_if_fail(swboard != NULL); |
| |
335 |
| |
336 gaim_debug_warning("msg", "Error: Unable to call the user %s for reason %i\n", |
| |
337 passport ? passport : "(null)", reason); |
| |
338 |
| |
339 /* TODO: if current_users > 0, this is probably a chat and an invite failed, |
| |
340 * we should report that in the chat or something */ |
| |
341 if (swboard->current_users == 0) |
| |
342 { |
| |
343 swboard->error = reason; |
| |
344 msn_switchboard_close(swboard); |
| |
345 } |
| |
346 } |
| |
347 |
| |
348 static void |
| |
349 cal_error_helper(MsnTransaction *trans, int reason) |
| |
350 { |
| |
351 MsnSwitchBoard *swboard; |
| |
352 const char *passport; |
| |
353 char **params; |
| |
354 |
| |
355 params = g_strsplit(trans->params, " ", 0); |
| |
356 |
| |
357 passport = params[0]; |
| |
358 |
| |
359 swboard = trans->data; |
| |
360 |
| |
361 gaim_debug_warning("msn", "cal_error_helper: command %s failed for reason %i\n",trans->command,reason); |
| |
362 |
| |
363 swboard_error_helper(swboard, reason, passport); |
| |
364 |
| |
365 g_strfreev(params); |
| |
366 } |
| |
367 |
| |
368 static void |
| |
369 msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error) |
| |
370 { |
| |
371 MsnSwitchBoard *swboard; |
| |
372 |
| |
373 g_return_if_fail(cmdproc != NULL); |
| |
374 g_return_if_fail(msg != NULL); |
| |
375 |
| |
376 if ((error != MSN_MSG_ERROR_SB) && (msg->nak_cb != NULL)) |
| |
377 msg->nak_cb(msg, msg->ack_data); |
| |
378 |
| |
379 swboard = cmdproc->data; |
| |
380 |
| |
381 /* This is not good, and should be fixed somewhere else. */ |
| |
382 g_return_if_fail(swboard != NULL); |
| |
383 |
| |
384 if (msg->type == MSN_MSG_TEXT) |
| |
385 { |
| |
386 const char *format, *str_reason; |
| |
387 char *body_str, *body_enc, *pre, *post; |
| |
388 |
| |
389 #if 0 |
| |
390 if (swboard->conv == NULL) |
| |
391 { |
| |
392 if (msg->ack_ref) |
| |
393 msn_message_unref(msg); |
| |
394 |
| |
395 return; |
| |
396 } |
| |
397 #endif |
| |
398 |
| |
399 if (error == MSN_MSG_ERROR_TIMEOUT) |
| |
400 { |
| |
401 str_reason = _("Message may have not been sent " |
| |
402 "because a timeout occurred:"); |
| |
403 } |
| |
404 else if (error == MSN_MSG_ERROR_SB) |
| |
405 { |
| |
406 switch (swboard->error) |
| |
407 { |
| |
408 case MSN_SB_ERROR_OFFLINE: |
| |
409 str_reason = _("Message could not be sent, " |
| |
410 "not allowed while invisible:"); |
| |
411 break; |
| |
412 case MSN_SB_ERROR_USER_OFFLINE: |
| |
413 str_reason = _("Message could not be sent " |
| |
414 "because the user is offline:"); |
| |
415 break; |
| |
416 case MSN_SB_ERROR_CONNECTION: |
| |
417 str_reason = _("Message could not be sent " |
| |
418 "because a connection error occurred:"); |
| |
419 break; |
| |
420 case MSN_SB_ERROR_TOO_FAST: |
| |
421 str_reason = _("Message could not be sent " |
| |
422 "because we are sending too quickly:"); |
| |
423 break; |
| |
424 default: |
| |
425 str_reason = _("Message could not be sent " |
| |
426 "because an error with " |
| |
427 "the switchboard occurred:"); |
| |
428 break; |
| |
429 } |
| |
430 } |
| |
431 else |
| |
432 { |
| |
433 str_reason = _("Message may have not been sent " |
| |
434 "because an unknown error occurred:"); |
| |
435 } |
| |
436 |
| |
437 body_str = msn_message_to_string(msg); |
| |
438 body_enc = g_markup_escape_text(body_str, -1); |
| |
439 g_free(body_str); |
| |
440 |
| |
441 format = msn_message_get_attr(msg, "X-MMS-IM-Format"); |
| |
442 msn_parse_format(format, &pre, &post); |
| |
443 body_str = g_strdup_printf("%s%s%s", pre ? pre : "", |
| |
444 body_enc ? body_enc : "", post ? post : ""); |
| |
445 g_free(body_enc); |
| |
446 g_free(pre); |
| |
447 g_free(post); |
| |
448 |
| |
449 msn_switchboard_report_user(swboard, GAIM_MESSAGE_ERROR, |
| |
450 str_reason); |
| |
451 msn_switchboard_report_user(swboard, GAIM_MESSAGE_RAW, |
| |
452 body_str); |
| |
453 |
| |
454 g_free(body_str); |
| |
455 } |
| |
456 |
| |
457 /* If a timeout occures we will want the msg around just in case we |
| |
458 * receive the ACK after the timeout. */ |
| |
459 if (msg->ack_ref && error != MSN_MSG_ERROR_TIMEOUT) |
| |
460 { |
| |
461 swboard->ack_list = g_list_remove(swboard->ack_list, msg); |
| |
462 msn_message_unref(msg); |
| |
463 } |
| |
464 } |
| |
465 |
| |
466 /************************************************************************** |
| |
467 * Message Stuff |
| |
468 **************************************************************************/ |
| |
469 |
| |
470 /** Called when a message times out. */ |
| |
471 static void |
| |
472 msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) |
| |
473 { |
| |
474 MsnMessage *msg; |
| |
475 |
| |
476 msg = trans->data; |
| |
477 |
| |
478 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT); |
| |
479 } |
| |
480 |
| |
481 /** Called when we receive an error of a message. */ |
| |
482 static void |
| |
483 msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
484 { |
| |
485 msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN); |
| |
486 } |
| |
487 |
| |
488 #if 0 |
| |
489 /** Called when we receive an ack of a special message. */ |
| |
490 static void |
| |
491 msg_ack(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
492 { |
| |
493 MsnMessage *msg; |
| |
494 |
| |
495 msg = cmd->trans->data; |
| |
496 |
| |
497 if (msg->ack_cb != NULL) |
| |
498 msg->ack_cb(msg->ack_data); |
| |
499 |
| |
500 msn_message_unref(msg); |
| |
501 } |
| |
502 |
| |
503 /** Called when we receive a nak of a special message. */ |
| |
504 static void |
| |
505 msg_nak(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
506 { |
| |
507 MsnMessage *msg; |
| |
508 |
| |
509 msg = cmd->trans->data; |
| |
510 |
| |
511 msn_message_unref(msg); |
| |
512 } |
| |
513 #endif |
| |
514 |
| |
515 static void |
| |
516 release_msg(MsnSwitchBoard *swboard, MsnMessage *msg) |
| |
517 { |
| |
518 MsnCmdProc *cmdproc; |
| |
519 MsnTransaction *trans; |
| |
520 char *payload; |
| |
521 gsize payload_len; |
| |
522 |
| |
523 g_return_if_fail(swboard != NULL); |
| |
524 g_return_if_fail(msg != NULL); |
| |
525 |
| |
526 cmdproc = swboard->cmdproc; |
| |
527 |
| |
528 payload = msn_message_gen_payload(msg, &payload_len); |
| |
529 |
| |
530 #ifdef MSN_DEBUG_SB |
| |
531 msn_message_show_readable(msg, "SB SEND", FALSE); |
| |
532 #endif |
| |
533 |
| |
534 trans = msn_transaction_new(cmdproc, "MSG", "%c %d", |
| |
535 msn_message_get_flag(msg), payload_len); |
| |
536 |
| |
537 /* Data for callbacks */ |
| |
538 msn_transaction_set_data(trans, msg); |
| |
539 |
| |
540 if (msg->type == MSN_MSG_TEXT) |
| |
541 { |
| |
542 msg->ack_ref = TRUE; |
| |
543 msn_message_ref(msg); |
| |
544 swboard->ack_list = g_list_append(swboard->ack_list, msg); |
| |
545 msn_transaction_set_timeout_cb(trans, msg_timeout); |
| |
546 } |
| |
547 else if (msg->type == MSN_MSG_SLP) |
| |
548 { |
| |
549 msg->ack_ref = TRUE; |
| |
550 msn_message_ref(msg); |
| |
551 swboard->ack_list = g_list_append(swboard->ack_list, msg); |
| |
552 msn_transaction_set_timeout_cb(trans, msg_timeout); |
| |
553 #if 0 |
| |
554 if (msg->ack_cb != NULL) |
| |
555 { |
| |
556 msn_transaction_add_cb(trans, "ACK", msg_ack); |
| |
557 msn_transaction_add_cb(trans, "NAK", msg_nak); |
| |
558 } |
| |
559 #endif |
| |
560 } |
| |
561 |
| |
562 trans->payload = payload; |
| |
563 trans->payload_len = payload_len; |
| |
564 |
| |
565 msg->trans = trans; |
| |
566 |
| |
567 msn_cmdproc_send_trans(cmdproc, trans); |
| |
568 } |
| |
569 |
| |
570 static void |
| |
571 queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg) |
| |
572 { |
| |
573 g_return_if_fail(swboard != NULL); |
| |
574 g_return_if_fail(msg != NULL); |
| |
575 |
| |
576 gaim_debug_info("msn", "Appending message to queue.\n"); |
| |
577 |
| |
578 g_queue_push_tail(swboard->msg_queue, msg); |
| |
579 |
| |
580 msn_message_ref(msg); |
| |
581 } |
| |
582 |
| |
583 static void |
| |
584 process_queue(MsnSwitchBoard *swboard) |
| |
585 { |
| |
586 MsnMessage *msg; |
| |
587 |
| |
588 g_return_if_fail(swboard != NULL); |
| |
589 |
| |
590 gaim_debug_info("msn", "Processing queue\n"); |
| |
591 |
| |
592 while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL) |
| |
593 { |
| |
594 gaim_debug_info("msn", "Sending message\n"); |
| |
595 release_msg(swboard, msg); |
| |
596 msn_message_unref(msg); |
| |
597 } |
| |
598 } |
| |
599 |
| |
600 gboolean |
| |
601 msn_switchboard_can_send(MsnSwitchBoard *swboard) |
| |
602 { |
| |
603 g_return_val_if_fail(swboard != NULL, FALSE); |
| |
604 |
| |
605 if (swboard->empty || !g_queue_is_empty(swboard->msg_queue)) |
| |
606 return FALSE; |
| |
607 |
| |
608 return TRUE; |
| |
609 } |
| |
610 |
| |
611 void |
| |
612 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg, |
| |
613 gboolean queue) |
| |
614 { |
| |
615 g_return_if_fail(swboard != NULL); |
| |
616 g_return_if_fail(msg != NULL); |
| |
617 |
| |
618 if (msn_switchboard_can_send(swboard)) |
| |
619 release_msg(swboard, msg); |
| |
620 else if (queue) |
| |
621 queue_msg(swboard, msg); |
| |
622 } |
| |
623 |
| |
624 /************************************************************************** |
| |
625 * Switchboard Commands |
| |
626 **************************************************************************/ |
| |
627 |
| |
628 static void |
| |
629 ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
630 { |
| |
631 MsnSwitchBoard *swboard; |
| |
632 |
| |
633 swboard = cmdproc->data; |
| |
634 swboard->ready = TRUE; |
| |
635 } |
| |
636 |
| |
637 static void |
| |
638 bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
639 { |
| |
640 MsnSwitchBoard *swboard; |
| |
641 const char *user; |
| |
642 |
| |
643 swboard = cmdproc->data; |
| |
644 user = cmd->params[0]; |
| |
645 |
| |
646 if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) |
| |
647 gaim_debug_error("msn_switchboard", "bye_cmd: helper bug\n"); |
| |
648 |
| |
649 if (swboard->conv == NULL) |
| |
650 { |
| |
651 /* This is a helper switchboard */ |
| |
652 msn_switchboard_destroy(swboard); |
| |
653 } |
| |
654 else if ((swboard->current_users > 1) || |
| |
655 (gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) |
| |
656 { |
| |
657 /* This is a switchboard used for a chat */ |
| |
658 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->conv), user, NULL); |
| |
659 swboard->current_users--; |
| |
660 if (swboard->current_users == 0) |
| |
661 msn_switchboard_destroy(swboard); |
| |
662 } |
| |
663 else |
| |
664 { |
| |
665 /* This is a switchboard used for a im session */ |
| |
666 msn_switchboard_destroy(swboard); |
| |
667 } |
| |
668 } |
| |
669 |
| |
670 static void |
| |
671 iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
672 { |
| |
673 GaimAccount *account; |
| |
674 GaimConnection *gc; |
| |
675 MsnSwitchBoard *swboard; |
| |
676 |
| |
677 account = cmdproc->session->account; |
| |
678 gc = account->gc; |
| |
679 swboard = cmdproc->data; |
| |
680 |
| |
681 swboard->total_users = atoi(cmd->params[2]); |
| |
682 |
| |
683 msn_switchboard_add_user(swboard, cmd->params[3]); |
| |
684 } |
| |
685 |
| |
686 static void |
| |
687 joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
688 { |
| |
689 MsnSession *session; |
| |
690 GaimAccount *account; |
| |
691 GaimConnection *gc; |
| |
692 MsnSwitchBoard *swboard; |
| |
693 const char *passport; |
| |
694 |
| |
695 passport = cmd->params[0]; |
| |
696 |
| |
697 session = cmdproc->session; |
| |
698 account = session->account; |
| |
699 gc = account->gc; |
| |
700 swboard = cmdproc->data; |
| |
701 |
| |
702 msn_switchboard_add_user(swboard, passport); |
| |
703 |
| |
704 process_queue(swboard); |
| |
705 |
| |
706 if (!session->http_method) |
| |
707 send_clientcaps(swboard); |
| |
708 |
| |
709 if (swboard->closed) |
| |
710 msn_switchboard_close(swboard); |
| |
711 } |
| |
712 |
| |
713 static void |
| |
714 msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) |
| |
715 { |
| |
716 MsnMessage *msg; |
| |
717 |
| |
718 msg = msn_message_new_from_cmd(cmdproc->session, cmd); |
| |
719 |
| |
720 msn_message_parse_payload(msg, payload, len); |
| |
721 #ifdef MSN_DEBUG_SB |
| |
722 msn_message_show_readable(msg, "SB RECV", FALSE); |
| |
723 #endif |
| |
724 |
| |
725 if (msg->remote_user != NULL) |
| |
726 g_free (msg->remote_user); |
| |
727 |
| |
728 msg->remote_user = g_strdup(cmd->params[0]); |
| |
729 msn_cmdproc_process_msg(cmdproc, msg); |
| |
730 |
| |
731 msn_message_destroy(msg); |
| |
732 } |
| |
733 |
| |
734 static void |
| |
735 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
736 { |
| |
737 cmdproc->servconn->payload_len = atoi(cmd->params[2]); |
| |
738 cmdproc->last_cmd->payload_cb = msg_cmd_post; |
| |
739 } |
| |
740 |
| |
741 static void |
| |
742 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
743 { |
| |
744 MsnMessage *msg; |
| |
745 |
| |
746 msg = cmd->trans->data; |
| |
747 g_return_if_fail(msg != NULL); |
| |
748 |
| |
749 msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK); |
| |
750 } |
| |
751 |
| |
752 static void |
| |
753 ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
754 { |
| |
755 MsnSwitchBoard *swboard; |
| |
756 MsnMessage *msg; |
| |
757 |
| |
758 msg = cmd->trans->data; |
| |
759 |
| |
760 if (msg->ack_cb != NULL) |
| |
761 msg->ack_cb(msg, msg->ack_data); |
| |
762 |
| |
763 swboard = cmdproc->data; |
| |
764 swboard->ack_list = g_list_remove(swboard->ack_list, msg); |
| |
765 msn_message_unref(msg); |
| |
766 } |
| |
767 |
| |
768 static void |
| |
769 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
770 { |
| |
771 GaimConnection *gc; |
| |
772 MsnSwitchBoard *swboard; |
| |
773 |
| |
774 gc = cmdproc->session->account->gc; |
| |
775 swboard = cmdproc->data; |
| |
776 |
| |
777 if (swboard->current_users > 1) |
| |
778 serv_got_chat_left(gc, swboard->chat_id); |
| |
779 |
| |
780 msn_switchboard_disconnect(swboard); |
| |
781 } |
| |
782 |
| |
783 static void |
| |
784 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
785 { |
| |
786 MsnSwitchBoard *swboard; |
| |
787 |
| |
788 swboard = cmdproc->data; |
| |
789 |
| |
790 #if 0 |
| |
791 GList *l; |
| |
792 |
| |
793 for (l = swboard->users; l != NULL; l = l->next) |
| |
794 { |
| |
795 const char *user; |
| |
796 user = l->data; |
| |
797 |
| |
798 msn_cmdproc_send(cmdproc, "CAL", "%s", user); |
| |
799 } |
| |
800 #endif |
| |
801 |
| |
802 swboard->ready = TRUE; |
| |
803 msn_cmdproc_process_queue(cmdproc); |
| |
804 } |
| |
805 |
| |
806 /************************************************************************** |
| |
807 * Message Handlers |
| |
808 **************************************************************************/ |
| |
809 static void |
| |
810 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
811 { |
| |
812 GaimConnection *gc; |
| |
813 MsnSwitchBoard *swboard; |
| |
814 const char *body; |
| |
815 char *body_str; |
| |
816 char *body_enc; |
| |
817 char *body_final; |
| |
818 size_t body_len; |
| |
819 const char *passport; |
| |
820 const char *value; |
| |
821 |
| |
822 gc = cmdproc->session->account->gc; |
| |
823 swboard = cmdproc->data; |
| |
824 |
| |
825 body = msn_message_get_bin_data(msg, &body_len); |
| |
826 body_str = g_strndup(body, body_len); |
| |
827 body_enc = g_markup_escape_text(body_str, -1); |
| |
828 g_free(body_str); |
| |
829 |
| |
830 passport = msg->remote_user; |
| |
831 |
| |
832 if (!strcmp(passport, "messenger@microsoft.com") && |
| |
833 strstr(body, "immediate security update")) |
| |
834 { |
| |
835 return; |
| |
836 } |
| |
837 |
| |
838 #if 0 |
| |
839 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) |
| |
840 { |
| |
841 gaim_debug_misc("msn", "User-Agent = '%s'\n", value); |
| |
842 } |
| |
843 #endif |
| |
844 |
| |
845 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) |
| |
846 { |
| |
847 char *pre, *post; |
| |
848 |
| |
849 msn_parse_format(value, &pre, &post); |
| |
850 |
| |
851 body_final = g_strdup_printf("%s%s%s", pre ? pre : "", |
| |
852 body_enc ? body_enc : "", post ? post : ""); |
| |
853 |
| |
854 g_free(pre); |
| |
855 g_free(post); |
| |
856 g_free(body_enc); |
| |
857 } |
| |
858 else |
| |
859 { |
| |
860 body_final = body_enc; |
| |
861 } |
| |
862 |
| |
863 swboard->flag |= MSN_SB_FLAG_IM; |
| |
864 |
| |
865 if (swboard->current_users > 1 || |
| |
866 ((swboard->conv != NULL) && |
| |
867 gaim_conversation_get_type(swboard->conv) == GAIM_CONV_TYPE_CHAT)) |
| |
868 { |
| |
869 /* If current_users is always ok as it should then there is no need to |
| |
870 * check if this is a chat. */ |
| |
871 if (swboard->current_users <= 1) |
| |
872 gaim_debug_misc("msn", "plain_msg: current_users(%d)\n", |
| |
873 swboard->current_users); |
| |
874 |
| |
875 serv_got_chat_in(gc, swboard->chat_id, passport, 0, body_final, |
| |
876 time(NULL)); |
| |
877 if (swboard->conv == NULL) |
| |
878 { |
| |
879 swboard->conv = gaim_find_chat(gc, swboard->chat_id); |
| |
880 swboard->flag |= MSN_SB_FLAG_IM; |
| |
881 } |
| |
882 } |
| |
883 else |
| |
884 { |
| |
885 serv_got_im(gc, passport, body_final, 0, time(NULL)); |
| |
886 if (swboard->conv == NULL) |
| |
887 { |
| |
888 swboard->conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| |
889 passport, gaim_connection_get_account(gc)); |
| |
890 swboard->flag |= MSN_SB_FLAG_IM; |
| |
891 } |
| |
892 } |
| |
893 |
| |
894 g_free(body_final); |
| |
895 } |
| |
896 |
| |
897 static void |
| |
898 control_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
899 { |
| |
900 GaimConnection *gc; |
| |
901 MsnSwitchBoard *swboard; |
| |
902 char *passport; |
| |
903 |
| |
904 gc = cmdproc->session->account->gc; |
| |
905 swboard = cmdproc->data; |
| |
906 passport = msg->remote_user; |
| |
907 |
| |
908 if (swboard->current_users == 1 && |
| |
909 msn_message_get_attr(msg, "TypingUser") != NULL) |
| |
910 { |
| |
911 serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT, |
| |
912 GAIM_TYPING); |
| |
913 } |
| |
914 } |
| |
915 |
| |
916 static void |
| |
917 clientcaps_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
918 { |
| |
919 #if 0 |
| |
920 MsnSession *session; |
| |
921 MsnSwitchBoard *swboard; |
| |
922 MsnUser *user; |
| |
923 GHashTable *clientcaps; |
| |
924 const char *value; |
| |
925 |
| |
926 char *passport = msg->sender; |
| |
927 |
| |
928 session = cmdproc->session; |
| |
929 swboard = cmdproc->servconn->swboard; |
| |
930 |
| |
931 clientcaps = msn_message_get_hashtable_from_body(msg); |
| |
932 #endif |
| |
933 } |
| |
934 |
| |
935 static void |
| |
936 nudge_msg(MsnCmdProc *cmdproc, MsnMessage *msg) |
| |
937 { |
| |
938 MsnSwitchBoard *swboard; |
| |
939 char *username, *str; |
| |
940 GaimAccount *account; |
| |
941 GaimBuddy *buddy; |
| |
942 const char *user; |
| |
943 |
| |
944 swboard = cmdproc->data; |
| |
945 account = cmdproc->session->account; |
| |
946 user = msg->remote_user; |
| |
947 |
| |
948 if ((buddy = gaim_find_buddy(account, user)) != NULL) |
| |
949 username = g_markup_escape_text(gaim_buddy_get_alias(buddy), -1); |
| |
950 else |
| |
951 username = g_markup_escape_text(user, -1); |
| |
952 |
| |
953 str = g_strdup_printf(_("%s just sent you a Nudge!"), username); |
| |
954 g_free(username); |
| |
955 msn_switchboard_report_user(swboard, GAIM_MESSAGE_SYSTEM, str); |
| |
956 g_free(str); |
| |
957 } |
| |
958 |
| |
959 /************************************************************************** |
| |
960 * Connect stuff |
| |
961 **************************************************************************/ |
| |
962 static void |
| |
963 connect_cb(MsnServConn *servconn) |
| |
964 { |
| |
965 MsnSwitchBoard *swboard; |
| |
966 MsnCmdProc *cmdproc; |
| |
967 GaimAccount *account; |
| |
968 |
| |
969 cmdproc = servconn->cmdproc; |
| |
970 g_return_if_fail(cmdproc != NULL); |
| |
971 |
| |
972 account = cmdproc->session->account; |
| |
973 swboard = cmdproc->data; |
| |
974 g_return_if_fail(swboard != NULL); |
| |
975 |
| |
976 if (msn_switchboard_is_invited(swboard)) |
| |
977 { |
| |
978 swboard->empty = FALSE; |
| |
979 |
| |
980 msn_cmdproc_send(cmdproc, "ANS", "%s %s %s", |
| |
981 gaim_account_get_username(account), |
| |
982 swboard->auth_key, swboard->session_id); |
| |
983 } |
| |
984 else |
| |
985 { |
| |
986 msn_cmdproc_send(cmdproc, "USR", "%s %s", |
| |
987 gaim_account_get_username(account), |
| |
988 swboard->auth_key); |
| |
989 } |
| |
990 } |
| |
991 |
| |
992 static void |
| |
993 disconnect_cb(MsnServConn *servconn) |
| |
994 { |
| |
995 MsnSwitchBoard *swboard; |
| |
996 |
| |
997 swboard = servconn->cmdproc->data; |
| |
998 g_return_if_fail(swboard != NULL); |
| |
999 |
| |
1000 msn_servconn_set_disconnect_cb(swboard->servconn, NULL); |
| |
1001 |
| |
1002 msn_switchboard_destroy(swboard); |
| |
1003 } |
| |
1004 |
| |
1005 gboolean |
| |
1006 msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port) |
| |
1007 { |
| |
1008 g_return_val_if_fail(swboard != NULL, FALSE); |
| |
1009 |
| |
1010 msn_servconn_set_connect_cb(swboard->servconn, connect_cb); |
| |
1011 msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb); |
| |
1012 |
| |
1013 return msn_servconn_connect(swboard->servconn, host, port); |
| |
1014 } |
| |
1015 |
| |
1016 void |
| |
1017 msn_switchboard_disconnect(MsnSwitchBoard *swboard) |
| |
1018 { |
| |
1019 g_return_if_fail(swboard != NULL); |
| |
1020 |
| |
1021 msn_servconn_disconnect(swboard->servconn); |
| |
1022 } |
| |
1023 |
| |
1024 /************************************************************************** |
| |
1025 * Call stuff |
| |
1026 **************************************************************************/ |
| |
1027 static void |
| |
1028 got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
1029 { |
| |
1030 #if 0 |
| |
1031 MsnSwitchBoard *swboard; |
| |
1032 const char *user; |
| |
1033 |
| |
1034 swboard = cmdproc->data; |
| |
1035 |
| |
1036 user = cmd->params[0]; |
| |
1037 |
| |
1038 msn_switchboard_add_user(swboard, user); |
| |
1039 #endif |
| |
1040 } |
| |
1041 |
| |
1042 static void |
| |
1043 cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans) |
| |
1044 { |
| |
1045 gaim_debug_warning("msn", "cal_timeout: command %s timed out\n", trans->command); |
| |
1046 |
| |
1047 cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN); |
| |
1048 } |
| |
1049 |
| |
1050 static void |
| |
1051 cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
1052 { |
| |
1053 int reason = MSN_SB_ERROR_UNKNOWN; |
| |
1054 |
| |
1055 if (error == 215) |
| |
1056 { |
| |
1057 gaim_debug_info("msn", "Invited user already in switchboard\n"); |
| |
1058 return; |
| |
1059 } |
| |
1060 else if (error == 217) |
| |
1061 { |
| |
1062 reason = MSN_SB_ERROR_USER_OFFLINE; |
| |
1063 } |
| |
1064 |
| |
1065 gaim_debug_warning("msn", "cal_error: command %s gave error %i\n", trans->command, error); |
| |
1066 |
| |
1067 cal_error_helper(trans, reason); |
| |
1068 } |
| |
1069 |
| |
1070 void |
| |
1071 msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user) |
| |
1072 { |
| |
1073 MsnTransaction *trans; |
| |
1074 MsnCmdProc *cmdproc; |
| |
1075 |
| |
1076 g_return_if_fail(swboard != NULL); |
| |
1077 |
| |
1078 cmdproc = swboard->cmdproc; |
| |
1079 |
| |
1080 trans = msn_transaction_new(cmdproc, "CAL", "%s", user); |
| |
1081 /* this doesn't do anything, but users seem to think that |
| |
1082 * 'Unhandled command' is some kind of error, so we don't report it */ |
| |
1083 msn_transaction_add_cb(trans, "CAL", got_cal); |
| |
1084 |
| |
1085 msn_transaction_set_data(trans, swboard); |
| |
1086 msn_transaction_set_timeout_cb(trans, cal_timeout); |
| |
1087 |
| |
1088 if (swboard->ready) |
| |
1089 msn_cmdproc_send_trans(cmdproc, trans); |
| |
1090 else |
| |
1091 msn_cmdproc_queue_trans(cmdproc, trans); |
| |
1092 } |
| |
1093 |
| |
1094 /************************************************************************** |
| |
1095 * Create & Transfer stuff |
| |
1096 **************************************************************************/ |
| |
1097 |
| |
1098 static void |
| |
1099 got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd) |
| |
1100 { |
| |
1101 MsnSwitchBoard *swboard; |
| |
1102 char *host; |
| |
1103 int port; |
| |
1104 swboard = cmd->trans->data; |
| |
1105 |
| |
1106 if (g_list_find(cmdproc->session->switches, swboard) == NULL) |
| |
1107 /* The conversation window was closed. */ |
| |
1108 return; |
| |
1109 |
| |
1110 msn_switchboard_set_auth_key(swboard, cmd->params[4]); |
| |
1111 |
| |
1112 msn_parse_socket(cmd->params[2], &host, &port); |
| |
1113 |
| |
1114 if (!msn_switchboard_connect(swboard, host, port)) |
| |
1115 msn_switchboard_destroy(swboard); |
| |
1116 |
| |
1117 g_free(host); |
| |
1118 } |
| |
1119 |
| |
1120 static void |
| |
1121 xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) |
| |
1122 { |
| |
1123 MsnSwitchBoard *swboard; |
| |
1124 int reason = MSN_SB_ERROR_UNKNOWN; |
| |
1125 |
| |
1126 if (error == 913) |
| |
1127 reason = MSN_SB_ERROR_OFFLINE; |
| |
1128 else if (error == 800) |
| |
1129 reason = MSN_SB_ERROR_TOO_FAST; |
| |
1130 |
| |
1131 swboard = trans->data; |
| |
1132 |
| |
1133 gaim_debug_info("msn", "xfr_error %i for %s: trans %x, command %s, reason %i\n", |
| |
1134 error, (swboard->im_user ? swboard->im_user : "(null)"), trans, |
| |
1135 (trans->command ? trans->command : "(null)"), reason); |
| |
1136 |
| |
1137 swboard_error_helper(swboard, reason, swboard->im_user); |
| |
1138 } |
| |
1139 |
| |
1140 void |
| |
1141 msn_switchboard_request(MsnSwitchBoard *swboard) |
| |
1142 { |
| |
1143 MsnCmdProc *cmdproc; |
| |
1144 MsnTransaction *trans; |
| |
1145 |
| |
1146 g_return_if_fail(swboard != NULL); |
| |
1147 |
| |
1148 cmdproc = swboard->session->notification->cmdproc; |
| |
1149 |
| |
1150 trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB"); |
| |
1151 msn_transaction_add_cb(trans, "XFR", got_swboard); |
| |
1152 |
| |
1153 msn_transaction_set_data(trans, swboard); |
| |
1154 msn_transaction_set_error_cb(trans, xfr_error); |
| |
1155 |
| |
1156 msn_cmdproc_send_trans(cmdproc, trans); |
| |
1157 } |
| |
1158 |
| |
1159 void |
| |
1160 msn_switchboard_close(MsnSwitchBoard *swboard) |
| |
1161 { |
| |
1162 g_return_if_fail(swboard != NULL); |
| |
1163 |
| |
1164 if (swboard->error != MSN_SB_ERROR_NONE) |
| |
1165 { |
| |
1166 msn_switchboard_destroy(swboard); |
| |
1167 } |
| |
1168 else if (g_queue_is_empty(swboard->msg_queue) || |
| |
1169 !swboard->session->connected) |
| |
1170 { |
| |
1171 MsnCmdProc *cmdproc; |
| |
1172 cmdproc = swboard->cmdproc; |
| |
1173 msn_cmdproc_send_quick(cmdproc, "OUT", NULL, NULL); |
| |
1174 |
| |
1175 msn_switchboard_destroy(swboard); |
| |
1176 } |
| |
1177 else |
| |
1178 { |
| |
1179 swboard->closed = TRUE; |
| |
1180 } |
| |
1181 } |
| |
1182 |
| |
1183 gboolean |
| |
1184 msn_switchboard_release(MsnSwitchBoard *swboard, MsnSBFlag flag) |
| |
1185 { |
| |
1186 g_return_val_if_fail(swboard != NULL, FALSE); |
| |
1187 |
| |
1188 swboard->flag &= ~flag; |
| |
1189 |
| |
1190 if (flag == MSN_SB_FLAG_IM) |
| |
1191 /* Forget any conversation that used to be associated with this |
| |
1192 * swboard. */ |
| |
1193 swboard->conv = NULL; |
| |
1194 |
| |
1195 if (swboard->flag == 0) |
| |
1196 { |
| |
1197 msn_switchboard_close(swboard); |
| |
1198 return TRUE; |
| |
1199 } |
| |
1200 |
| |
1201 return FALSE; |
| |
1202 } |
| |
1203 |
| |
1204 /************************************************************************** |
| |
1205 * Init stuff |
| |
1206 **************************************************************************/ |
| |
1207 |
| |
1208 void |
| |
1209 msn_switchboard_init(void) |
| |
1210 { |
| |
1211 cbs_table = msn_table_new(); |
| |
1212 |
| |
1213 msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd); |
| |
1214 msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd); |
| |
1215 |
| |
1216 msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd); |
| |
1217 msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd); |
| |
1218 |
| |
1219 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); |
| |
1220 |
| |
1221 msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd); |
| |
1222 msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd); |
| |
1223 msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd); |
| |
1224 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd); |
| |
1225 |
| |
1226 #if 0 |
| |
1227 /* They might skip the history */ |
| |
1228 msn_table_add_cmd(cbs_table, NULL, "ACK", NULL); |
| |
1229 #endif |
| |
1230 |
| |
1231 msn_table_add_error(cbs_table, "MSG", msg_error); |
| |
1232 msn_table_add_error(cbs_table, "CAL", cal_error); |
| |
1233 |
| |
1234 /* Register the message type callbacks. */ |
| |
1235 msn_table_add_msg_type(cbs_table, "text/plain", |
| |
1236 plain_msg); |
| |
1237 msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol", |
| |
1238 control_msg); |
| |
1239 msn_table_add_msg_type(cbs_table, "text/x-clientcaps", |
| |
1240 clientcaps_msg); |
| |
1241 msn_table_add_msg_type(cbs_table, "text/x-clientinfo", |
| |
1242 clientcaps_msg); |
| |
1243 msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p", |
| |
1244 msn_p2p_msg); |
| |
1245 msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon", |
| |
1246 msn_emoticon_msg); |
| |
1247 msn_table_add_msg_type(cbs_table, "text/x-mms-animemoticon", |
| |
1248 msn_emoticon_msg); |
| |
1249 msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast", |
| |
1250 nudge_msg); |
| |
1251 #if 0 |
| |
1252 msn_table_add_msg_type(cbs_table, "text/x-msmmsginvite", |
| |
1253 msn_invite_msg); |
| |
1254 #endif |
| |
1255 } |
| |
1256 |
| |
1257 void |
| |
1258 msn_switchboard_end(void) |
| |
1259 { |
| |
1260 msn_table_destroy(cbs_table); |
| |
1261 } |