Mercurial > pidgin.yaz
comparison libpurple/protocols/bonjour/jabber.c @ 17792: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
17791:61005dea822b | 17792: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); |