changeset 572:afc2bd38b15c

Implement affiliations handling, add "/room whois"
author Mikael Berthe <mikael@lilotux.net>
date Sat, 03 Dec 2005 23:40:40 +0100
parents d63e6cbdc297
children 4df43fcdabc4
files mcabber/src/commands.c mcabber/src/hooks.c mcabber/src/jabglue.c mcabber/src/jabglue.h mcabber/src/roster.c mcabber/src/roster.h
diffstat 6 files changed, 152 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/commands.c	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/commands.c	Sat Dec 03 23:40:40 2005 +0100
@@ -167,6 +167,7 @@
   compl_add_category_word(COMPL_ROOM, "remove");
   compl_add_category_word(COMPL_ROOM, "topic");
   compl_add_category_word(COMPL_ROOM, "unlock");
+  compl_add_category_word(COMPL_ROOM, "whois");
 }
 
 //  expandalias(line)
@@ -1262,7 +1263,7 @@
     return;
   }
 
-  jb_room_kickban(roomid, jid, NULL, 2, arg);
+  jb_room_setaffil(roomid, jid, NULL, affil_outcast, arg);
 
   free_arg_lst(paramlst);
 }
@@ -1284,7 +1285,7 @@
     return;
   }
 
-  jb_room_kickban(roomid, NULL, nick, 1, arg);
+  jb_room_setaffil(roomid, NULL, nick, affil_none, arg);
 
   free_arg_lst(paramlst);
 }
@@ -1389,6 +1390,66 @@
   jb_room_unlock(buddy_getjid(bud));
 }
 
+static void room_whois(gpointer bud, char *arg)
+{
+  char **paramlst;
+  gchar *nick, *buffer;
+  const char *jid, *realjid;
+  const char *rst_msg;
+  enum imstatus rstatus;
+  enum imrole role;
+  enum imaffiliation affil;
+
+  char *strroles[] = { "none", "moderator", "participant", "visitor" };
+  char *straffil[] = { "none", "owner", "admin", "member", "outcast" };
+
+  paramlst = split_arg(arg, 1, 0); // nickname
+  nick = *paramlst;
+
+  if (!nick || !*nick) {
+    scr_LogPrint(LPRINT_NORMAL, "Missing parameter (nickname)");
+    free_arg_lst(paramlst);
+    return;
+  }
+
+  jid = buddy_getjid(bud);
+  rstatus = buddy_getstatus(bud, nick);
+
+  if (rstatus == offline) {
+    scr_LogPrint(LPRINT_NORMAL, "No such member: %s", nick);
+    free_arg_lst(paramlst);
+    return;
+  }
+
+  rst_msg = buddy_getstatusmsg(bud, nick);
+  if (!rst_msg) rst_msg = "";
+
+  role = buddy_getrole(bud, nick);
+  affil = buddy_getaffil(bud, nick);
+  realjid = buddy_getrjid(bud, nick);
+
+  buffer = g_new(char, 128);
+
+  snprintf(buffer, 127, "Whois [%s]", nick);
+  scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
+  snprintf(buffer, 127, "Status: [%c] %s", imstatus2char[rstatus],
+           rst_msg);
+  scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
+
+  if (realjid) {
+    snprintf(buffer, 127, "Real jid: <%s>", realjid);
+    scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
+  }
+
+  snprintf(buffer, 127, "Role: %s", strroles[role]);
+  scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
+  snprintf(buffer, 127, "Affiliation: %s", straffil[affil]);
+  scr_WriteIncomingMessage(jid, buffer, 0, HBB_PREFIX_INFO);
+
+  g_free(buffer);
+  free_arg_lst(paramlst);
+}
+
 static void do_room(char *arg)
 {
   char **paramlst;
@@ -1446,6 +1507,9 @@
   } else if (!strcasecmp(subcmd, "topic"))  {
     if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
       room_topic(bud, arg);
+  } else if (!strcasecmp(subcmd, "whois"))  {
+    if ((arg = check_room_subcommand(arg, TRUE, bud)) != NULL)
+      room_whois(bud, arg);
   } else {
     scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
   }
--- a/mcabber/src/hooks.c	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/hooks.c	Sat Dec 03 23:40:40 2005 +0100
@@ -213,7 +213,8 @@
     }
   }
 
-  roster_setstatus(jid, rn, prio, status, status_msg, role_none, NULL);
+  roster_setstatus(jid, rn, prio, status, status_msg, role_none, affil_none,
+                   NULL);
   buddylist_build();
   scr_DrawRoster();
   hlog_write_status(jid, 0, status, status_msg);
--- a/mcabber/src/jabglue.c	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/jabglue.c	Sat Dec 03 23:40:40 2005 +0100
@@ -588,16 +588,19 @@
 // room syntax: "room@server"
 // Either the jid or the nickname must be set (when banning, only the jid is
 // allowed)
