# HG changeset patch # User Mikael Berthe # Date 1300103607 -3600 # Node ID 1a01a7ef4e433687c5092a11a65a2b07576bc98b # Parent aec86670047be565fc175f4b88a2c74bdd01d7ba Add support for XEP-0249 / Direct MUC Invitations (Myhailo Danylenko) Patch merged from isbear's mcabber-experimental repository. diff -r aec86670047b -r 1a01a7ef4e43 mcabber/mcabber/xmpp.c --- a/mcabber/mcabber/xmpp.c Mon Mar 14 12:50:18 2011 +0100 +++ b/mcabber/mcabber/xmpp.c Mon Mar 14 12:53:27 2011 +0100 @@ -1295,6 +1295,18 @@ x = lm_message_node_find_xmlns(m->node, NS_MUC_USER); if (x && !strcmp(x->name, "x")) got_muc_message(from, x); + + x = lm_message_node_find_xmlns(m->node, NS_X_CONFERENCE); + + if (x && !strcmp(x->name, "x")) { + const char *jid = lm_message_node_get_attribute(x, "jid"); + if (jid) { + const char *reason = lm_message_node_get_attribute(x, "reason"); + const char *password = lm_message_node_get_attribute(x, "password"); + // FIXME we shouldn't send decline stanzas in this case + got_invite(from, jid, reason, password, FALSE); + } + } } return LM_HANDLER_RESULT_REMOVE_MESSAGE; diff -r aec86670047b -r 1a01a7ef4e43 mcabber/mcabber/xmpp_defines.h --- a/mcabber/mcabber/xmpp_defines.h Mon Mar 14 12:50:18 2011 +0100 +++ b/mcabber/mcabber/xmpp_defines.h Mon Mar 14 12:53:27 2011 +0100 @@ -27,6 +27,8 @@ #define NS_BROWSE "jabber:iq:browse" #define NS_EVENT "jabber:x:event" #define NS_CONFERENCE "jabber:iq:conference" +// direct muc invitation (xep-0249) +#define NS_X_CONFERENCE "jabber:x:conference" #define NS_SIGNED "jabber:x:signed" #define NS_ENCRYPTED "jabber:x:encrypted" #define NS_GATEWAY "jabber:iq:gateway" diff -r aec86670047b -r 1a01a7ef4e43 mcabber/mcabber/xmpp_helper.c --- a/mcabber/mcabber/xmpp_helper.c Mon Mar 14 12:50:18 2011 +0100 +++ b/mcabber/mcabber/xmpp_helper.c Mon Mar 14 12:53:27 2011 +0100 @@ -234,6 +234,7 @@ caps_add_feature("", NS_PING); caps_add_feature("", NS_COMMANDS); caps_add_feature("", NS_RECEIPTS); + caps_add_feature("", NS_X_CONFERENCE); if (!settings_opt_get_int("iq_last_disable") && (!settings_opt_get_int("iq_last_disable_when_notavail") || status != notavail)) diff -r aec86670047b -r 1a01a7ef4e43 mcabber/mcabber/xmpp_muc.c --- a/mcabber/mcabber/xmpp_muc.c Mon Mar 14 12:50:18 2011 +0100 +++ b/mcabber/mcabber/xmpp_muc.c Mon Mar 14 12:53:27 2011 +0100 @@ -39,6 +39,8 @@ extern enum imstatus mystatus; extern gchar *mystatusmsg; +static GSList *invitations = NULL; + static void decline_invitation(event_muc_invitation *invitation, const char *reason) { // cut and paste from xmpp_room_invite @@ -65,10 +67,12 @@ void destroy_event_muc_invitation(event_muc_invitation *invitation) { + invitations = g_slist_remove(invitations, invitation); g_free(invitation->to); g_free(invitation->from); g_free(invitation->passwd); g_free(invitation->reason); + g_free(invitation->evid); g_free(invitation); } @@ -104,7 +108,8 @@ g_free(nickname); } else { scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to); - decline_invitation(invitation, arg); + if (invitation->reply) + decline_invitation(invitation, arg); } return FALSE; @@ -643,14 +648,12 @@ g_free(to); } -// got_invite(from, to, reason, passwd) +// got_invite(from, to, reason, passwd, reply) // This function should be called when receiving an invitation from user // "from", to enter the room "to". Optional reason and room password can // be provided. -// TODO: check for duplicate invites (need an existing invitation registry -// for that). -static void got_invite(const char* from, const char *to, const char* reason, - const char* passwd) +void got_invite(const char* from, const char *to, const char* reason, + const char* passwd, gboolean reply) { GString *sbuf; char *barejid; @@ -670,7 +673,21 @@ scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); - { + { // remove any equal older invites + GSList *iel = invitations; + while (iel) { + event_muc_invitation *invitation = iel->data; + iel = iel -> next; + if (!g_strcmp0(to, invitation->to) && + !g_strcmp0(passwd, invitation->passwd)) { + scr_LogPrint(LPRINT_DEBUG, "Destroying previous invitation event %s.", + invitation->evid); + evs_del(invitation->evid); + } + } + } + + { // create event const char *id; char *desc = g_strdup_printf("<%s> invites you to %s", from, to); event_muc_invitation *invitation; @@ -680,13 +697,18 @@ invitation->from = g_strdup(from); invitation->passwd = g_strdup(passwd); invitation->reason = g_strdup(reason); + invitation->reply = reply; + invitation->evid = NULL; + + invitations = g_slist_append(invitations, invitation); id = evs_new(desc, NULL, 0, evscallback_invitation, invitation, (GDestroyNotify)destroy_event_muc_invitation); g_free(desc); - if (id) + if (id) { + invitation->evid = g_strdup(id); g_string_printf(sbuf, "Please use /event %s accept|reject", id); - else + } else g_string_printf(sbuf, "Unable to create a new event!"); } scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); @@ -718,7 +740,7 @@ reason = lm_message_node_get_child_value(invite, "reason"); password = lm_message_node_get_child_value(invite, "password"); if (invite_from) - got_invite(invite_from, from, reason, password); + got_invite(invite_from, from, reason, password, TRUE); } // TODO // handle status code = 100 ( not anonymous ) diff -r aec86670047b -r 1a01a7ef4e43 mcabber/mcabber/xmpp_muc.h --- a/mcabber/mcabber/xmpp_muc.h Mon Mar 14 12:50:18 2011 +0100 +++ b/mcabber/mcabber/xmpp_muc.h Mon Mar 14 12:53:27 2011 +0100 @@ -6,10 +6,14 @@ char *from; char *passwd; char *reason; + char *evid; + gboolean reply; } event_muc_invitation; void destroy_event_muc_invitation(event_muc_invitation *invitation); void roompresence(gpointer room, void *presencedata); +void got_invite(const char* from, const char *to, const char* reason, + const char* passwd, gboolean reply); void got_muc_message(const char *from, LmMessageNode *x); void handle_muc_presence(const char *from, LmMessageNode * xmldata, const char *roomjid, const char *rname,