changeset 745:413e95f3051a

Introduce user "events" list Not used yet. The events list (evs_list) will be used to queue events for user approval, for example subscription requests, file tranfers, etc. The evs stuff is actually almost the same as the iqs stuff, a lot of code is duplicated... :-\
author Mikael Berthe <mikael@lilotux.net>
date Mon, 13 Mar 2006 17:28:24 +0100
parents c3b76a1a07cb
children 3a76c2d73606
files mcabber/src/Makefile.am mcabber/src/events.c mcabber/src/events.h mcabber/src/jab_iq.c mcabber/src/jab_priv.h mcabber/src/jabglue.c
diffstat 6 files changed, 197 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/Makefile.am	Sat Mar 11 16:37:24 2006 +0100
+++ b/mcabber/src/Makefile.am	Mon Mar 13 17:28:24 2006 +0100
@@ -1,5 +1,5 @@
 bin_PROGRAMS = mcabber
-mcabber_SOURCES = main.c roster.c roster.h \
+mcabber_SOURCES = main.c roster.c roster.h events.c events.h \
 		  jabglue.c jabglue.h jab_iq.c jab_priv.h \
 		  commands.c commands.h compl.c compl.h \
 		  hbuf.c hbuf.h screen.c screen.h logprint.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/events.c	Mon Mar 13 17:28:24 2006 +0100
