Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/presence.c @ 27447:712289e2aa6d
Rearrange all the MUC code to be together.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Mon, 06 Jul 2009 03:45:57 +0000 |
parents | 735e58197140 |
children | b41b69e8b341 |
comparison
equal
deleted
inserted
replaced
27446:735e58197140 | 27447:712289e2aa6d |
---|---|
458 | 458 |
459 void jabber_presence_parse(JabberStream *js, xmlnode *packet) | 459 void jabber_presence_parse(JabberStream *js, xmlnode *packet) |
460 { | 460 { |
461 const char *from; | 461 const char *from; |
462 const char *type; | 462 const char *type; |
463 const char *real_jid = NULL; | |
464 const char *affiliation = NULL; | |
465 const char *role = NULL; | |
466 char *status = NULL; | 463 char *status = NULL; |
467 int priority = 0; | 464 int priority = 0; |
468 JabberID *jid; | 465 JabberID *jid; |
469 JabberChat *chat; | 466 JabberChat *chat; |
470 JabberBuddy *jb; | 467 JabberBuddy *jb; |
474 const gchar *stamp = NULL; /* from <delayed/> element */ | 471 const gchar *stamp = NULL; /* from <delayed/> element */ |
475 PurpleBuddy *b = NULL; | 472 PurpleBuddy *b = NULL; |
476 char *buddy_name; | 473 char *buddy_name; |
477 JabberBuddyState state = JABBER_BUDDY_STATE_UNKNOWN; | 474 JabberBuddyState state = JABBER_BUDDY_STATE_UNKNOWN; |
478 xmlnode *y; | 475 xmlnode *y; |
479 gboolean muc = FALSE; | |
480 char *avatar_hash = NULL; | 476 char *avatar_hash = NULL; |
481 xmlnode *caps = NULL; | 477 xmlnode *caps = NULL; |
482 int idle = 0; | 478 int idle = 0; |
483 gchar *nickname = NULL; | 479 gchar *nickname = NULL; |
484 gboolean signal_return; | 480 gboolean signal_return; |
607 } else if(!strcmp(y->name, "x")) { | 603 } else if(!strcmp(y->name, "x")) { |
608 if(!strcmp(xmlns, "jabber:x:delay")) { | 604 if(!strcmp(xmlns, "jabber:x:delay")) { |
609 /* XXX: compare the time. jabber:x:delay can happen on presence packets that aren't really and truly delayed */ | 605 /* XXX: compare the time. jabber:x:delay can happen on presence packets that aren't really and truly delayed */ |
610 delayed = TRUE; | 606 delayed = TRUE; |
611 stamp = xmlnode_get_attrib(y, "stamp"); | 607 stamp = xmlnode_get_attrib(y, "stamp"); |
612 } else if(!strcmp(xmlns, "http://jabber.org/protocol/muc#user")) { | 608 } else if(!strcmp(xmlns, "vcard-temp:x:update")) { |
613 xmlnode *z; | 609 xmlnode *photo = xmlnode_get_child(y, "photo"); |
614 | 610 if(photo) { |
615 muc = TRUE; | 611 g_free(avatar_hash); |
616 if((z = xmlnode_get_child(y, "status"))) { | 612 avatar_hash = xmlnode_get_data(photo); |
617 const char *code = xmlnode_get_attrib(z, "code"); | 613 } |
614 } | |
615 } else if (!strcmp(y->name, "query") && | |
616 !strcmp(xmlnode_get_namespace(y), "jabber:iq:last")) { | |
617 /* resource has specified idle */ | |
618 const gchar *seconds = xmlnode_get_attrib(y, "seconds"); | |
619 if (seconds) { | |
620 /* we may need to take "delayed" into account here */ | |
621 idle = atoi(seconds); | |
622 } | |
623 } | |
624 } | |
625 | |
626 if (idle && delayed && stamp) { | |
627 /* if we have a delayed presence, we need to add the delay to the idle | |
628 value */ | |
629 time_t offset = time(NULL) - purple_str_to_time(stamp, TRUE, NULL, NULL, | |
630 NULL); | |
631 purple_debug_info("jabber", "got delay %s yielding %ld s offset\n", | |
632 stamp, offset); | |
633 idle += offset; | |
634 } | |
635 | |
636 if(jid->node && (chat = jabber_chat_find(js, jid->node, jid->domain))) { | |
637 static int i = 1; | |
638 | |
639 if(state == JABBER_BUDDY_STATE_ERROR) { | |
640 char *title, *msg = jabber_parse_error(js, packet, NULL); | |
641 | |
642 if (!chat->conv) { | |
643 title = g_strdup_printf(_("Error joining chat %s"), from); | |
644 purple_serv_got_join_chat_failed(js->gc, chat->components); | |
645 } else { | |
646 title = g_strdup_printf(_("Error in chat %s"), from); | |
647 if (g_hash_table_size(chat->members) == 0) | |
648 serv_got_chat_left(js->gc, chat->id); | |
649 } | |
650 purple_notify_error(js->gc, title, title, msg); | |
651 g_free(title); | |
652 g_free(msg); | |
653 | |
654 if (g_hash_table_size(chat->members) == 0) | |
655 /* Only destroy the chat if the error happened while joining */ | |
656 jabber_chat_destroy(chat); | |
657 jabber_id_free(jid); | |
658 g_free(status); | |
659 g_free(avatar_hash); | |
660 g_free(nickname); | |
661 return; | |
662 } | |
663 | |
664 if (type == NULL) { | |
665 xmlnode *x; | |
666 const char *real_jid = NULL; | |
667 const char *affiliation = NULL; | |
668 const char *role = NULL; | |
669 | |
670 /* | |
671 * XEP-0045 mandates the presence to include a resource (which is | |
672 * treated as the chat nick). Some non-compliant servers allow | |
673 * joining without a nick. | |
674 */ | |
675 if (!jid->resource) { | |
676 jabber_id_free(jid); | |
677 g_free(avatar_hash); | |
678 g_free(nickname); | |
679 g_free(status); | |
680 return; | |
681 } | |
682 | |
683 x = xmlnode_get_child_with_namespace(packet, "x", | |
684 "http://jabber.org/protocol/muc#user"); | |
685 if (x) { | |
686 xmlnode *status_node; | |
687 xmlnode *item_node; | |
688 | |
689 status_node = xmlnode_get_child(x, "status"); | |
690 if (status_node) { | |
691 const char *code = xmlnode_get_attrib(status_node, "code"); | |
618 if (purple_strequal(code, "201")) { | 692 if (purple_strequal(code, "201")) { |
619 if((chat = jabber_chat_find(js, jid->node, jid->domain))) { | 693 if ((chat = jabber_chat_find(js, jid->node, jid->domain))) { |
620 chat->config_dialog_type = PURPLE_REQUEST_ACTION; | 694 chat->config_dialog_type = PURPLE_REQUEST_ACTION; |
621 chat->config_dialog_handle = | 695 chat->config_dialog_handle = |
622 purple_request_action(js->gc, | 696 purple_request_action(js->gc, |
623 _("Create New Room"), | 697 _("Create New Room"), |
624 _("Create New Room"), | 698 _("Create New Room"), |
630 chat, 2, | 704 chat, 2, |
631 _("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure), | 705 _("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure), |
632 _("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room)); | 706 _("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room)); |
633 } | 707 } |
634 } else if (purple_strequal(code, "210")) { | 708 } else if (purple_strequal(code, "210")) { |
635 /* server rewrote room-nick */ | 709 /* server rewrote room-nick */ |
636 if((chat = jabber_chat_find(js, jid->node, jid->domain))) { | 710 if((chat = jabber_chat_find(js, jid->node, jid->domain))) { |
637 g_free(chat->handle); | 711 g_free(chat->handle); |
638 chat->handle = g_strdup(jid->resource); | 712 chat->handle = g_strdup(jid->resource); |
639 } | 713 } |
640 } | 714 } |
641 } | 715 } |
642 if((z = xmlnode_get_child(y, "item"))) { | 716 |
643 real_jid = xmlnode_get_attrib(z, "jid"); | 717 item_node = xmlnode_get_child(x, "item"); |
644 affiliation = xmlnode_get_attrib(z, "affiliation"); | 718 if (item_node) { |
645 role = xmlnode_get_attrib(z, "role"); | 719 real_jid = xmlnode_get_attrib(item_node, "jid"); |
646 if(affiliation != NULL && !strcmp(affiliation, "owner")) | 720 affiliation = xmlnode_get_attrib(item_node, "affiliation"); |
721 role = xmlnode_get_attrib(item_node, "role"); | |
722 | |
723 if (purple_strequal(affiliation, "owner")) | |
647 flags |= PURPLE_CBFLAGS_FOUNDER; | 724 flags |= PURPLE_CBFLAGS_FOUNDER; |
648 if (role != NULL) { | 725 if (role) { |
649 if (!strcmp(role, "moderator")) | 726 if (g_str_equal(role, "moderator")) |
650 flags |= PURPLE_CBFLAGS_OP; | 727 flags |= PURPLE_CBFLAGS_OP; |
651 else if (!strcmp(role, "participant")) | 728 else if (g_str_equal(role, "participant")) |
652 flags |= PURPLE_CBFLAGS_VOICE; | 729 flags |= PURPLE_CBFLAGS_VOICE; |
653 } | 730 } |
654 } | 731 } |
655 } else if(!strcmp(xmlns, "vcard-temp:x:update")) { | |
656 xmlnode *photo = xmlnode_get_child(y, "photo"); | |
657 if(photo) { | |
658 g_free(avatar_hash); | |
659 avatar_hash = xmlnode_get_data(photo); | |
660 } | |
661 } | |
662 } else if (!strcmp(y->name, "query") && | |
663 !strcmp(xmlnode_get_namespace(y), "jabber:iq:last")) { | |
664 /* resource has specified idle */ | |
665 const gchar *seconds = xmlnode_get_attrib(y, "seconds"); | |
666 if (seconds) { | |
667 /* we may need to take "delayed" into account here */ | |
668 idle = atoi(seconds); | |
669 } | |
670 } | |
671 } | |
672 | |
673 if (idle && delayed && stamp) { | |
674 /* if we have a delayed presence, we need to add the delay to the idle | |
675 value */ | |
676 time_t offset = time(NULL) - purple_str_to_time(stamp, TRUE, NULL, NULL, | |
677 NULL); | |
678 purple_debug_info("jabber", "got delay %s yielding %ld s offset\n", | |
679 stamp, offset); | |
680 idle += offset; | |
681 } | |
682 | |
683 if(jid->node && (chat = jabber_chat_find(js, jid->node, jid->domain))) { | |
684 static int i = 1; | |
685 | |
686 if(state == JABBER_BUDDY_STATE_ERROR) { | |
687 char *title, *msg = jabber_parse_error(js, packet, NULL); | |
688 | |
689 if (!chat->conv) { | |
690 title = g_strdup_printf(_("Error joining chat %s"), from); | |
691 purple_serv_got_join_chat_failed(js->gc, chat->components); | |
692 } else { | |
693 title = g_strdup_printf(_("Error in chat %s"), from); | |
694 if (g_hash_table_size(chat->members) == 0) | |
695 serv_got_chat_left(js->gc, chat->id); | |
696 } | |
697 purple_notify_error(js->gc, title, title, msg); | |
698 g_free(title); | |
699 g_free(msg); | |
700 | |
701 if (g_hash_table_size(chat->members) == 0) | |
702 /* Only destroy the chat if the error happened while joining */ | |
703 jabber_chat_destroy(chat); | |
704 jabber_id_free(jid); | |
705 g_free(status); | |
706 g_free(avatar_hash); | |
707 g_free(nickname); | |
708 return; | |
709 } | |
710 | |
711 if (type == NULL) { | |
712 /* | |
713 * XEP-0045 mandates the presence to include a resource (which is | |
714 * treated as the chat nick). Some non-compliant servers allow | |
715 * joining without a nick. | |
716 */ | |
717 if (!jid->resource) { | |
718 jabber_id_free(jid); | |
719 g_free(avatar_hash); | |
720 g_free(nickname); | |
721 g_free(status); | |
722 return; | |
723 } | 732 } |
724 | 733 |
725 if(!chat->conv) { | 734 if(!chat->conv) { |
726 char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain); | 735 char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain); |
727 chat->id = i++; | 736 chat->id = i++; |
728 chat->muc = muc; | 737 chat->muc = (x != NULL); |
729 chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid); | 738 chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid); |
730 purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle); | 739 purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle); |
731 | 740 |
732 jabber_chat_disco_traffic(chat); | 741 jabber_chat_disco_traffic(chat); |
733 g_free(room_jid); | 742 g_free(room_jid); |