comparison src/protocols/msn/switchboard.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 17ef51dc609c
children 2185ced3b087
comparison
equal deleted inserted replaced
8807:482fc53c969d 8808:bbd8cdaf0ad5
23 #include "msnslp.h" 23 #include "msnslp.h"
24 #include "prefs.h" 24 #include "prefs.h"
25 #include "switchboard.h" 25 #include "switchboard.h"
26 #include "utils.h" 26 #include "utils.h"
27 27
28 static GHashTable *switchboard_commands = NULL; 28 static MsnTable *cbs_table = NULL;
29 static GHashTable *switchboard_msg_types = NULL;
30 29
31 /************************************************************************** 30 /**************************************************************************
32 * Utility functions 31 * Utility functions
33 **************************************************************************/ 32 **************************************************************************/
34 static gboolean 33 static void
35 send_clientcaps(MsnSwitchBoard *swboard) 34 send_clientcaps(MsnSwitchBoard *swboard)
36 { 35 {
37 MsnMessage *msg; 36 MsnMessage *msg;
38 37
39 msg = msn_message_new(); 38 msg = msn_message_new();
40 msn_message_set_content_type(msg, "text/x-clientcaps"); 39 msn_message_set_content_type(msg, "text/x-clientcaps");
41 msn_message_set_charset(msg, NULL); 40 msn_message_set_charset(msg, NULL);
42 msn_message_set_attr(msg, "User-Agent", NULL); 41 msn_message_set_attr(msg, "User-Agent", NULL);
43 msn_message_set_body(msg, MSN_CLIENTINFO); 42 msn_message_set_body(msg, MSN_CLIENTINFO);
44 43
45 if (!msn_switchboard_send_msg(swboard, msg)) 44 msn_switchboard_send_msg(swboard, msg);
46 {
47 gaim_debug_warning("msn",
48 "Unable to send clientcaps. "
49 "Disconnecting from switchboard.\n");
50 msn_switchboard_destroy(swboard);
51
52 msn_message_destroy(msg);
53
54 return FALSE;
55 }
56 45
57 msn_message_destroy(msg); 46 msn_message_destroy(msg);
58
59 return TRUE;
60 }
61
62 /**************************************************************************
63 * Catch-all commands
64 **************************************************************************/
65 static gboolean
66 blank_cmd(MsnServConn *servconn, const char *command, const char **params,
67 size_t param_count)
68 {
69 return TRUE;
70 }
71
72 static gboolean
73 unknown_cmd(MsnServConn *servconn, const char *command, const char **params,
74 size_t param_count)
75 {
76 gaim_debug(GAIM_DEBUG_ERROR, "msg",
77 "Handled switchboard message: %s\n", command);
78
79 return FALSE;
80 } 47 }
81 48
82 /************************************************************************** 49 /**************************************************************************
83 * Switchboard Commands 50 * Switchboard Commands
84 **************************************************************************/ 51 **************************************************************************/
85 static gboolean 52 static void
86 ans_cmd(MsnServConn *servconn, const char *command, const char **params, 53 ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
87 size_t param_count) 54 {
88 { 55 MsnSwitchBoard *swboard;
89 MsnSwitchBoard *swboard = servconn->data; 56 MsnSession *session;
90 MsnSession *session = servconn->session; 57
91 58 swboard = cmdproc->servconn->data;
92 /*send_clientcaps(swboard);*/ 59 session = cmdproc->session;
60
61 /* send_clientcaps(swboard); */
93 62
94 if (0 && session->protocol_ver >= 9) 63 if (0 && session->protocol_ver >= 9)
95 { 64 {
96 MsnUser *local_user, *remote_user; 65 MsnUser *local_user, *remote_user;
97 66
110 local_user, remote_user, 79 local_user, remote_user,
111 msn_user_get_object(remote_user)); 80 msn_user_get_object(remote_user));
112 } 81 }
113 } 82 }
114 83
115 return TRUE; 84 swboard->joined = TRUE;
116 } 85 }
117 86
118 static gboolean 87 static void
119 bye_cmd(MsnServConn *servconn, const char *command, const char **params, 88 bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
120 size_t param_count) 89 {
121 { 90 GaimAccount *account;
122 GaimAccount *account = servconn->session->account; 91 MsnSwitchBoard *swboard;
123 MsnSwitchBoard *swboard = servconn->data; 92 const char *user = cmd->params[0];
124 const char *user = params[0]; 93
94 account = cmdproc->session->account;
95 swboard = cmdproc->servconn->data;
125 96
126 if (swboard->hidden) 97 if (swboard->hidden)
127 return TRUE; 98 return;
128 99
129 if (swboard->chat != NULL) 100 if (swboard->chat != NULL)
130 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->chat), user, NULL); 101 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(swboard->chat), user, NULL);
131 else 102 else
132 { 103 {
140 else 111 else
141 username = user; 112 username = user;
142 113
143 *buf = '\0'; 114 *buf = '\0';
144 115
145 if (param_count == 2 && atoi(params[1]) == 1) 116 if (cmd->param_count == 2 && atoi(cmd->params[1]) == 1)
146 { 117 {
147 if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice")) 118 if (gaim_prefs_get_bool("/plugins/prpl/msn/conv_timeout_notice"))
148 { 119 {
149 g_snprintf(buf, sizeof(buf), 120 g_snprintf(buf, sizeof(buf),
150 _("The conversation has become inactive " 121 _("The conversation has become inactive "
167 gaim_conversation_write(conv, NULL, buf, GAIM_MESSAGE_SYSTEM, 138 gaim_conversation_write(conv, NULL, buf, GAIM_MESSAGE_SYSTEM,
168 time(NULL)); 139 time(NULL));
169 } 140 }
170 141
171 msn_switchboard_destroy(swboard); 142 msn_switchboard_destroy(swboard);
172 143 }
173 return FALSE; 144 }
174 } 145
175 146 static void
176 return TRUE; 147 iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
177 } 148 {
178 149 GaimAccount *account;
179 static gboolean 150 GaimConnection *gc;
180 iro_cmd(MsnServConn *servconn, const char *command, const char **params, 151 MsnSwitchBoard *swboard;
181 size_t param_count) 152
182 { 153 account = cmdproc->session->account;
183 GaimAccount *account = servconn->session->account; 154 gc = account->gc;
184 GaimConnection *gc = account->gc; 155 swboard = cmdproc->servconn->data;
185 MsnSwitchBoard *swboard = servconn->data; 156
186 157 swboard->total_users = atoi(cmd->params[2]) + 1;
187 swboard->total_users = atoi(params[2]) + 1; 158
188 159 if (swboard->total_users > 2)
189 if (swboard->total_users > 2) { 160 {
190 if (swboard->chat == NULL) { 161 if (swboard->chat == NULL)
162 {
191 GaimConversation *conv; 163 GaimConversation *conv;
192 164
193 conv = gaim_find_conversation_with_account( 165 conv = gaim_find_conversation_with_account(
194 msn_user_get_passport(swboard->user), account); 166 msn_user_get_passport(swboard->user), account);
195 167
196 servconn->session->last_chat_id++; 168 cmdproc->session->last_chat_id++;
197 swboard->chat_id = servconn->session->last_chat_id; 169 swboard->chat_id = cmdproc->session->last_chat_id;
198 swboard->chat = serv_got_joined_chat(gc, swboard->chat_id, 170 swboard->chat = serv_got_joined_chat(gc, swboard->chat_id,
199 "MSN Chat"); 171 "MSN Chat");
200 172
201 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), 173 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat),
202 gaim_account_get_username(account), NULL); 174 gaim_account_get_username(account), NULL);
203 175
204 gaim_conversation_destroy(conv); 176 gaim_conversation_destroy(conv);
205 } 177 }
206 178
207 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), params[3], NULL); 179 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), cmd->params[3], NULL);
208 } 180 }
209 181 }
210 return TRUE; 182
211 } 183 static void
212 184 joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
213 static gboolean 185 {
214 joi_cmd(MsnServConn *servconn, const char *command, const char **params, 186 GaimAccount *account;
215 size_t param_count) 187 GaimConnection *gc;
216 { 188 MsnSwitchBoard *swboard;
217 GaimAccount *account = servconn->session->account;
218 GaimConnection *gc = account->gc;
219 MsnSwitchBoard *swboard = servconn->data;
220 const char *passport; 189 const char *passport;
221 190
222 passport = params[0]; 191 account = cmdproc->session->account;
223 192 gc = account->gc;
224 if (swboard->total_users == 2 && swboard->chat == NULL) { 193 swboard = cmdproc->servconn->data;
194 passport = cmd->params[0];
195
196 if (swboard->total_users == 2 && swboard->chat == NULL)
197 {
225 GaimConversation *conv; 198 GaimConversation *conv;
226 199
227 conv = gaim_find_conversation_with_account( 200 conv = gaim_find_conversation_with_account(
228 msn_user_get_passport(swboard->user), account); 201 msn_user_get_passport(swboard->user), account);
229 202
230 servconn->session->last_chat_id++; 203 cmdproc->session->last_chat_id++;
231 swboard->chat_id = servconn->session->last_chat_id; 204 swboard->chat_id = cmdproc->session->last_chat_id;
232 swboard->chat = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat"); 205 swboard->chat = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat");
233 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), 206 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat),
234 msn_user_get_passport(swboard->user), NULL); 207 msn_user_get_passport(swboard->user), NULL);
235 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), 208 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat),
236 gaim_account_get_username(account), NULL); 209 gaim_account_get_username(account), NULL);
237 210
238 msn_user_unref(swboard->user); 211 msn_user_unref(swboard->user);
239 212
240 gaim_conversation_destroy(conv); 213 gaim_conversation_destroy(conv);
241 } 214 }
243 if (swboard->chat != NULL) 216 if (swboard->chat != NULL)
244 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), passport, NULL); 217 gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), passport, NULL);
245 218
246 swboard->total_users++; 219 swboard->total_users++;
247 220
248 while (servconn->txqueue) { 221 swboard->joined = TRUE;
249 char *buf = servconn->txqueue->data; 222
250 223 msn_cmdproc_process_queue(cmdproc);
251 servconn->txqueue = g_slist_remove(servconn->txqueue, buf); 224
252 225 send_clientcaps(swboard);
253 if (msn_servconn_write(swboard->servconn, buf, strlen(buf)) < 0) { 226 }
254 msn_switchboard_destroy(swboard); 227
255 228 static void
256 return FALSE; 229 msg_cmd_post(MsnCmdProc *cmdproc, char *payload, size_t len)
257 }
258 }
259
260 return send_clientcaps(swboard);
261 }
262
263 static void
264 msg_cmd_post(MsnServConn *servconn, char *payload, size_t len)
265 { 230 {
266 MsnMessage *msg = msn_message_new(); 231 MsnMessage *msg = msn_message_new();
267 232
268 msg->passport = servconn->msg_passport;
269
270 msn_message_parse_payload(msg, payload, len); 233 msn_message_parse_payload(msg, payload, len);
271 234
272 msn_servconn_process_message(servconn, msg); 235 msg->passport = cmdproc->temp;
236 msn_cmdproc_process_msg(cmdproc, msg);
237 g_free(cmdproc->temp);
238 cmdproc->temp = NULL;
273 239
274 msn_message_destroy(msg); 240 msn_message_destroy(msg);
275 } 241 }
276 242
277 static gboolean 243 static void
278 msg_cmd(MsnServConn *servconn, const char *command, const char **params, 244 msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
279 size_t param_count)
280 { 245 {
281 gaim_debug(GAIM_DEBUG_INFO, "msn", "Found message. Parsing.\n"); 246 gaim_debug(GAIM_DEBUG_INFO, "msn", "Found message. Parsing.\n");
282 247
283 servconn->payload_cb = msg_cmd_post; 248 cmdproc->payload_cb = msg_cmd_post;
284 servconn->payload_len = atoi(params[2]); 249 cmdproc->servconn->payload_len = atoi(cmd->params[2]);
285 250 cmdproc->temp = g_strdup(cmd->params[0]);
286 servconn->msg_passport = g_strdup(params[0]); 251 }
287 252
288 return TRUE; 253 static void
289 } 254 nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
290
291 static gboolean
292 nak_cmd(MsnServConn *servconn, const char *command, const char **params,
293 size_t param_count)
294 { 255 {
295 /* 256 /*
296 * TODO: Investigate this, as it seems to occur frequently with 257 * TODO: Investigate this, as it seems to occur frequently with
297 * the old prpl. 258 * the old prpl.
259 *
260 * shx: This will only happend in the new protocol when we ask for it
261 * in the message flags.
298 */ 262 */
299 gaim_notify_error(servconn->session->account->gc, NULL, 263 gaim_notify_error(cmdproc->servconn->session->account->gc, NULL,
300 _("An MSN message may not have been received."), NULL); 264 _("An MSN message may not have been received."), NULL);
301 265 }
302 return TRUE; 266
303 } 267 static void
304 268 out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
305 static gboolean 269 {
306 out_cmd(MsnServConn *servconn, const char *command, const char **params, 270 GaimConnection *gc;
307 size_t param_count) 271 MsnSwitchBoard *swboard;
308 { 272
309 GaimConnection *gc = servconn->session->account->gc; 273 gc = cmdproc->servconn->session->account->gc;
310 MsnSwitchBoard *swboard = servconn->data; 274 swboard = cmdproc->servconn->data;
311 275
312 if (swboard->chat != NULL) 276 if (swboard->chat != NULL)
313 { 277 {
314 serv_got_chat_left(gc, 278 serv_got_chat_left(gc,
315 gaim_conv_chat_get_id(GAIM_CONV_CHAT(swboard->chat))); 279 gaim_conv_chat_get_id(GAIM_CONV_CHAT(swboard->chat)));
316 } 280 }
317 281
318 msn_switchboard_destroy(swboard); 282 msn_switchboard_destroy(swboard);
319 283 }
320 return FALSE; 284
321 } 285 static void
322 286 usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
323 static gboolean 287 {
324 usr_cmd(MsnServConn *servconn, const char *command, const char **params, 288 MsnSwitchBoard *swboard;
325 size_t param_count) 289
326 { 290 swboard = cmdproc->servconn->data;
327 MsnSwitchBoard *swboard = servconn->data; 291
328 292 msn_cmdproc_send(swboard->cmdproc, "CAL", "%s",
329 if (!msn_switchboard_send_command(swboard, "CAL", 293 msn_user_get_passport(swboard->user));
330 msn_user_get_passport(swboard->user)))
331 {
332 msn_switchboard_destroy(swboard);
333
334 return FALSE;
335 }
336
337 return TRUE;
338 } 294 }
339 295
340 /************************************************************************** 296 /**************************************************************************
341 * Message Types 297 * Message Types
342 **************************************************************************/ 298 **************************************************************************/
343 static gboolean 299 static void
344 plain_msg(MsnServConn *servconn, MsnMessage *msg) 300 plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
345 { 301 {
346 GaimConnection *gc = servconn->session->account->gc; 302 GaimConnection *gc;
347 MsnSwitchBoard *swboard = servconn->data; 303 MsnSwitchBoard *swboard;
348 char *body; 304 char *body;
305 char *passport;
349 const char *value; 306 const char *value;
350 307
308 gc = cmdproc->session->account->gc;
309 swboard = cmdproc->servconn->data;
351 body = gaim_escape_html(msn_message_get_body(msg)); 310 body = gaim_escape_html(msn_message_get_body(msg));
352 311 passport = msg->passport;
353 if (!strcmp(msg->passport, "messenger@microsoft.com") && 312
313 if (!strcmp(passport, "messenger@microsoft.com") &&
354 strstr(body, "immediate security update")) 314 strstr(body, "immediate security update"))
355 { 315 {
356 g_free(body); 316 g_free(body);
357 317
358 return TRUE; 318 return;
359 } 319 }
360 320
361 #if 0 321 #if 0
362 gaim_debug(GAIM_DEBUG_INFO, "msn", "Checking User-Agent...\n"); 322 gaim_debug(GAIM_DEBUG_INFO, "msn", "Checking User-Agent...\n");
363 323
364 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) { 324 if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) {
365 gaim_debug(GAIM_DEBUG_MISC, "msn", "value = '%s'\n", value); 325 gaim_debug(GAIM_DEBUG_MISC, "msn", "value = '%s'\n", value);
366 } 326 }
367 #endif 327 #endif
368 328
369 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) { 329 if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL)
330 {
370 char *pre_format, *post_format; 331 char *pre_format, *post_format;
371 332
372 msn_parse_format(value, &pre_format, &post_format); 333 msn_parse_format(value, &pre_format, &post_format);
373 334
374 body = g_strdup_printf("%s%s%s", pre_format, body, post_format); 335 body = g_strdup_printf("%s%s%s", pre_format, body, post_format);
379 340
380 if (swboard->chat != NULL) 341 if (swboard->chat != NULL)
381 { 342 {
382 serv_got_chat_in(gc, 343 serv_got_chat_in(gc,
383 gaim_conv_chat_get_id(GAIM_CONV_CHAT(swboard->chat)), 344 gaim_conv_chat_get_id(GAIM_CONV_CHAT(swboard->chat)),
384 msg->passport, 0, body, time(NULL)); 345 passport, 0, body, time(NULL));
385 } 346 }
386 else 347 else
387 serv_got_im(gc, msg->passport, body, 0, time(NULL)); 348 serv_got_im(gc, passport, body, 0, time(NULL));
388 349
389 g_free(body); 350 g_free(body);
390 351 }
391 return TRUE; 352
392 } 353 static void
393 354 control_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
394 static gboolean 355 {
395 control_msg(MsnServConn *servconn, MsnMessage *msg) 356 GaimConnection *gc;
396 { 357 MsnSwitchBoard *swboard;
397 GaimConnection *gc = servconn->session->account->gc; 358 char *passport;
398 MsnSwitchBoard *swboard = servconn->data;
399 const char *value; 359 const char *value;
400 360
361 gc = cmdproc->session->account->gc;
362 swboard = cmdproc->servconn->data;
363 passport = msg->passport;
364
401 if (swboard->chat == NULL && 365 if (swboard->chat == NULL &&
402 (value = msn_message_get_attr(msg, "TypingUser")) != NULL) { 366 (value = msn_message_get_attr(msg, "TypingUser")) != NULL)
403 367 {
404 serv_got_typing(gc, msg->passport, MSN_TYPING_RECV_TIMEOUT, 368 serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
405 GAIM_TYPING); 369 GAIM_TYPING);
406 } 370 }
407 371 }
408 return TRUE; 372
409 } 373 static void
410 374 clientcaps_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
411 static gboolean
412 clientcaps_msg(MsnServConn *servconn, MsnMessage *msg)
413 { 375 {
414 #if 0 376 #if 0
415 MsnSession *session = servconn->session; 377 MsnSession *session;
416 MsnSwitchBoard *swboard = servconn->data; 378 MsnSwitchBoard *swboard;
417 MsnUser *user; 379 MsnUser *user;
418 GHashTable *clientcaps; 380 GHashTable *clientcaps;
419 const char *value; 381 const char *value;
420 382
383 session = cmdproc->session;
384 swboard = cmdproc->servconn->data;
385
421 user = msn_user_new(session, msg->passport, NULL); 386 user = msn_user_new(session, msg->passport, NULL);
422 387
423 clientcaps = msn_message_get_hashtable_from_body(msg); 388 clientcaps = msn_message_get_hashtable_from_body(msg);
424 #endif 389 #endif
425
426 return TRUE;
427 } 390 }
428 391
429 /************************************************************************** 392 /**************************************************************************
430 * Connect stuff 393 * Connect stuff
431 **************************************************************************/ 394 **************************************************************************/
432 static gboolean 395 static gboolean
433 connect_cb(MsnServConn *servconn) 396 connect_cb(MsnServConn *servconn)
434 { 397 {
435 GaimAccount *account = servconn->session->account; 398 GaimAccount *account;
436 MsnSwitchBoard *swboard = servconn->data; 399 MsnSwitchBoard *swboard;
437 char outparams[MSN_BUF_LEN]; 400
401 account = servconn->session->account;
402 swboard = servconn->data;
438 403
439 swboard->in_use = TRUE; 404 swboard->in_use = TRUE;
440 405
441 gaim_debug(GAIM_DEBUG_INFO, "msn", "Connecting to switchboard...\n"); 406 gaim_debug_info("msn", "Connecting to switchboard...\n");
442 407
443 if (msn_switchboard_is_invited(swboard)) { 408 if (msn_switchboard_is_invited(swboard))
444 g_snprintf(outparams, sizeof(outparams), "%s %s %s", 409 {
445 gaim_account_get_username(account), 410 msn_cmdproc_send(swboard->cmdproc, "ANS", "%s %s %s",
446 swboard->auth_key, swboard->session_id); 411 gaim_account_get_username(account),
447 412 swboard->auth_key, swboard->session_id);
448 if (!msn_switchboard_send_command(swboard, "ANS", outparams)) { 413 }
449 msn_switchboard_destroy(swboard); 414 else
450 415 {
451 return FALSE; 416 msn_cmdproc_send(swboard->cmdproc, "USR", "%s %s",
452 } 417 gaim_account_get_username(account),
453 } 418 swboard->auth_key);
454 else { 419 }
455 g_snprintf(outparams, sizeof(outparams), "%s %s", 420
456 gaim_account_get_username(account), swboard->auth_key); 421 if (swboard->cmdproc->error)
457 422 return FALSE;
458 if (!msn_switchboard_send_command(swboard, "USR", outparams)) {
459 msn_switchboard_destroy(swboard);
460
461 return FALSE;
462 }
463 }
464 423
465 return TRUE; 424 return TRUE;
466 } 425 }
467 426
468 static void 427 static void
469 disconnect_cb(MsnServConn *servconn) 428 disconnect_cb(MsnServConn *servconn)
470 { 429 {
471 MsnSwitchBoard *swboard; 430 MsnSwitchBoard *swboard;
472 431
473 swboard = servconn->data; 432 swboard = servconn->data;
433
474 if (!swboard->destroying) 434 if (!swboard->destroying)
475 msn_switchboard_destroy(swboard); 435 msn_switchboard_destroy(swboard);
476 } 436 }
477 437
438 void
439 msn_switchboard_init(void)
440 {
441 cbs_table = msn_table_new();
442
443 /* Register the command callbacks. */
444 msn_table_add_cmd(cbs_table, NULL, "ACK", NULL);
445
446 msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd);
447 msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd);
448
449 msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd);
450
451 msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd);
452
453 msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd);
454 msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd);
455 msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd);
456 msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd);
457
458 /* Register the message type callbacks. */
459 msn_table_add_msg_type(cbs_table, "text/plain",
460 plain_msg);
461 msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol",
462 control_msg);
463 msn_table_add_msg_type(cbs_table, "text/x-clientcaps",
464 clientcaps_msg);
465 msn_table_add_msg_type(cbs_table, "text/x-clientinfo",
466 clientcaps_msg);
467 #if 0
468 msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p",
469 msn_p2p_msg);
470 #endif
471 }
472
473 void
474 msn_switchboard_end(void)
475 {
476 msn_table_destroy(cbs_table);
477 }
478
478 MsnSwitchBoard * 479 MsnSwitchBoard *
479 msn_switchboard_new(MsnSession *session) 480 msn_switchboard_new(MsnSession *session)
480 { 481 {
481 MsnSwitchBoard *swboard; 482 MsnSwitchBoard *swboard;
482 MsnServConn *servconn; 483 MsnServConn *servconn;
484 MsnCmdProc *cmdproc;
483 485
484 g_return_val_if_fail(session != NULL, NULL); 486 g_return_val_if_fail(session != NULL, NULL);
485 487
486 swboard = g_new0(MsnSwitchBoard, 1); 488 swboard = g_new0(MsnSwitchBoard, 1);
487 489
488 swboard->servconn = servconn = msn_servconn_new(session); 490 swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVER_SB);
491 cmdproc = swboard->cmdproc = servconn->cmdproc;
492
489 msn_servconn_set_connect_cb(servconn, connect_cb); 493 msn_servconn_set_connect_cb(servconn, connect_cb);
490 msn_servconn_set_disconnect_cb(servconn, disconnect_cb); 494 msn_servconn_set_disconnect_cb(servconn, disconnect_cb);
491 495
492 if (session->http_method) 496 if (session->http_method)
493 swboard->servconn->http_data->server_type = "SB"; 497 swboard->servconn->http_data->server_type = "SB";
494 498
495 servconn->data = swboard; 499 servconn->data = swboard;
496 500
497 session->switches = g_list_append(session->switches, swboard); 501 session->switches = g_list_append(session->switches, swboard);
498 502
499 if (switchboard_commands == NULL) { 503 cmdproc->cbs_table = cbs_table;
500 /* Register the command callbacks. */
501 msn_servconn_register_command(servconn, "ACK", blank_cmd);
502 msn_servconn_register_command(servconn, "ANS", ans_cmd);
503 msn_servconn_register_command(servconn, "BYE", bye_cmd);
504 msn_servconn_register_command(servconn, "CAL", blank_cmd);
505 msn_servconn_register_command(servconn, "IRO", iro_cmd);
506 msn_servconn_register_command(servconn, "JOI", joi_cmd);
507 msn_servconn_register_command(servconn, "MSG", msg_cmd);
508 msn_servconn_register_command(servconn, "NAK", nak_cmd);
509 msn_servconn_register_command(servconn, "NLN", blank_cmd);
510 msn_servconn_register_command(servconn, "OUT", out_cmd);
511 msn_servconn_register_command(servconn, "USR", usr_cmd);
512 msn_servconn_register_command(servconn, "_UNKNOWN_",unknown_cmd);
513
514 /* Register the message type callbacks. */
515 msn_servconn_register_msg_type(servconn, "text/plain",plain_msg);
516 msn_servconn_register_msg_type(servconn, "text/x-msmsgscontrol",
517 control_msg);
518 msn_servconn_register_msg_type(servconn, "text/x-clientcaps",
519 clientcaps_msg);
520 msn_servconn_register_msg_type(servconn, "text/x-clientinfo",
521 clientcaps_msg);
522 #if 0
523 msn_servconn_register_msg_type(servconn, "application/x-msnmsgrp2p",
524 msn_p2p_msg);
525 #endif
526
527 /* Save these for future use. */
528 switchboard_commands = servconn->commands;
529 switchboard_msg_types = servconn->msg_types;
530 }
531 else {
532 g_hash_table_destroy(servconn->commands);
533 g_hash_table_destroy(servconn->msg_types);
534
535 servconn->commands = switchboard_commands;
536 servconn->msg_types = switchboard_msg_types;
537 }
538 504
539 return swboard; 505 return swboard;
540 } 506 }
541 507
542 void 508 void
660 msn_servconn_disconnect(swboard->servconn); 626 msn_servconn_disconnect(swboard->servconn);
661 627
662 swboard->in_use = FALSE; 628 swboard->in_use = FALSE;
663 } 629 }
664 630
665 gboolean 631 void
666 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) 632 msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
667 { 633 {
668 char *buf; 634 MsnCmdProc *cmdproc;
635 MsnTransaction *trans;
669 char *payload; 636 char *payload;
670 size_t len;
671 size_t payload_len; 637 size_t payload_len;
672 int ret; 638
673 #if 0 639 g_return_if_fail(swboard != NULL);
674 FILE *fp; 640 g_return_if_fail(msg != NULL);
675 #endif 641
676 642 cmdproc = swboard->servconn->cmdproc;
677 g_return_val_if_fail(swboard != NULL, FALSE);
678 g_return_val_if_fail(msg != NULL, FALSE);
679
680 buf = g_strdup_printf("MSG %d %c %d\r\n", ++swboard->trId,
681 msn_message_get_flag(msg), (int)msg->size);
682
683 len = strlen(buf);
684
685 payload = msn_message_gen_payload(msg, &payload_len); 643 payload = msn_message_gen_payload(msg, &payload_len);
686 644
687 if (payload != NULL) 645 trans = msn_transaction_new("MSG", "%c %d", msn_message_get_flag(msg),
688 { 646 payload_len);
689 buf = g_realloc(buf, len + payload_len + 1); 647
690 memcpy(buf + len, payload, payload_len); 648 trans->payload = payload;
691 len += payload_len; 649 trans->payload_len = payload_len;
692 buf[len] = 0; 650
693 } 651 if (!g_queue_is_empty(cmdproc->txqueue) || !swboard->joined)
694 652 msn_cmdproc_queue_trans(cmdproc, trans);
695 if (swboard->servconn->txqueue != NULL || !swboard->in_use)
696 {
697 gaim_debug(GAIM_DEBUG_INFO, "msn", "Appending message to queue.\n");
698
699 swboard->servconn->txqueue =
700 g_slist_append(swboard->servconn->txqueue, buf);
701
702 return TRUE;
703 }
704
705 ret = msn_servconn_write(swboard->servconn, buf, len);
706
707 #if 0
708 /* Windows doesn't like Unix paths */
709 fp = fopen("/tmp/msn-msg", "ab");
710 fwrite(buf, 1, len, fp);
711 fclose(fp);
712 #endif
713
714 g_free(buf);
715
716 return (ret > 0);
717 }
718
719 gboolean
720 msn_switchboard_send_command(MsnSwitchBoard *swboard, const char *command,
721 const char *params)
722 {
723 char buf[MSN_BUF_LEN];
724
725 g_return_val_if_fail(swboard != NULL, FALSE);
726 g_return_val_if_fail(command != NULL, FALSE);
727
728 if (params == NULL)
729 g_snprintf(buf, sizeof(buf), "%s %u\r\n", command,
730 ++swboard->trId);
731 else 653 else
732 g_snprintf(buf, sizeof(buf), "%s %u %s\r\n", 654 msn_cmdproc_send_trans(cmdproc, trans);
733 command, ++swboard->trId, params); 655 }
734
735 return (msn_servconn_write(swboard->servconn, buf, strlen(buf)) > 0);
736 }