-// kickban: 1=kick 2=ban
+// affil: new affiliation (ex. affil_none for kick, affil_outcast for ban...)
 // The reason can be null
 // Return 0 if everything is ok
-int jb_room_kickban(const char *roomid, const char *jid, const char *nick,
-                    int kickban, const char *reason)
+int jb_room_setaffil(const char *roomid, const char *jid, const char *nick,
+                     enum imaffiliation affil, const char *reason)
 {
   xmlnode x, y, z;
 
   if (!online || !roomid) return 1;
-  if (kickban != 1 && kickban != 2) return 1;
+
+  // Only none & outcast at the moment
+  if (affil != affil_none && affil != affil_outcast)
+    return 1;
 
   if (check_jid_syntax((char*)roomid)) {
     scr_LogPrint(LPRINT_NORMAL, "<%s> is not a valid Jabber id", roomid);
@@ -608,8 +611,8 @@
     return 1;
   }
 
-  if (kickban == 2 && !jid)
-    return 1; // Shouldn't happen
+  if (affil == affil_outcast && !jid)
+    return 1; // Shouldn't happen (jid mandatory when banning)
 
   x = jutil_iqnew(JPACKET__SET, "http://jabber.org/protocol/muc#admin");
   xmlnode_put_attrib(x, "id", "kick1"); // XXX
@@ -624,10 +627,10 @@
     g_free(utf8_nickname);
   } else {
     xmlnode_put_attrib(z, "jid", jid);
-    if (kickban == 2)
+    if (affil == affil_outcast)
       xmlnode_put_attrib(z, "affiliation", "outcast");
   }
