Improved events interface
* User can pass additional arguments to event handler
* MUC invitation reject now can be supplied a reason
--- a/mcabber/doc/help/en/hlp_event.txt Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/doc/help/en/hlp_event.txt Tue Feb 02 22:44:18 2010 +0100
@@ -1,15 +1,16 @@
- /EVENT #N|* accept|ignore|reject
+ /EVENT #N|* accept|ignore|reject [event-specific arguments]
/EVENT list
Tell mcabber what to do about pending events.
If the first parameter is '*', the command will apply to all queued events.
+Event-specific arguments will be interpreted on event-to event basis. The only built-in case, when argument is used is MUC invitation reject - argument, if present, will be interpreted as reject reason.
-/event #N|* accept
+/event #N|* accept [event-specific arguments]
Event number #N/All events will be accepted
-/event #N|* ignore
+/event #N|* ignore [event-specific arguments]
Event number #N/All events will be ignored
-/event #N|* reject
+/event #N|* reject [event-specific arguments]
Event number #N/All events will be rejected
/event list
List all pending events
--- a/mcabber/doc/help/ru/hlp_event.txt Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/doc/help/ru/hlp_event.txt Tue Feb 02 22:44:18 2010 +0100
@@ -1,15 +1,16 @@
- /EVENT #N|* accept|ignore|reject
+ /EVENT #N|* accept|ignore|reject [дополнительные аргументы]
/EVENT list
Говорит mcabber`у что делать с событиями.
Если первый параметр '*', команда будет применена ко всей очереди событий.
+Дополнительные аргументы используются в зависимости от типа события. Из встроенных событий единственный случай, когда они используются - это отклонение приглашения в чат, если есть дополнительный аргумент, он будет использован в качестве сообщения о причине отказа.
-/event #N|* accept
+/event #N|* accept [дополнительные аргументы]
Событие номер #N/All будет разрешено
-/event #N|* ignore
+/event #N|* ignore [дополнительные аргументы]
Событие номер #N/All будет проигнорировано
-/event #N|* reject
+/event #N|* reject [дополнительные аргументы]
Событие номер #N/All будет отклонено
/event list
Показать список всех событий
--- a/mcabber/doc/help/uk/hlp_event.txt Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/doc/help/uk/hlp_event.txt Tue Feb 02 22:44:18 2010 +0100
@@ -1,15 +1,16 @@
- /EVENT #N|* accept|ignore|reject
+ /EVENT #N|* accept|ignore|reject [додаткові аргументи]
/EVENT list
Розібратися з подіями, що трапилися (запити на авторизацію ітп).
Якщо перший параметр - зірочка (*), відповідь буде застосована до всіх подій.
+Значення додаткового аргументу залежить від типу події. Єдиний випадок використання додаткового аргументу вбудованими подіями - відмова увійти у багатокористувацької розмови, якщо аргумент вказано, його буде надіслано, як причину відмови.
-/event N|* accept
+/event N|* accept [додаткові аргументи]
Подія номер #N отримає позитивну відповідь.
-/event N|* ignore
+/event N|* ignore [додаткові аргументи]
Не відповідати на подію номер N.
-/event N|* reject
+/event N|* reject [додаткові аргументи]
Подія номер N отримає негативну відповідь.
/event list
Друкує перелік подій.
--- a/mcabber/mcabber/commands.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/commands.c Tue Feb 02 22:44:18 2010 +0100
@@ -3305,9 +3305,8 @@
char **paramlst;
char *evid, *subcmd;
int action = -1;
- GSList *evidlst;
-
- paramlst = split_arg(arg, 2, 0); // id, subcmd
+
+ paramlst = split_arg(arg, 3, 1); // id, subcmd, optional arg
evid = *paramlst;
subcmd = *(paramlst+1);
@@ -3317,41 +3316,37 @@
evs_display_list();
else
scr_LogPrint(LPRINT_NORMAL,
- "Missing parameter. Usage: /event num action");
+ "Missing parameter. Usage: /event num action "
+ "[event-specific args]");
free_arg_lst(paramlst);
return;
}
if (!strcasecmp(subcmd, "reject"))
- action = 0;
+ action = EVS_CONTEXT_REJECT;
else if (!strcasecmp(subcmd, "accept"))
- action = 1;
+ action = EVS_CONTEXT_ACCEPT;
else if (!strcasecmp(subcmd, "ignore"))
- action = 2;
+ action = EVS_CONTEXT_CANCEL;
if (action == -1) {
scr_LogPrint(LPRINT_NORMAL, "Wrong action parameter.");
- } else if (action >= 0 && action <= 2) {
+ } else {
GSList *p;
-
- if (action == 2) {
- action = EVS_CONTEXT_CANCEL;
- } else {
- action += EVS_CONTEXT_USER;
- }
+ GSList *evidlst;
if (!strcmp(evid, "*")) {
// Use completion list
- evidlst = evs_geteventslist(FALSE);
+ evidlst = evs_geteventslist();
} else {
// Let's create a slist with the provided event id
- evidlst = g_slist_append(NULL, g_strdup(evid));
+ evidlst = g_slist_append(NULL, evid);
}
for (p = evidlst; p; p = g_slist_next(p)) {
- if (evs_callback(p->data, action) == -1) {
+ if (evs_callback(p->data, action,
+ (const char*)(paramlst+2)) == -1) {
scr_LogPrint(LPRINT_NORMAL, "Event %s not found.", p->data);
}
- g_free(p->data);
}
g_slist_free(evidlst);
}
--- a/mcabber/mcabber/compl.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/compl.c Tue Feb 02 22:44:18 2010 +0100
@@ -276,7 +276,12 @@
return buddy_getresources_locale(NULL);
}
if (cat_flags == COMPL_EVENTSID) {
- return evs_geteventslist(TRUE);
+ GSList *compl = evs_geteventslist();
+ GSList *cel;
+ for (cel = compl; cel; cel = cel->next)
+ cel->data = g_strdup(cel->data);
+ compl = g_slist_append(compl, g_strdup("list"));
+ return compl;
}
*dynlist = FALSE;
--- a/mcabber/mcabber/events.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/events.c Tue Feb 02 22:44:18 2010 +0100
@@ -2,6 +2,7 @@
* events.c -- Events fonctions
*
* Copyright (C) 2006-2009 Mikael Berthe <mikael@lilotux.net>
+ * Copyrigth (C) 2010 Myhailo Danylenko <isbear@ukrposte.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
@@ -24,157 +25,191 @@
#include "events.h"
#include "logprint.h"
+typedef struct {
+ char *id;
+ char *description;
+ time_t timeout;
+ guint source;
+ evs_callback_t callback;
+ gpointer data;
+ GDestroyNotify notify;
+} evs_t;
+
static GSList *evs_list; // Events list
-static eviqs *evs_find(const char *evid);
+static evs_t *evs_find(const char *evid);
+
+static gboolean evs_check_timeout (gpointer userdata)
+{
+ evs_t *event = userdata;
+ if (event->callback &&
+ !event->callback(EVS_CONTEXT_TIMEOUT, NULL, event->data)) {
+ evs_del(event->id);
+ return FALSE;
+ }
+ return TRUE; // XXX
+}
// evs_new(type, timeout)
-// Create an events structure.
-eviqs *evs_new(guint8 type, time_t timeout)
+// Create new event. If id is omitted, generates unique
+// numerical id (recommended). If timeout is specified, sets
+// up timeout source, that will call handler in timeout
+// context after specified number of seconds. If supplied id
+// already exists, returns NULL, calling destroy notifier, if
+// one is specified.
+const char *evs_new(const char *desc, const char *id, time_t timeout, evs_callback_t callback, gpointer udata, GDestroyNotify notify)
{
static guint evs_idn;
- eviqs *new_evs;
- time_t now_t;
+ evs_t *event;
char *stridn;
- if (!++evs_idn)
- evs_idn = 1;
- /* Check for wrapping, we shouldn't reuse ids */
- stridn = g_strdup_printf("%d", evs_idn);
- if (evs_find(stridn)) {
- g_free(stridn);
- // We could try another id but for now giving up should be fine...
+ if (!id) {
+ if (!++evs_idn)
+ evs_idn = 1;
+ /* Check for wrapping, we shouldn't reuse ids */
+ stridn = g_strdup_printf("%d", evs_idn);
+ if (evs_find(stridn)) {
+ g_free(stridn);
+ // We could try another id but for now giving up should be fine...
+ if (notify)
+ notify(udata);
+ return NULL;
+ }
+ } else if (!evs_find(id))
+ stridn = g_strdup(id);
+ else {
+ if (notify)
+ notify(udata);
return NULL;
}
- new_evs = g_new0(eviqs, 1);
- time(&now_t);
- new_evs->ts_create = now_t;
+ event = g_new(evs_t, 1);
+
+ event->id = stridn;
+ event->description = g_strdup(desc);
+ event->timeout = timeout;
+ event->callback = callback;
+ event->data = udata;
+ event->notify = notify;
+
if (timeout)
- new_evs->ts_expire = now_t + timeout;
- new_evs->type = type;
- new_evs->id = stridn;
+ g_timeout_add_seconds(timeout, evs_check_timeout, event);
- if(!g_slist_length(evs_list))
- g_timeout_add_seconds(20, evs_check_timeout, NULL);
- evs_list = g_slist_append(evs_list, new_evs);
- return new_evs;
+ evs_list = g_slist_append(evs_list, event);
+ return stridn;
}
-int evs_del(const char *evid)
+static evs_t *evs_find(const char *evid)
{
GSList *p;
- eviqs *i;
- if (!evid) return 1;
+ if (!evid)
+ return NULL;
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);
- g_free(i->data);
- g_free(i->desc);
- 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;
+ evs_t *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)
+// evs_del(evid)
+// Deletes event.
+// This will not call event handler, however this will
+// call destroy notify function.
+// Returns 0 in case of success, -1 if the evid hasn't been found.
+int evs_del(const char *evid)
{
- eviqs *i;
+ evs_t *event = evs_find(evid);
+
+ if (!event)
+ return -1;
+
+ if (event->notify)
+ event->notify(event->data);
+ if (event->source)
+ g_source_remove(event->source);
- i = evs_find(evid);
- if (!i) return -1;
+ evs_list = g_slist_remove(evs_list, event);
+ g_free(event->id);
+ g_free(event->description);
+ g_free(event);
+
+ return 0; // Ok, deleted
+}
- // IQ processing
- // Note: If xml_result is NULL, this is a timeout
- if (i->callback)
- (void)(*i->callback)(i, evcontext);
+// evs_callback(evid, evcontext, argument)
+// Callback processing for the specified event.
+// If event handler will return FALSE, event will be destroyed.
+// Return 0 in case of success, -1 if the evid hasn't been found.
+// evcontext and argument are transparently passed to event handler.
+int evs_callback(const char *evid, guint context, const char *arg)
+{
+ evs_t *event;
- evs_del(evid);
+ event = evs_find(evid);
+ if (!event)
+ return -1;
+
+ if (event->callback &&
+ !event->callback(context, arg, event->data))
+ evs_del(evid);
return 0;
}
-gboolean evs_check_timeout()
-{
- time_t now_t;
- GSList *p;
- eviqs *i;
-
- time(&now_t);
- p = evs_list;
- if (!p)
- return FALSE;
- 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);
- }
- }
- return TRUE;
-}
-
+// evs_display_list()
+// Prints list of events to mcabber log window.
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;
+ evs_t *i = p->data;
scr_LogPrint(LPRINT_LOGNORM,
- "Id: %-3s %s", i->id, (i->desc ? i->desc : ""));
+ "Id: %-3s %s", i->id,
+ (i->description ? i->description : ""));
}
scr_LogPrint(LPRINT_LOGNORM, "End of events list.");
}
-// evs_geteventslist(bool comp)
-// Return a singly-linked-list of events ids, for the completion system.
-// If comp is true, the string "list" is added (it's a completion argument).
-// Note: the caller should free the list (and data) after use.
-GSList *evs_geteventslist(int compl)
+// evs_geteventslist()
+// Return a singly-linked-list of events ids.
+// Data in list should not be modified and can disappear,
+// you must strdup them, if you want them to persist.
+// Note: the caller should free the list after use.
+GSList *evs_geteventslist(void)
{
GSList *evidlist = NULL, *p;
- eviqs *i;
for (p = evs_list; p; p = g_slist_next(p)) {
- i = p->data;
- evidlist = g_slist_append(evidlist, g_strdup(i->id));
+ evs_t *i = p->data;
+ evidlist = g_slist_append(evidlist, i->id);
}
- if (compl) {
- // Last item is the "list" subcommand.
- evidlist = g_slist_append(evidlist, g_strdup("list"));
- }
return evidlist;
}
+// evs_deinit()
+// Frees all events.
+void evs_deinit(void)
+{
+ GSList *eel;
+ for (eel = evs_list; eel; eel = eel->next) {
+ evs_t *event = eel->data;
+ if (event->notify)
+ event->notify(event->data);
+ if (event->source)
+ g_source_remove(event->source);
+
+ evs_list = g_slist_remove(evs_list, event);
+ g_free(event->id);
+ g_free(event->description);
+ g_free(event);
+ }
+ g_slist_free(evs_list);
+ evs_list = NULL;
+}
+
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
--- a/mcabber/mcabber/events.h Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/events.h Tue Feb 02 22:44:18 2010 +0100
@@ -8,40 +8,18 @@
#define EVS_CONTEXT_TIMEOUT 0U
#define EVS_CONTEXT_CANCEL 1U
-#define EVS_CONTEXT_USER 2U
+#define EVS_CONTEXT_ACCEPT 2U
+#define EVS_CONTEXT_REJECT 3U
+/* There can be other user-defined contexts */
-typedef enum {
- EVS_TYPE_SUBSCRIPTION = 1,
- EVS_TYPE_INVITATION = 2,
-#ifdef MODULES_ENABLE
- EVS_TYPE_USER = 3,
-#endif
-} evs_type;
+typedef gboolean (*evs_callback_t)(guint context, const char *arg, gpointer userdata);
-/* 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;
- int (*callback)();
- char *desc;
-} eviqs;
-
-typedef struct {
- char* to;
- char* from;
- char* passwd;
- char* reason;
-} event_muc_invitation;
-
-eviqs *evs_new(guint8 type, time_t timeout);
-int evs_del(const char *evid);
-int evs_callback(const char *evid, guint evcontext);
-gboolean evs_check_timeout();
-void evs_display_list(void);
-GSList *evs_geteventslist(int forcompl);
+const char *evs_new(const char *description, const char *id, time_t timeout, evs_callback_t callback, gpointer userdata, GDestroyNotify notify);
+int evs_del(const char *evid);
+int evs_callback(const char *evid, guint evcontext, const char *arg);
+void evs_display_list(void);
+GSList *evs_geteventslist(void);
+void evs_deinit(void);
#endif /* __MCABBER_EVENTS_H__ */
--- a/mcabber/mcabber/main.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/main.c Tue Feb 02 22:44:18 2010 +0100
@@ -45,6 +45,7 @@
#include "fifo.h"
#include "xmpp.h"
#include "help.h"
+#include "events.h"
#ifdef ENABLE_HGCSET
# include "hgcset.h"
@@ -464,6 +465,7 @@
g_source_unref(mc_source);
}
+ evs_deinit();
scr_TerminateCurses();
#ifdef MODULES_ENABLE
cmd_deinit();
--- a/mcabber/mcabber/xmpp.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/xmpp.c Tue Feb 02 22:44:18 2010 +0100
@@ -1473,7 +1473,6 @@
if (mstype == LM_MESSAGE_SUB_TYPE_SUBSCRIBE) {
/* The sender wishes to subscribe to our presence */
const char *msg;
- eviqs *evn;
msg = lm_message_node_get_child_value(m->node, "status");
@@ -1492,15 +1491,18 @@
}
// Create a new event item
- evn = evs_new(EVS_TYPE_SUBSCRIPTION, EVS_MAX_TIMEOUT);
- if (evn) {
- evn->callback = &evscallback_subscription;
- evn->data = g_strdup(r);
- evn->desc = g_strdup_printf("<%s> wants to subscribe to your "
- "presence updates", r);
- buf = g_strdup_printf("Please use /event %s accept|reject", evn->id);
- } else {
- buf = g_strdup_printf("Unable to create a new event!");
+ {
+ const char *id;
+ char *desc = g_strdup_printf("<%s> wants to subscribe to your "
+ "presence updates", r);
+
+ id = evs_new(desc, NULL, 0, evscallback_subscription, g_strdup(r),
+ (GDestroyNotify)g_free);
+ g_free(desc);
+ if (id)
+ buf = g_strdup_printf("Please use /event %s accept|reject", id);
+ else
+ buf = g_strdup_printf("Unable to create a new event!");
}
scr_WriteIncomingMessage(r, buf, 0, HBB_PREFIX_INFO, 0);
scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
--- a/mcabber/mcabber/xmpp_muc.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/xmpp_muc.c Tue Feb 02 22:44:18 2010 +0100
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include "xmpp_helper.h"
+#include "xmpp_muc.h"
#include "events.h"
#include "hooks.h"
#include "screen.h"
@@ -37,7 +38,7 @@
extern enum imstatus mystatus;
extern gchar *mystatusmsg;
-static void decline_invitation(event_muc_invitation *invitation, char *reason)
+static void decline_invitation(event_muc_invitation *invitation, const char *reason)
{
// cut and paste from xmpp_room_invite
LmMessage *m;
@@ -62,47 +63,51 @@
lm_message_unref(m);
}
-static int evscallback_invitation(eviqs *evp, guint evcontext)
+void destroy_event_muc_invitation(event_muc_invitation *invitation)
{
- event_muc_invitation *invitation = evp->data;
+ g_free(invitation->to);
+ g_free(invitation->from);
+ g_free(invitation->passwd);
+ g_free(invitation->reason);
+ g_free(invitation);
+}
+
+// invitation event handler
+// TODO: if event is accepted, check if other events to the same room exist and
+// destroy them? (need invitation registry list for that)
+static gboolean evscallback_invitation(guint evcontext, const char *arg, gpointer userdata)
+{
+ event_muc_invitation *invitation = userdata;
// Sanity check
- if (!invitation) {
+ if (G_UNLIKELY(!invitation)) {
// Shouldn't happen.
scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
- return 0;
+ return FALSE;
}
if (evcontext == EVS_CONTEXT_TIMEOUT) {
- scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.", evp->id);
- goto evscallback_invitation_free;
+ scr_LogPrint(LPRINT_LOGNORM, "Invitation event %s timed out, cancelled.", invitation->to);
+ return FALSE;
}
if (evcontext == EVS_CONTEXT_CANCEL) {
- scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
- goto evscallback_invitation_free;
+ scr_LogPrint(LPRINT_LOGNORM, "Invitation event %s cancelled.", invitation->to);
+ return FALSE;
}
- if (!(evcontext & EVS_CONTEXT_USER))
- goto evscallback_invitation_free;
- // Ok, let's work now.
- // evcontext: 0, 1 == reject, accept
+ if (!(evcontext == EVS_CONTEXT_ACCEPT || evcontext == EVS_CONTEXT_REJECT))
+ return FALSE;
- if (evcontext & ~EVS_CONTEXT_USER) {
+ // Ok, let's work now
+ if (evcontext == EVS_CONTEXT_ACCEPT) {
char *nickname = default_muc_nickname(invitation->to);
xmpp_room_join(invitation->to, nickname, invitation->passwd);
g_free(nickname);
} else {
scr_LogPrint(LPRINT_LOGNORM, "Invitation to %s refused.", invitation->to);
- decline_invitation(invitation, NULL);
+ decline_invitation(invitation, arg);
}
-evscallback_invitation_free:
- g_free(invitation->to);
- g_free(invitation->from);
- g_free(invitation->passwd);
- g_free(invitation->reason);
- g_free(invitation);
- evp->data = NULL;
- return 0;
+ return FALSE;
}
// Join a MUC room
@@ -642,11 +647,11 @@
// This function should be called when receiving an invitation from user
// "from", to enter the room "to". Optional reason and room password can
// be provided.
+// TODO: check for duplicate invites (need an existing invitation registry
+// for that).
static void got_invite(const char* from, const char *to, const char* reason,
const char* passwd)
{
- eviqs *evn;
- event_muc_invitation *invitation;
GString *sbuf;
char *barejid;
GSList *room_elt;
@@ -665,19 +670,24 @@
scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
- evn = evs_new(EVS_TYPE_INVITATION, EVS_MAX_TIMEOUT);
- if (evn) {
- evn->callback = &evscallback_invitation;
+ {
+ const char *id;
+ char *desc = g_strdup_printf("<%s> invites you to %s", from, to);
+ event_muc_invitation *invitation;
+
invitation = g_new(event_muc_invitation, 1);
invitation->to = g_strdup(to);
invitation->from = g_strdup(from);
invitation->passwd = g_strdup(passwd);
invitation->reason = g_strdup(reason);
- evn->data = invitation;
- evn->desc = g_strdup_printf("<%s> invites you to %s ", from, to);
- g_string_printf(sbuf, "Please use /event %s accept|reject", evn->id);
- } else {
- g_string_printf(sbuf, "Unable to create a new event!");
+
+ id = evs_new(desc, NULL, 0, evscallback_invitation, invitation,
+ (GDestroyNotify)destroy_event_muc_invitation);
+ g_free(desc);
+ if (id)
+ g_string_printf(sbuf, "Please use /event %s accept|reject", id);
+ else
+ g_string_printf(sbuf, "Unable to create a new event!");
}
scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0);
scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str);
--- a/mcabber/mcabber/xmpp_muc.h Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/xmpp_muc.h Tue Feb 02 22:44:18 2010 +0100
@@ -1,6 +1,14 @@
#ifndef __MCABBER_XMPP_MUC_H__
#define __MCABBER_XMPP_MUC_H__ 1
+typedef struct {
+ char *to;
+ char *from;
+ char *passwd;
+ char *reason;
+} event_muc_invitation;
+
+void destroy_event_muc_invitation(event_muc_invitation *invitation);
void roompresence(gpointer room, void *presencedata);
void got_muc_message(const char *from, LmMessageNode *x);
void handle_muc_presence(const char *from, LmMessageNode * xmldata,
--- a/mcabber/mcabber/xmpp_s10n.c Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/xmpp_s10n.c Tue Feb 02 22:44:18 2010 +0100
@@ -37,36 +37,32 @@
lm_message_unref(x);
}
-int evscallback_subscription(eviqs *evp, guint evcontext)
+gboolean evscallback_subscription(guint evcontext, const char *arg, gpointer userdata)
{
- char *barejid;
+ char *barejid = userdata;
char *buf;
+ // Sanity check
+ if (G_UNLIKELY(!barejid)) {
+ // Shouldn't happen, data should be set to the barejid.
+ scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
+ return FALSE;
+ }
+
if (evcontext == EVS_CONTEXT_TIMEOUT) {
- scr_LogPrint(LPRINT_LOGNORM, "Event %s timed out, cancelled.",
- evp->id);
- return 0;
+ scr_LogPrint(LPRINT_LOGNORM, "Subscription event for %s timed out, cancelled.",
+ barejid);
+ return FALSE;
}
if (evcontext == EVS_CONTEXT_CANCEL) {
- scr_LogPrint(LPRINT_LOGNORM, "Event %s cancelled.", evp->id);
- return 0;
+ scr_LogPrint(LPRINT_LOGNORM, "Subscription event for %s cancelled.", barejid);
+ return FALSE;
}
- if (!(evcontext & EVS_CONTEXT_USER))
- return 0;
-
- // Sanity check
- if (!evp->data) {
- // Shouldn't happen, data should be set to the barejid.
- scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
- return 0;
- }
+ if (!(evcontext == EVS_CONTEXT_REJECT || evcontext == EVS_CONTEXT_ACCEPT))
+ return FALSE;
// Ok, let's work now.
- // evcontext: 0, 1 == reject, accept
-
- barejid = evp->data;
-
- if (evcontext & ~EVS_CONTEXT_USER) {
+ if (evcontext == EVS_CONTEXT_ACCEPT) {
// Accept subscription request
xmpp_send_s10n(barejid, LM_MESSAGE_SUB_TYPE_SUBSCRIBED);
buf = g_strdup_printf("<%s> is allowed to receive your presence updates",
@@ -84,7 +80,7 @@
scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_INFO, 0);
scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
g_free(buf);
- return 0;
+ return FALSE;
}
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
--- a/mcabber/mcabber/xmpp_s10n.h Tue Jan 19 19:16:38 2010 +0200
+++ b/mcabber/mcabber/xmpp_s10n.h Tue Feb 02 22:44:18 2010 +0100
@@ -3,7 +3,7 @@
#include <mcabber/events.h>
-int evscallback_subscription(eviqs *evp, guint evcontext);
+gboolean evscallback_subscription(guint evcontext, const char *arg, gpointer userdata);
#endif /* __MCABBER_XMPP_S10N_H__ */