@@ -0,0 +1,142 @@
+/*
+ * events.c     -- Events fonctions
+ *
+ * Copyright (C) 2006 Mikael Berthe <bmikael@lists.lilotux.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <glib.h>
+#include "events.h"
+#include "logprint.h"
+
+static GSList *evs_list; // Events list
+
+
+//  evs_new(type, timeout)
+// Create an events structure.
+eviqs *evs_new(guint8 type, time_t timeout)
+{
+  static guint evs_idn;
+  eviqs *new_evs;
+  time_t now_t;
+
+  if (!++evs_idn)
+    evs_idn = 1;
+  /* TODO: check for wrapping, we shouldn't reuse ids */
+
+  new_evs = g_new0(eviqs, 1);
+  time(&now_t);
+  new_evs->ts_create = now_t;
+  if (timeout)
+    new_evs->ts_expire = now_t + timeout;
+  new_evs->type = type;
+  new_evs->id = g_strdup_printf("%d", evs_idn);
+
+  evs_list = g_slist_append(evs_list, new_evs);
+  return new_evs;
+}
+
+int evs_del(const char *evid)
+{
+  GSList *p;
+  eviqs *i;
+
+  if (!evid) return 1;
+
+  for (p = evs_list; p; p = g_slist_next(p)) {
+    i = p->data;
+    if (!strcmp(evid, i->id))
+      break;
+  }
+  if (p) {
+    g_free(i->id);
+    if (i->xmldata) xmlnode_free(i->xmldata);
+    // XXX Should we free i->data?
+    g_free(i);
+    evs_list = g_slist_remove(evs_list, p->data);
+    return 0; // Ok, deleted
+  }
+  return -1;  // Not found
+}
+
+static eviqs *evs_find(const char *evid)
+{
+  GSList *p;
+  eviqs *i;
+
+  if (!evid) return NULL;
+
+  for (p = evs_list; p; p = g_slist_next(p)) {
+    i = p->data;
+    if (!strcmp(evid, i->id))
+      return i;
+  }
+  return NULL;
+}
+
+//  evs_callback(evid, evcontext)
+// Callback processing for the specified event.
+// Return 0 in case of success, -1 if the evid hasn't been found.
+int evs_callback(const char *evid, guint evcontext)
+{
+  eviqs *i;
+
+  i = evs_find(evid);
+  if (!i) return -1;
+
+  // IQ processing
+  // Note: If xml_result is NULL, this is a timeout
+  if (i->callback)
+    (*i->callback)(i, evcontext);
+
+  evs_del(evid);
+  return 0;
+}
+
+void evs_check_timeout(time_t now_t)
+{
+  GSList *p;
+  eviqs *i;
+
+  p = evs_list;
+  while (p) {
+    i = p->data;
+    // We must get next IQ eviqs element now because the current one
+    // could be freed.
+    p = g_slist_next(p);
+
+    if ((!i->ts_expire && now_t > i->ts_create + EVS_MAX_TIMEOUT) ||
+        (i->ts_expire && now_t > i->ts_expire)) {
+      evs_callback(i->id, EVS_CONTEXT_TIMEOUT);
+    }
+  }
+}
+
+void evs_display_list(void)
+{
+  GSList *p;
+  eviqs *i;
+
+  scr_LogPrint(LPRINT_LOGNORM, "Events list:");
+  for (p = evs_list; p; p = g_slist_next(p)) {
+    i = p->data;
+    scr_LogPrint(LPRINT_LOGNORM, "Id: %s", i->id);
+  }
+  scr_LogPrint(LPRINT_LOGNORM, "End of events list.");
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/events.h	Mon Mar 13 17:28:24 2006 +0100
@@ -0,0 +1,27 @@
+#ifndef __EVENTS_H__
+#define __EVENTS_H__ 1
+
+#include "jabglue.h"
+
+
+#define EVS_DEFAULT_TIMEOUT 90
+#define EVS_MAX_TIMEOUT     600
+
+#define EVS_CONTEXT_USER    0
+#define EVS_CONTEXT_TIMEOUT 1
+
+/* Common structure for events (evs) and IQ requests (iqs) */
+typedef struct {
+  char *id;
+  time_t ts_create;
+  time_t ts_expire;
+  guint8 type;
+  gpointer data;
+  void (*callback)();
+  xmlnode xmldata;
+} eviqs;
+
+
+#endif /* __EVENTS_H__ */
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/jab_iq.c	Sat Mar 11 16:37:24 2006 +0100
+++ b/mcabber/src/jab_iq.c	Mon Mar 13 17:28:24 2006 +0100
@@ -40,15 +40,15 @@
 //  iqs_new(type, namespace, prefix, timeout)
 // Create a query (GET, SET) IQ structure.  This function should not be used
 // for RESULT packets.
-iqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout)
+eviqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout)
 {
   static guint iqs_idn;
-  iqs *new_iqs;
+  eviqs *new_iqs;
   time_t now_t;
 
   iqs_idn++;
 
-  new_iqs = g_new0(iqs, 1);
+  new_iqs = g_new0(eviqs, 1);
   time(&now_t);
   new_iqs->ts_create = now_t;
   if (timeout)
@@ -68,7 +68,7 @@
 int iqs_del(const char *iqid)
 {
   GSList *p;
-  iqs *i;
+  eviqs *i;
 
   if (!iqid) return 1;
 
@@ -88,10 +88,10 @@
   return -1;  // Not found
 }
 
-static iqs *iqs_find(const char *iqid)
+static eviqs *iqs_find(const char *iqid)
 {
   GSList *p;
-  iqs *i;
+  eviqs *i;
 
   if (!iqid) return NULL;
 
@@ -110,7 +110,7 @@
 // Return 0 in case of success, -1 if the iqid hasn't been found.
 int iqs_callback(const char *iqid, xmlnode xml_result, guint iqcontext)
 {
-  iqs *i;
+  eviqs *i;
 
   i = iqs_find(iqid);
   if (!i) return -1;
@@ -127,12 +127,12 @@
 void iqs_check_timeout(time_t now_t)
 {
   GSList *p;
-  iqs *i;
+  eviqs *i;
 
   p = iqs_list;
   while (p) {
     i = p->data;
-    // We must get next iqs element now because the current one
+    // We must get next IQ eviqs element now because the current one
     // could be freed.
     p = g_slist_next(p);
 
@@ -146,7 +146,7 @@
 void jb_iqs_display_list(void)
 {
   GSList *p;
-  iqs *i;
+  eviqs *i;
 
   scr_LogPrint(LPRINT_LOGNORM, "IQ list:");
   for (p = iqs_list; p; p = g_slist_next(p)) {
@@ -158,7 +158,7 @@
 
 static void request_roster(void)
 {
-  iqs *iqn = iqs_new(JPACKET__GET, NS_ROSTER, "Roster", IQS_DEFAULT_TIMEOUT);
+  eviqs *iqn = iqs_new(JPACKET__GET, NS_ROSTER, "Roster", IQS_DEFAULT_TIMEOUT);
   jab_send(jc, iqn->xmldata);
   iqs_del(iqn->id); // XXX
 }
@@ -244,7 +244,7 @@
     scr_ShowBuddyWindow();
 }
 
-void iqscallback_version(iqs *iqp, xmlnode xml_result, guint iqcontext)
+void iqscallback_version(eviqs *iqp, xmlnode xml_result, guint iqcontext)
 {
   xmlnode ansqry;
   char *p, *p_noutf8;
@@ -318,7 +318,7 @@
 
 void request_version(const char *fulljid)
 {
-  iqs *iqn;
+  eviqs *iqn;
   gchar *utf8_jid = to_utf8(fulljid);
 
   iqn = iqs_new(JPACKET__GET, NS_VERSION, "version", IQS_DEFAULT_TIMEOUT);
@@ -328,7 +328,7 @@
   jab_send(jc, iqn->xmldata);
 }
 
-void iqscallback_time(iqs *iqp, xmlnode xml_result, guint iqcontext)
+void iqscallback_time(eviqs *iqp, xmlnode xml_result, guint iqcontext)
 {
   xmlnode ansqry;
   char *p, *p_noutf8;
@@ -402,7 +402,7 @@
 
 void request_time(const char *fulljid)
 {
-  iqs *iqn;
+  eviqs *iqn;
   gchar *utf8_jid = to_utf8(fulljid);
 
   iqn = iqs_new(JPACKET__GET, NS_TIME, "time", IQS_DEFAULT_TIMEOUT);
@@ -412,10 +412,10 @@
   jab_send(jc, iqn->xmldata);
 }
 
-void iqscallback_auth(iqs *iqp, xmlnode xml_result)
+void iqscallback_auth(eviqs *iqp, xmlnode xml_result)
 {
   if (jstate == STATE_GETAUTH) {
-    iqs *iqn;
+    eviqs *iqn;
 
     if (xml_result) {
       xmlnode x = xmlnode_get_tag(xml_result, "query");
--- a/mcabber/src/jab_priv.h	Sat Mar 11 16:37:24 2006 +0100
+++ b/mcabber/src/jab_priv.h	Mon Mar 13 17:28:24 2006 +0100
@@ -4,6 +4,7 @@
 /* This header file declares functions used by jab*.c only. */
 
 #include "jabglue.h"
+#include "events.h"
 
 #define JABBER_AGENT_GROUP "Jabber Agents"
 
@@ -27,29 +28,17 @@
 #define IQS_CONTEXT_TIMEOUT 1
 #define IQS_CONTEXT_ERROR   2
 
-
-typedef struct {
-  char *id;
-  time_t ts_create;
-  time_t ts_expire;
-  guint8 type;
-  gpointer data;
-  void (*callback)();
-  xmlnode xmldata;
-} iqs;
-
-
 extern enum enum_jstate jstate;
 
 
 char *jidtodisp(const char *jid);
 void handle_packet_iq(jconn conn, char *type, char *from, xmlnode xmldata);
 void display_server_error(xmlnode x);
-iqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout);
+eviqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout);
 int  iqs_del(const char *iqid);
 int  iqs_callback(const char *iqid, xmlnode xml_result, guint iqcontext);
 void iqs_check_timeout(time_t now_t);
-void iqscallback_auth(iqs *iqp, xmlnode xml_result);
+void iqscallback_auth(eviqs *iqp, xmlnode xml_result);
 void request_version(const char *fulljid);
 void request_time(const char *fulljid);
 
--- a/mcabber/src/jabglue.c	Sat Mar 11 16:37:24 2006 +0100
+++ b/mcabber/src/jabglue.c	Mon Mar 13 17:28:24 2006 +0100
@@ -188,7 +188,7 @@
 
   if (jstate == STATE_CONNECTING) {
     if (jc) {
-      iqs *iqn;
+      eviqs *iqn;
       xmlnode z;
 
       iqn = iqs_new(JPACKET__GET, NS_AUTH, "auth", IQS_DEFAULT_TIMEOUT);
@@ -465,7 +465,7 @@
 void jb_addbuddy(const char *jid, const char *name, const char *group)
 {
   xmlnode y, z;
-  iqs *iqn;
+  eviqs *iqn;
   char *cleanjid;
 
   if (!online) return;
@@ -508,7 +508,7 @@
 void jb_delbuddy(const char *jid)
 {
   xmlnode x, y, z;
-  iqs *iqn;
+  eviqs *iqn;
   char *cleanjid;
 
   if (!online) return;
@@ -554,7 +554,7 @@
 void jb_updatebuddy(const char *jid, const char *name, const char *group)
 {
   xmlnode y;
-  iqs *iqn;
+  eviqs *iqn;
   char *cleanjid;
   gchar *name_utf8;
 
@@ -674,7 +674,7 @@
 void jb_room_unlock(const char *room)
 {
   xmlnode y, z;
-  iqs *iqn;
+  eviqs *iqn;
 
   if (!online || !room) return;
 
@@ -696,7 +696,7 @@
 void jb_room_destroy(const char *room, const char *venue, const char *reason)
 {
   xmlnode y, z;
-  iqs *iqn;
+  eviqs *iqn;
 
   if (!online || !room) return;
 
@@ -733,7 +733,7 @@
                       struct role_affil ra, const char *reason)
 {
   xmlnode y, z;
-  iqs *iqn;
+  eviqs *iqn;
 
   if (!online || !roomid) return 1;
   if (!jid && !nick) return 1;