Mercurial > pidgin.yaz
comparison src/protocols/bonjour/jabber.c @ 13902:425e0f861e88
[gaim-migrate @ 16390]
A small part of sf patch #1490646, from Jonty Wareing & Jono Cole
"Fix & Enhance the Bonjour prpl"
"Several instances of "magic strings" have been replaced
with proper XML parsing code in the Bonjour prpl,
allowing it to communicate with other Gaim clients (a
misplaced space in one of the strings prevented this),
and every other Bonjour chat client we can find.
A fair amount of completely redundant code was also
stripped, which in combination with the proper XML
parsing allows the client to be far more flexible about
Jabber errors in other clients."
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 01 Jul 2006 22:32:20 +0000 |
parents | 47c3d00713af |
children | 8264f52a1142 |
comparison
equal
deleted
inserted
replaced
13901:e40263ba9680 | 13902:425e0f861e88 |
---|---|
307 GaimAccount *account = gb->account; | 307 GaimAccount *account = gb->account; |
308 GaimConversation *conversation; | 308 GaimConversation *conversation; |
309 char *closed_conv_message; | 309 char *closed_conv_message; |
310 BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; | 310 BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; |
311 gboolean closed_conversation = FALSE; | 311 gboolean closed_conversation = FALSE; |
312 xmlnode *message_node = NULL; | |
312 | 313 |
313 /* Read the data from the socket */ | 314 /* Read the data from the socket */ |
314 if ((message_length = _read_data(socket, &message)) == -1) { | 315 if ((message_length = _read_data(socket, &message)) == -1) { |
315 /* There have been an error reading from the socket */ | 316 /* There have been an error reading from the socket */ |
316 return; | 317 return; |
323 message[message_length - 1] = '\0'; | 324 message[message_length - 1] = '\0'; |
324 message_length--; | 325 message_length--; |
325 } | 326 } |
326 } | 327 } |
327 | 328 |
328 /* Check if the start of the doctype has been received, if not check that the current */ | 329 /* Parse the message into an XMLnode for analysis */ |
329 /* data is the doctype */ | 330 message_node = xmlnode_from_str(message, strlen(message)); |
330 if (!(bb->conversation->start_step_one)) | |
331 { | |
332 if (g_str_has_prefix(message, DOCTYPE_DECLARATION)) | |
333 { | |
334 bb->conversation->start_step_one = TRUE; | |
335 } | |
336 } | |
337 | 331 |
338 /* Check if the start of the stream has been received, if not check that the current */ | 332 /* Check if the start of the stream has been received, if not check that the current */ |
339 /* data is the start of the stream */ | 333 /* data is the start of the stream */ |
340 if (!(bb->conversation->start_step_two)) | 334 if (!(bb->conversation->stream_started)) |
341 { | 335 { |
342 if (g_str_has_suffix(message, STREAM_START)) { | 336 /* Check if this is the start of the stream */ |
343 bb->conversation->start_step_two = TRUE; | 337 if ((message_node != NULL) && |
344 | 338 g_ascii_strcasecmp(xmlnode_get_attrib(message_node, "xmlns"), "jabber:client") && |
345 /* If we haven't done it yet, we have to sent the start of the stream to the other buddy */ | 339 (xmlnode_get_attrib(message_node,"xmlns:stream") != NULL)) |
346 if (!(bb->conversation->stream_started)) { | 340 { |
347 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) { | 341 bb->conversation->stream_started = TRUE; |
348 gaim_debug_error("bonjour", "Unable to start a conversation with %s\n", bb->name); | 342 } |
349 } | 343 else |
344 { | |
345 /* TODO: This needs to be nonblocking! */ | |
346 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) | |
347 { | |
348 gaim_debug_error("bonjour", "Unable to start a conversation with %s\n", bb->name); | |
350 } | 349 } |
351 } | 350 else |
352 return; | 351 { |
353 } | 352 bb->conversation->stream_started = TRUE; |
354 | 353 } |
355 /* Check that this is not the end of the conversation */ | 354 } |
355 } | |
356 | |
357 /* | |
358 * Check that this is not the end of the conversation. This is | |
359 * using a magic string, but xmlnode won't play nice when just | |
360 * parsing an end tag | |
361 */ | |
356 if (g_str_has_prefix(message, STREAM_END) || (closed_conversation == TRUE)) { | 362 if (g_str_has_prefix(message, STREAM_END) || (closed_conversation == TRUE)) { |
357 /* Close the socket, clear the watcher and free memory */ | 363 /* Close the socket, clear the watcher and free memory */ |
358 if (bb->conversation != NULL) { | 364 if (bb->conversation != NULL) { |
359 close(bb->conversation->socket); | 365 close(bb->conversation->socket); |
360 gaim_input_remove(bb->conversation->watcher_id); | 366 gaim_input_remove(bb->conversation->watcher_id); |
370 g_free(closed_conv_message); | 376 g_free(closed_conv_message); |
371 } else { | 377 } else { |
372 /* Parse the message to get the data and send to the ui */ | 378 /* Parse the message to get the data and send to the ui */ |
373 _jabber_parse_and_write_message_to_ui(message, account->gc, gb); | 379 _jabber_parse_and_write_message_to_ui(message, account->gc, gb); |
374 } | 380 } |
381 | |
382 xmlnode_free(message_node); | |
375 } | 383 } |
376 | 384 |
377 static void | 385 static void |
378 _server_socket_handler(gpointer data, int server_socket, GaimInputCondition condition) | 386 _server_socket_handler(gpointer data, int server_socket, GaimInputCondition condition) |
379 { | 387 { |
417 /* Check if the conversation has been previously started */ | 425 /* Check if the conversation has been previously started */ |
418 if (bb->conversation == NULL) | 426 if (bb->conversation == NULL) |
419 { | 427 { |
420 bb->conversation = g_new(BonjourJabberConversation, 1); | 428 bb->conversation = g_new(BonjourJabberConversation, 1); |
421 bb->conversation->socket = client_socket; | 429 bb->conversation->socket = client_socket; |
422 bb->conversation->start_step_one = FALSE; | |
423 bb->conversation->start_step_two = FALSE; | |
424 bb->conversation->stream_started = FALSE; | 430 bb->conversation->stream_started = FALSE; |
425 bb->conversation->buddy_name = g_strdup(gb->name); | 431 bb->conversation->buddy_name = g_strdup(gb->name); |
426 bb->conversation->message_id = 1; | 432 bb->conversation->message_id = 1; |
427 | 433 |
428 if (bb->conversation->stream_started == FALSE) { | 434 if (bb->conversation->stream_started == FALSE) { |
551 /* Check if there is a previously open conversation */ | 557 /* Check if there is a previously open conversation */ |
552 if (bb->conversation == NULL) | 558 if (bb->conversation == NULL) |
553 { | 559 { |
554 bb->conversation = g_new(BonjourJabberConversation, 1); | 560 bb->conversation = g_new(BonjourJabberConversation, 1); |
555 bb->conversation->socket = _connect_to_buddy(gb); | 561 bb->conversation->socket = _connect_to_buddy(gb); |
556 bb->conversation->start_step_one = FALSE; | |
557 bb->conversation->start_step_two = FALSE; | |
558 bb->conversation->stream_started = FALSE; | 562 bb->conversation->stream_started = FALSE; |
559 bb->conversation->buddy_name = g_strdup(gb->name); | 563 bb->conversation->buddy_name = g_strdup(gb->name); |
560 bb->conversation->watcher_id = gaim_input_add(bb->conversation->socket, | 564 bb->conversation->watcher_id = gaim_input_add(bb->conversation->socket, |
561 GAIM_INPUT_READ, _client_socket_handler, gb); | 565 GAIM_INPUT_READ, _client_socket_handler, gb); |
562 } | 566 } |
563 | 567 |
564 /* Check if the stream for the conversation has been started */ | 568 /* Check if the stream for the conversation has been started */ |
565 if (bb->conversation->stream_started == FALSE) | 569 if (bb->conversation->stream_started == FALSE) |
566 { | 570 { |