changeset 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 aec86670047b
children 975f6f26b052
files mcabber/mcabber/xmpp.c mcabber/mcabber/xmpp_defines.h mcabber/mcabber/xmpp_helper.c mcabber/mcabber/xmpp_muc.c mcabber/mcabber/xmpp_muc.h
diffstat 5 files changed, 51 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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"
--- 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))
--- 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 )
--- 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,