-  if (kickban == 1)
+  if (affil == affil_none)
     xmlnode_put_attrib(z, "role", "none");
 
   if (reason) {
@@ -958,7 +961,7 @@
     if ((p = xmlnode_get_attrib(xmldata, "id")) != NULL) {
       int iid = atoi(p);
 
-      scr_LogPrint(LPRINT_DEBUG, "iid = %d", iid);
+      //scr_LogPrint(LPRINT_DEBUG, "iid = %d", iid);
       if (iid == s_id) {
         if (!regmode) {
           if (jstate == STATE_GETAUTH) {
@@ -1144,8 +1147,6 @@
                    from, p);
   }
 
-  // Call hk_statuschange() if status has changed or if the
-  // status message is different
   rname = strchr(from, '/');
   if (rname) rname++;
 
@@ -1160,6 +1161,7 @@
   }
   if (x) {    // This is a MUC presence message
     enum imrole mbrole = role_none;
+    enum imaffiliation mbaffil = affil_none;
     const char *mbrjid = NULL;
     const char *mbnewnick = NULL;
     GSList *room_elt;
@@ -1175,6 +1177,16 @@
     // Get room member's information
     y = xmlnode_get_tag(x, "item");
     if (y) {
+      p = xmlnode_get_attrib(y, "affiliation");
+      if (p) {
+        if (!strcmp(p, "owner"))        mbaffil = affil_owner;
+        else if (!strcmp(p, "admin"))   mbaffil = affil_admin;
+        else if (!strcmp(p, "member"))  mbaffil = affil_member;
+        else if (!strcmp(p, "outcast")) mbaffil = affil_outcast;
+        else if (!strcmp(p, "none"))    mbaffil = affil_none;
+        else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
+                          from, p);
+      }
       p = xmlnode_get_attrib(y, "role");
       if (p) {
         if (!strcmp(p, "moderator"))        mbrole = role_moderator;
@@ -1258,7 +1270,7 @@
 
     // Update room member status
     if (rname)
-      roster_setstatus(r, rname, bpprio, ust, s, mbrole, mbrjid);
+      roster_setstatus(r, rname, bpprio, ust, s, mbrole, mbaffil, mbrjid);
     else
       scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
 
@@ -1269,6 +1281,8 @@
   }
 
   // Not a MUC message, so this is a regular buddy...
+  // Call hk_statuschange() if status has changed or if the
+  // status message is different
   m = roster_getstatusmsg(r, rname);
   if ((ust != roster_getstatus(r, rname)) ||
       (!s && m && m[0]) || (s && (!m || strcmp(s, m))))
--- a/mcabber/src/jabglue.h	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/jabglue.h	Sat Dec 03 23:40:40 2005 +0100
@@ -3,6 +3,7 @@
 
 #include <glib.h>
 
+#include "roster.h"
 #include "../libjabber/jabber.h"
 
 #if HAVE_CONFIG_H
@@ -18,17 +19,6 @@
 extern char imstatus2char[];
 // Status chars: '_', 'o', 'i', 'f', 'd', 'n', 'a'
 
-enum imstatus {
-    offline,
-    available,
-    invisible,
-    freeforchat,
-    dontdisturb,
-    notavail,
-    away,
-    imstatus_size
-};
-
 enum agtype {
     unknown,
     groupchat,
@@ -58,7 +48,7 @@
 void jb_room_join(const char *room, const char *nickname);
 void jb_room_unlock(const char *room);
 void jb_room_invite(const char *room, const char *jid, const char *reason);
-int  jb_room_kickban(const char *roomid, const char *jid, const char *nick,
-                     int kickban, const char *reason);
+int  jb_room_setaffil(const char *roomid, const char *jid, const char *nick,
+                      enum imaffiliation, const char *reason);
 
 #endif /* __JABGLUE_H__ */
--- a/mcabber/src/roster.c	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/roster.c	Sat Dec 03 23:40:40 2005 +0100
@@ -33,6 +33,7 @@
   enum imstatus status;
   gchar *status_msg;
   enum imrole role;
+  enum imaffiliation affil;
   gchar *realjid;       /* for chatrooms, if buddy's real jid is known */
 } res;
 
@@ -372,10 +373,11 @@
 }
 
 //  roster_setstatus()
-// Note: resname, role and realjid are for room members only
+// Note: resname, role, affil and realjid are for room members only
 void roster_setstatus(const char *jid, const char *resname, gchar prio,
                       enum imstatus bstat, const char *status_msg,
-                      enum imrole role, const char *realjid)
+                      enum imrole role, enum imaffiliation affil,
+                      const char *realjid)
 {
   GSList *sl_user;
   roster *roster_usr;
@@ -410,6 +412,7 @@
     p_res->status_msg = g_strdup(status_msg);
 
   p_res->role = role;
+  p_res->affil = affil;
 
   if (p_res->realjid) {
     g_free((gchar*)p_res->realjid);
@@ -885,6 +888,33 @@
   return 0;
 }
 
+enum imrole buddy_getrole(gpointer rosterdata, const char *resname)
+{
+  roster *roster_usr = rosterdata;
+  res *p_res = get_resource(roster_usr, resname);
+  if (p_res)
+    return p_res->role;
+  return role_none;
+}
+
+enum imaffiliation buddy_getaffil(gpointer rosterdata, const char *resname)
+{
+  roster *roster_usr = rosterdata;
+  res *p_res = get_resource(roster_usr, resname);
+  if (p_res)
+    return p_res->affil;
+  return affil_none;
+}
+
+const char *buddy_getrjid(gpointer rosterdata, const char *resname)
+{
+  roster *roster_usr = rosterdata;
+  res *p_res = get_resource(roster_usr, resname);
+  if (p_res)
+    return p_res->realjid;
+  return NULL;
+}
+
 //  buddy_getresources(roster_data)
 // Return a singly-linked-list of resource names
 // Note: the caller should free the list (and data) after use
--- a/mcabber/src/roster.h	Sat Dec 03 14:25:34 2005 +0100
+++ b/mcabber/src/roster.h	Sat Dec 03 23:40:40 2005 +0100
@@ -3,7 +3,16 @@
 
 #include <glib.h>
 
-# include "jabglue.h"
+enum imstatus {
+    offline,
+    available,
+    invisible,
+    freeforchat,
+    dontdisturb,
+    notavail,
+    away,
+    imstatus_size
+};
 
 enum imrole {
   role_none,
@@ -12,6 +21,14 @@
   role_visitor
 };
 
+enum imaffiliation {
+  affil_none,
+  affil_owner,
+  affil_admin,
+  affil_member,
+  affil_outcast
+};
+
 enum subscr {
   sub_none,
   sub_to,
@@ -54,7 +71,8 @@
 void    roster_free(void);
 void    roster_setstatus(const char *jid, const char *resname, gchar prio,
                          enum imstatus bstat, const char *status_msg,
-                         enum imrole role, const char *realjid);
+                         enum imrole role, enum imaffiliation affil,
+                         const char *realjid);
 void    roster_setflags(const char *jid, guint flags, guint value);
 void    roster_msg_setflag(const char *jid, guint value);
 const char *roster_getname(const char *jid);
@@ -86,6 +104,9 @@
 GSList *buddy_getresources(gpointer rosterdata);
 void    buddy_resource_setname(gpointer rosterdata, const char *resname,
                                const char *newname);
+enum imrole buddy_getrole(gpointer rosterdata, const char *resname);
+enum imaffiliation buddy_getaffil(gpointer rosterdata, const char *resname);
+const char *buddy_getrjid(gpointer rosterdata, const char *resname);
 void    buddy_del_all_resources(gpointer rosterdata);
 void    buddy_setflags(gpointer rosterdata, guint flags, guint value);
 guint   buddy_getflags(gpointer rosterdata);