changeset 1353:7caedca15e50

Add post-connect internal hook
author Mikael Berthe <mikael@lilotux.net>
date Sat, 10 Nov 2007 23:06:28 +0100
parents 61a54e172010
children c373ff3fe7e1
files mcabber/mcabberrc.example mcabber/src/jab_iq.c
diffstat 2 files changed, 49 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/mcabberrc.example	Sat Nov 10 22:29:31 2007 +0100
+++ b/mcabber/mcabberrc.example	Sat Nov 10 23:06:28 2007 +0100
@@ -199,6 +199,14 @@
 # exit value is 2.
 #set eventcmd_checkstatus = 0
 
+# Internal hooks
+# You can ask mcabber to execute an internal command when a special event
+# occurs (for example when it connects to the server).
+#
+# 'hook-post-connect' is executed when mcabber has connected to the server
+# and the roster has been received.
+#set hook-post-connect = status dnd
+
 # Traces logging
 # If you want advanced traces, please specify a file and a level here.
 # There are currently 2 traceloglog levels:
--- a/mcabber/src/jab_iq.c	Sat Nov 10 22:29:31 2007 +0100
+++ b/mcabber/src/jab_iq.c	Sat Nov 10 23:06:28 2007 +0100
@@ -33,6 +33,7 @@
 #include "settings.h"
 #include "hbuf.h"
 #include "commands.h"
+#include "hooks.h"
 
 #ifdef ENABLE_HGCSET
 # include "hgcset.h"
@@ -246,13 +247,6 @@
   scr_LogPrint(LPRINT_LOGNORM, "End of IQ list.");
 }
 
-static void request_roster(void)
-{
-  eviqs *iqn = iqs_new(JPACKET__GET, NS_ROSTER, "Roster", IQS_DEFAULT_TIMEOUT);
-  jab_send(jc, iqn->xmldata);
-  iqs_del(iqn->id); // XXX
-}
-
 static void handle_iq_roster(xmlnode x)
 {
   xmlnode y;
@@ -327,6 +321,44 @@
     scr_UpdateBuddyWindow();
 }
 
+//  This callback is reached when mcabber receives the first roster update
+// after the connection.
+static int iqscallback_gotroster(eviqs *iqp, xmlnode xml_result, guint iqcontext)
+{
+  xmlnode x;
+  char *ns;
+
+  // Leave now if we cannot process xml_result
+  if (!xml_result || iqcontext) return -1;
+
+  // Only execute the hook if the roster has been successfully retrieved
+  if (iqcontext != IQS_CONTEXT_RESULT)
+    return 0;
+
+  x = xmlnode_get_tag(xml_result, "query");
+  if (!x)
+    return -1;
+  ns = xmlnode_get_attrib(x, "xmlns");
+  if (!ns)
+    return -1;
+
+  if (!strcmp(ns, NS_ROSTER))   // The check is probably useless...
+    handle_iq_roster(x);
+
+  // Post-login stuff
+  jb_setprevstatus();
+  hook_execute_internal("hook-post-connect");
+
+  return 0;
+}
+
+static void request_roster(void)
+{
+  eviqs *iqn = iqs_new(JPACKET__GET, NS_ROSTER, "Roster", IQS_DEFAULT_TIMEOUT);
+  iqn->callback = &iqscallback_gotroster;
+  jab_send(jc, iqn->xmldata);
+}
+
 static int iqscallback_version(eviqs *iqp, xmlnode xml_result, guint iqcontext)
 {
   xmlnode ansqry;
@@ -895,33 +927,14 @@
 
 static void handle_iq_result(jconn conn, char *from, xmlnode xmldata)
 {
-  xmlnode x;
-  char *id;
-  char *ns;
+  char *id = xmlnode_get_attrib(xmldata, "id");
 
-  id = xmlnode_get_attrib(xmldata, "id");
   if (!id) {
     scr_LogPrint(LPRINT_LOG, "IQ result stanza with no ID, ignored.");
     return;
   }
 
-  if (!iqs_callback(id, xmldata, IQS_CONTEXT_RESULT))
-    return;
-
-  x = xmlnode_get_tag(xmldata, "query");
-  if (!x) return;
-
-  ns = xmlnode_get_attrib(x, "xmlns");
-  if (!ns) return;
-
-  if (!strcmp(ns, NS_ROSTER)) {
-    handle_iq_roster(x);
-
-    // Post-login stuff
-    // Usually we request the roster only at connection time
-    // so we should be there only once.  (That's ugly, however)
-    jb_setprevstatus();
-  }
+  (void)iqs_callback(id, xmldata, IQS_CONTEXT_RESULT);
 }
 
 // FIXME  highly duplicated code