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);