diff mcabber/src/jabglue.c @ 447:03bb57383cea

Initial Multi-User Chat support This patch adds basic MUC support. We now can: - join an existing room; - create and unlock a room using the /rawxml command; - set our nickname; - send/receive chatgroup messages; - see the members of the room; - leave the room. Chatroom logging is currently disabled, as it could do some unexpected things.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 25 Sep 2005 01:01:44 +0200
parents 5927c3bfba13
children e08b0c2d0e54
line wrap: on
line diff
--- a/mcabber/src/jabglue.c	Sun Sep 25 00:44:11 2005 +0200
+++ b/mcabber/src/jabglue.c	Sun Sep 25 01:01:44 2005 +0200
@@ -333,10 +333,17 @@
   mystatus = st;
 }
 
-void jb_send_msg(const char *jid, const char *text)
+void jb_send_msg(const char *jid, const char *text, int type)
 {
+  gchar *strtype;
   gchar *buffer = to_utf8(text);
-  xmlnode x = jutil_msgnew(TMSG_CHAT, (char*)jid, 0, (char*)buffer);
+
+  if (type == ROSTER_TYPE_ROOM)
+    strtype = TMSG_GROUPCHAT;
+  else
+    strtype = TMSG_CHAT;
+
+  xmlnode x = jutil_msgnew(strtype, (char*)jid, 0, (char*)buffer);
   jab_send(jc, x);
   xmlnode_free(x);
   g_free(buffer);
@@ -462,6 +469,26 @@
   g_free(cleanjid);
 }
 
+// Join a MUC room
+// room syntax: "room@server/nick"
+void jb_room_join(const char *room)
+{
+  xmlnode x, y;
+
+  if (!online) return;
+  if (!room)   return;
+
+  x = jutil_presnew(JPACKET__UNKNOWN, 0, 0);
+  xmlnode_put_attrib(x, "from", jid_full(jc->user));
+  xmlnode_put_attrib(x, "to", room);
+  y = xmlnode_insert_tag(x, "x");
+  xmlnode_put_attrib(y, "xmlns", "http://jabber.org/protocol/muc");
+
+  jab_send(jc, x);
+  xmlnode_free(x);
+  jb_reset_keepalive();
+}
+
 void postlogin()
 {
   //int i;
@@ -571,6 +598,7 @@
         const char *enc, time_t timestamp)
 {
   char *jid;
+  const char *rname;
   gchar *buffer = from_utf8(body);
 
   jid = jidtodisp(from);
@@ -585,18 +613,9 @@
     return;
   }
 
-  /*
-  //char *u, *h, *r;
-  //jidsplit(from, &u, &h, &r);
-  // Maybe we should remember the resource?
-  if (r)
-    scr_LogPrint(LPRINT_NORMAL,
-                 "There is an extra part in message (resource?): %s", r);
-  //scr_LogPrint(LPRINT_NORMAL, "Msg from <%s>, type=%s",
-  //             jidtodisp(from), type);
-  */
-
-  hk_message_in(jid, timestamp, buffer, type);
+  rname = strchr(from, '/');
+  if (rname) rname++;
+  hk_message_in(jid, rname, timestamp, buffer, type);
   g_free(jid);
   g_free(buffer);
 }
@@ -727,7 +746,7 @@
 
 void packethandler(jconn conn, jpacket packet)
 {
-  char *p, *r;
+  char *p, *r, *s;
   const char *m, *rname;
   xmlnode x, y;
   char *from=NULL, *type=NULL, *body=NULL, *enc=NULL;
@@ -906,7 +925,28 @@
 
             }
           }
+        } else if (!strcmp(type, "get")) {
+          p = xmlnode_get_attrib(packet->x, "id");
+          if (p) {
+            xmlnode z;
+
+            id = p;
+            x = xmlnode_new_tag("iq");
+            xmlnode_put_attrib(x, "type", "result");
+            xmlnode_put_attrib(x, "to", from);
+            xmlnode_put_attrib(x, "id", id);
+            xmlnode_put_attrib(x, "type", "error");
+            y = xmlnode_insert_tag(x, "error");
+            xmlnode_put_attrib(y, "code", "503");
+            xmlnode_put_attrib(y, "type", "cancel");
+            z = xmlnode_insert_tag(y, "feature-not-implemented");
+            xmlnode_put_attrib(z, "xmlns",
+                               "urn:ietf:params:xml:ns:xmpp-stanzas");
+            jab_send(conn, x);
+            xmlnode_free(x);
+          }
         } else if (!strcmp(type, "set")) {
+          /* FIXME: send error */
         } else if (!strcmp(type, "error")) {
           if ((x = xmlnode_get_tag(packet->x, "error")) != NULL)
             display_server_error(x);
@@ -940,19 +980,43 @@
           ust = offline;
 
         if ((x = xmlnode_get_tag(packet->x, "status")) != NULL)
-          p = from_utf8(xmlnode_get_data(x));
+          s = from_utf8(xmlnode_get_data(x));
         else
-          p = NULL;
+          s = NULL;
 
         // Call hk_statuschange() if status has changed or if the
         // status message is different
         rname = strchr(from, '/');
         if (rname) rname++;
+
+        // Check for MUC presence packet
+        // There can be multiple <x> tags!!
+        x = xmlnode_get_firstchild(packet->x);
+        for ( ; x; x = xmlnode_get_nextsibling(x)) {
+          if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
+            if ((p = xmlnode_get_attrib(x, "xmlns")) &&
+                !strncasecmp(p, "http://jabber.org/protocol/muc", 30))
+              break;
+        }
+        if (x) {    // This is a MUC presence message
+          roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM);
+
+          if (rname)
+            roster_setstatus(r, rname, bpprio, ust, NULL);
+          else
+            scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
+
+          buddylist_build();
+          scr_DrawRoster();
+          break;
+        }
+
+        // Not a MUC message, so this is a regular buddy...
         m = roster_getstatusmsg(r, rname);
-        if ((ust != roster_getstatus(r, rname)) || (p && (!m || strcmp(p, m))))
-          hk_statuschange(r, rname, bpprio, 0, ust, p);
+        if ((ust != roster_getstatus(r, rname)) || (s && (!m || strcmp(s, m))))
+          hk_statuschange(r, rname, bpprio, 0, ust, s);
         g_free(r);
-        if (p) g_free(p);
+        if (s) g_free(s);
         break;
 
     case JPACKET_S10N: