comparison mcabber/mcabber/xmpp_muc.c @ 1951:1a01a7ef4e43

Add support for XEP-0249 / Direct MUC Invitations (Myhailo Danylenko) Patch merged from isbear's mcabber-experimental repository.
author Mikael Berthe <mikael@lilotux.net>
date Mon, 14 Mar 2011 12:53:27 +0100
parents 26e437e79e60
children 9f443617e96b
comparison
equal deleted inserted replaced
1950:aec86670047b 1951:1a01a7ef4e43
37 #include "histolog.h" 37 #include "histolog.h"
38 38
39 extern enum imstatus mystatus; 39 extern enum imstatus mystatus;
40 extern gchar *mystatusmsg; 40 extern gchar *mystatusmsg;
41 41
42 static GSList *invitations = NULL;
43
42 static void decline_invitation(event_muc_invitation *invitation, const char *reason) 44 static void decline_invitation(event_muc_invitation *invitation, const char *reason)
43 { 45 {
44 // cut and paste from xmpp_room_invite 46 // cut and paste from xmpp_room_invite
45 LmMessage *m; 47 LmMessage *m;
46 LmMessageNode *x, *y; 48 LmMessageNode *x, *y;
63 lm_message_unref(m); 65 lm_message_unref(m);
64 } 66 }
65 67
66 void destroy_event_muc_invitation(event_muc_invitation *invitation) 68 void destroy_event_muc_invitation(event_muc_invitation *invitation)
67 { 69 {
70 invitations = g_slist_remove(invitations, invitation);
68 g_free(invitation->to); 71 g_free(invitation->to);
69 g_free(invitation->from); 72 g_free(invitation->from);
70 g_free(invitation->passwd); 73 g_free(invitation->passwd);
71 g_free(invitation->reason); 74 g_free(invitation->reason);
75 g_free(invitation->evid);
72 g_free(invitation); 76 g_free(invitation);
73 } 77 }
74 78
75 // invitation event handler 79 // invitation event handler
76 // TODO: if event is accepted, check if other events to the same room exist and 80 // TODO: if event is accepted, check if other events to the same room exist and
102 char *nickname = default_muc_nickname(invitation->to); 106 char *nickname = default_muc_nickname(invitation->to);
103 xmpp_room_join(invitation->to, nickname, invitation->passwd); 107 xmpp_room_join(invitation->to, nickname, invitation->passwd);
104 g_free(nickname); 108 g_free(nickname);
105 } else { 109 } else {
106 scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to); 110 scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
107 decline_invitation(invitation, arg); 111 if (invitation->reply)
112 decline_invitation(invitation, arg);
108 } 113 }
109 114
110 return FALSE; 115 return FALSE;
111 } 116 }
112 117
641 to = g_strdup_printf("%s/%s", bjid, nickname); 646 to = g_strdup_printf("%s/%s", bjid, nickname);
642 xmpp_setstatus(pres->st, to, pres->msg, TRUE); 647 xmpp_setstatus(pres->st, to, pres->msg, TRUE);
643 g_free(to); 648 g_free(to);
644 } 649 }
645 650
646 // got_invite(from, to, reason, passwd) 651 // got_invite(from, to, reason, passwd, reply)
647 // This function should be called when receiving an invitation from user 652 // This function should be called when receiving an invitation from user
648 // "from", to enter the room "to". Optional reason and room password can 653 // "from", to enter the room "to". Optional reason and room password can
649 // be provided. 654 // be provided.
650 // TODO: check for duplicate invites (need an existing invitation registry 655 void got_invite(const char* from, const char *to, const char* reason,
651 // for that). 656 const char* passwd, gboolean reply)
652 static void got_invite(const char* from, const char *to, const char* reason,
653 const char* passwd)
654 { 657 {
655 GString *sbuf; 658 GString *sbuf;
656 char *barejid; 659 char *barejid;
657 GSList *room_elt; 660 GSList *room_elt;
658 661
668 671
669 barejid = jidtodisp(from); 672 barejid = jidtodisp(from);
670 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); 673 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
671 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); 674 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
672 675
673 { 676 { // remove any equal older invites
677 GSList *iel = invitations;
678 while (iel) {
679 event_muc_invitation *invitation = iel->data;
680 iel = iel -> next;
681 if (!g_strcmp0(to, invitation->to) &&
682 !g_strcmp0(passwd, invitation->passwd)) {
683 scr_LogPrint(LPRINT_DEBUG, "Destroying previous invitation event %s.",
684 invitation->evid);
685 evs_del(invitation->evid);
686 }
687 }
688 }
689
690 { // create event
674 const char *id; 691 const char *id;
675 char *desc = g_strdup_printf("<%s> invites you to %s", from, to); 692 char *desc = g_strdup_printf("<%s> invites you to %s", from, to);
676 event_muc_invitation *invitation; 693 event_muc_invitation *invitation;
677 694
678 invitation = g_new(event_muc_invitation, 1); 695 invitation = g_new(event_muc_invitation, 1);
679 invitation->to = g_strdup(to); 696 invitation->to = g_strdup(to);
680 invitation->from = g_strdup(from); 697 invitation->from = g_strdup(from);
681 invitation->passwd = g_strdup(passwd); 698 invitation->passwd = g_strdup(passwd);
682 invitation->reason = g_strdup(reason); 699 invitation->reason = g_strdup(reason);
700 invitation->reply = reply;
701 invitation->evid = NULL;
702
703 invitations = g_slist_append(invitations, invitation);
683 704
684 id = evs_new(desc, NULL, 0, evscallback_invitation, invitation, 705 id = evs_new(desc, NULL, 0, evscallback_invitation, invitation,
685 (GDestroyNotify)destroy_event_muc_invitation); 706 (GDestroyNotify)destroy_event_muc_invitation);
686 g_free(desc); 707 g_free(desc);
687 if (id) 708 if (id) {
709 invitation->evid = g_strdup(id);
688 g_string_printf(sbuf, "Please use /event %s accept|reject", id); 710 g_string_printf(sbuf, "Please use /event %s accept|reject", id);
689 else 711 } else
690 g_string_printf(sbuf, "Unable to create a new event!"); 712 g_string_printf(sbuf, "Unable to create a new event!");
691 } 713 }
692 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); 714 scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
693 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); 715 scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
694 g_string_free(sbuf, TRUE); 716 g_string_free(sbuf, TRUE);
716 738
717 invite_from = lm_message_node_get_attribute(invite, "from"); 739 invite_from = lm_message_node_get_attribute(invite, "from");
718 reason = lm_message_node_get_child_value(invite, "reason"); 740 reason = lm_message_node_get_child_value(invite, "reason");
719 password = lm_message_node_get_child_value(invite, "password"); 741 password = lm_message_node_get_child_value(invite, "password");
720 if (invite_from) 742 if (invite_from)
721 got_invite(invite_from, from, reason, password); 743 got_invite(invite_from, from, reason, password, TRUE);
722 } 744 }
723 // TODO 745 // TODO
724 // handle status code = 100 ( not anonymous ) 746 // handle status code = 100 ( not anonymous )
725 // handle status code = 170 ( changement de config ) 747 // handle status code = 170 ( changement de config )
726 // 10.2.1 Notification of Configuration Changes 748 // 10.2.1 Notification of Configuration Changes