comparison libpurple/protocols/bonjour/jabber.c @ 17554:a1d05bc43d95

Send 'to' and 'from' attributes in the stream start message.
author Daniel Atallah <daniel.atallah@gmail.com>
date Fri, 08 Jun 2007 06:15:43 +0000
parents 61005dea822b
children b13850d13391
comparison
equal deleted inserted replaced
17553:61005dea822b 17554:a1d05bc43d95
42 42
43 #include "jabber.h" 43 #include "jabber.h"
44 #include "bonjour.h" 44 #include "bonjour.h"
45 #include "buddy.h" 45 #include "buddy.h"
46 46
47 #define STREAM_END "</stream:stream>"
48 /* TODO: specify version='1.0' and send stream features */
49 #define DOCTYPE "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \
50 "<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" from=\"%s\" to=\"%s\">"
51
47 static gint 52 static gint
48 _connect_to_buddy(PurpleBuddy *gb) 53 _connect_to_buddy(PurpleBuddy *gb)
49 { 54 {
50 gint socket_fd; 55 gint socket_fd;
51 struct sockaddr_in buddy_address; 56 struct sockaddr_in buddy_address;
209 g_free(html_body); 214 g_free(html_body);
210 } 215 }
211 216
212 struct _check_buddy_by_address_t { 217 struct _check_buddy_by_address_t {
213 const char *address; 218 const char *address;
214 PurpleBuddy **gb; 219 PurpleBuddy **pb;
215 BonjourJabber *bj; 220 BonjourJabber *bj;
216 }; 221 };
217 222
218 static void 223 static void
219 _check_buddy_by_address(gpointer key, gpointer value, gpointer data) 224 _check_buddy_by_address(gpointer key, gpointer value, gpointer data)
220 { 225 {
221 PurpleBuddy *gb = value; 226 PurpleBuddy *pb = value;
222 BonjourBuddy *bb; 227 BonjourBuddy *bb;
223 struct _check_buddy_by_address_t *cbba = data; 228 struct _check_buddy_by_address_t *cbba = data;
224 229
225 /* 230 /*
226 * If the current PurpleBuddy's data is not null and the PurpleBuddy's account 231 * If the current PurpleBuddy's data is not null and the PurpleBuddy's account
227 * is the same as the account requesting the check then continue to determine 232 * is the same as the account requesting the check then continue to determine
228 * whether the buddies IP matches the target IP. 233 * whether the buddies IP matches the target IP.
229 */ 234 */
230 if (cbba->bj->account == gb->account) 235 if (cbba->bj->account == pb->account)
231 { 236 {
232 bb = gb->proto_data; 237 bb = pb->proto_data;
233 if ((bb != NULL) && (g_ascii_strcasecmp(bb->ip, cbba->address) == 0)) 238 if ((bb != NULL) && (g_ascii_strcasecmp(bb->ip, cbba->address) == 0))
234 *(cbba->gb) = gb; 239 *(cbba->pb) = pb;
235 } 240 }
236 } 241 }
237 242
238 static gint 243 static gint
239 _read_data(gint socket, char **message) 244 _read_data(gint socket, char **message)
289 static void 294 static void
290 _client_socket_handler(gpointer data, gint socket, PurpleInputCondition condition) 295 _client_socket_handler(gpointer data, gint socket, PurpleInputCondition condition)
291 { 296 {
292 char *message = NULL; 297 char *message = NULL;
293 gint message_length; 298 gint message_length;
294 PurpleBuddy *gb = data; 299 PurpleBuddy *pb = data;
295 PurpleAccount *account = gb->account; 300 PurpleAccount *account = pb->account;
296 PurpleConversation *conversation; 301 PurpleConversation *conversation;
297 BonjourBuddy *bb = gb->proto_data; 302 BonjourBuddy *bb = pb->proto_data;
298 gboolean closed_conversation = FALSE; 303 gboolean closed_conversation = FALSE;
299 xmlnode *message_node; 304 xmlnode *message_node;
300 305
301 /* Read the data from the socket */ 306 /* Read the data from the socket */
302 if ((message_length = _read_data(socket, &message)) == -1) { 307 if ((message_length = _read_data(socket, &message)) == -1) {
328 { 333 {
329 bb->conversation->stream_started = TRUE; 334 bb->conversation->stream_started = TRUE;
330 } 335 }
331 else 336 else
332 { 337 {
338 char *stream_start = g_strdup_printf(DOCTYPE, purple_account_get_username(pb->account),
339 purple_buddy_get_name(pb));
340
333 /* TODO: This needs to be nonblocking! */ 341 /* TODO: This needs to be nonblocking! */
334 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) 342 if (send(bb->conversation->socket, stream_start, strlen(stream_start), 0) == -1)
335 purple_debug_error("bonjour", "Unable to start a conversation with %s\n", bb->name); 343 purple_debug_error("bonjour", "Unable to start a conversation with %s\n", bb->name);
336 else 344 else
337 bb->conversation->stream_started = TRUE; 345 bb->conversation->stream_started = TRUE;
346
347 g_free(stream_start);
338 } 348 }
339 } 349 }
340 350
341 /* 351 /*
342 * Check that this is not the end of the conversation. This is 352 * Check that this is not the end of the conversation. This is
354 g_free(bb->conversation); 364 g_free(bb->conversation);
355 bb->conversation = NULL; 365 bb->conversation = NULL;
356 } 366 }
357 367
358 /* Inform the user that the conversation has been closed */ 368 /* Inform the user that the conversation has been closed */
359 conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, gb->name, account); 369 conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pb->name, account);
360 closed_conv_message = g_strdup_printf(_("%s has closed the conversation."), gb->name); 370 closed_conv_message = g_strdup_printf(_("%s has closed the conversation."), pb->name);
361 purple_conversation_write(conversation, NULL, closed_conv_message, PURPLE_MESSAGE_SYSTEM, time(NULL)); 371 purple_conversation_write(conversation, NULL, closed_conv_message, PURPLE_MESSAGE_SYSTEM, time(NULL));
362 g_free(closed_conv_message); 372 g_free(closed_conv_message);
363 } else if (message_node != NULL) { 373 } else if (message_node != NULL) {
364 /* Parse the message to get the data and send to the ui */ 374 /* Parse the message to get the data and send to the ui */
365 _jabber_parse_and_write_message_to_ui(message_node, account->gc, gb); 375 _jabber_parse_and_write_message_to_ui(message_node, account->gc, pb);
366 } else { 376 } else {
367 /* TODO: Deal with receiving only a partial message */ 377 /* TODO: Deal with receiving only a partial message */
368 } 378 }
369 379
370 g_free(message); 380 g_free(message);
373 } 383 }
374 384
375 static void 385 static void
376 _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition condition) 386 _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition condition)
377 { 387 {
378 PurpleBuddy *gb = NULL; 388 PurpleBuddy *pb = NULL;
379 struct sockaddr_in their_addr; /* connector's address information */ 389 struct sockaddr_in their_addr; /* connector's address information */
380 socklen_t sin_size = sizeof(struct sockaddr); 390 socklen_t sin_size = sizeof(struct sockaddr);
381 int client_socket; 391 int client_socket;
382 BonjourBuddy *bb; 392 BonjourBuddy *bb;
383 char *address_text = NULL; 393 char *address_text = NULL;
395 405
396 /* Look for the buddy that has opened the conversation and fill information */ 406 /* Look for the buddy that has opened the conversation and fill information */
397 address_text = inet_ntoa(their_addr.sin_addr); 407 address_text = inet_ntoa(their_addr.sin_addr);
398 cbba = g_new0(struct _check_buddy_by_address_t, 1); 408 cbba = g_new0(struct _check_buddy_by_address_t, 1);
399 cbba->address = address_text; 409 cbba->address = address_text;
400 cbba->gb = &gb; 410 cbba->pb = &pb;
401 cbba->bj = data; 411 cbba->bj = data;
402 g_hash_table_foreach(bl->buddies, _check_buddy_by_address, cbba); 412 g_hash_table_foreach(bl->buddies, _check_buddy_by_address, cbba);
403 g_free(cbba); 413 g_free(cbba);
404 if (gb == NULL) 414 if (pb == NULL)
405 { 415 {
406 purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheros comic\n"); 416 purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheros comic\n");
407 close(client_socket); 417 close(client_socket);
408 return; 418 return;
409 } 419 }
410 bb = gb->proto_data; 420 bb = pb->proto_data;
411 421
412 /* Check if the conversation has been previously started */ 422 /* Check if the conversation has been previously started */
413 if (bb->conversation == NULL) 423 if (bb->conversation == NULL)
414 { 424 {
415 bb->conversation = g_new(BonjourJabberConversation, 1); 425 bb->conversation = g_new(BonjourJabberConversation, 1);
416 bb->conversation->socket = client_socket; 426 bb->conversation->socket = client_socket;
417 bb->conversation->stream_started = FALSE; 427 bb->conversation->stream_started = FALSE;
418 bb->conversation->buddy_name = g_strdup(gb->name); 428 bb->conversation->buddy_name = g_strdup(pb->name);
419 429
420 if (bb->conversation->stream_started == FALSE) { 430 if (bb->conversation->stream_started == FALSE) {
431 char *stream_start = g_strdup_printf(DOCTYPE, purple_account_get_username(pb->account),
432 purple_buddy_get_name(pb));
421 /* Start the stream */ 433 /* Start the stream */
422 send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0); 434 send(bb->conversation->socket, stream_start, strlen(stream_start), 0);
423 bb->conversation->stream_started = TRUE; 435 bb->conversation->stream_started = TRUE;
436 g_free(stream_start);
424 } 437 }
425 438
426 /* Open a watcher for the client socket */ 439 /* Open a watcher for the client socket */
427 bb->conversation->watcher_id = purple_input_add(client_socket, PURPLE_INPUT_READ, 440 bb->conversation->watcher_id = purple_input_add(client_socket, PURPLE_INPUT_READ,
428 _client_socket_handler, gb); 441 _client_socket_handler, pb);
429 } else { 442 } else {
430 close(client_socket); 443 close(client_socket);
431 } 444 }
432 } 445 }
433 446
565 xmlnode_free(message_node); 578 xmlnode_free(message_node);
566 579
567 /* Check if the stream for the conversation has been started */ 580 /* Check if the stream for the conversation has been started */
568 if (bb->conversation->stream_started == FALSE) 581 if (bb->conversation->stream_started == FALSE)
569 { 582 {
583 char *stream_start = g_strdup_printf(DOCTYPE, purple_account_get_username(pb->account),
584 purple_buddy_get_name(pb));
570 /* Start the stream */ 585 /* Start the stream */
571 if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) 586 if (send(bb->conversation->socket, stream_start, strlen(stream_start), 0) == -1)
572 { 587 {
573 PurpleConversation *conv; 588 PurpleConversation *conv;
574 589
575 purple_debug_error("bonjour", "Unable to start a conversation\n"); 590 purple_debug_error("bonjour", "Unable to start a conversation\n");
576 purple_debug_warning("bonjour", "send error: %s\n", strerror(errno)); 591 purple_debug_warning("bonjour", "send error: %s\n", strerror(errno));
584 /* Free all the data related to the conversation */ 599 /* Free all the data related to the conversation */
585 g_free(bb->conversation->buddy_name); 600 g_free(bb->conversation->buddy_name);
586 g_free(bb->conversation); 601 g_free(bb->conversation);
587 bb->conversation = NULL; 602 bb->conversation = NULL;
588 g_free(message); 603 g_free(message);
604 g_free(stream_start);
589 return 0; 605 return 0;
590 } 606 }
591 607
608 g_free(stream_start);
592 bb->conversation->stream_started = TRUE; 609 bb->conversation->stream_started = TRUE;
593 } 610 }
594 611
595 /* Send the message */ 612 /* Send the message */
596 ret = (_send_data(bb->conversation->socket, message) == -1); 613 ret = (_send_data(bb->conversation->socket, message) == -1);