# HG changeset patch # User Mikael Berthe # Date 1194732388 -3600 # Node ID 7caedca15e507c4c0d3c624c75401dc156bfa2bc # Parent 61a54e172010993b36b65e8bab5526379700361b Add post-connect internal hook diff -r 61a54e172010 -r 7caedca15e50 mcabber/mcabberrc.example --- 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: diff -r 61a54e172010 -r 7caedca15e50 mcabber/src/jab_iq.c --- 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