# HG changeset patch # User Myhailo Danylenko # Date 1265147058 -3600 # Node ID 1342df44c814ce8744817b977b11268af2239d69 # Parent 95df4ea512c8bb64cb0e5d9e31b7d560352400a9 Improved events interface * User can pass additional arguments to event handler * MUC invitation reject now can be supplied a reason diff -r 95df4ea512c8 -r 1342df44c814 mcabber/doc/help/en/hlp_event.txt --- 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 diff -r 95df4ea512c8 -r 1342df44c814 mcabber/doc/help/ru/hlp_event.txt --- 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 Показать список всех событий diff -r 95df4ea512c8 -r 1342df44c814 mcabber/doc/help/uk/hlp_event.txt --- 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 Друкує перелік подій. diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/commands.c --- 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); } diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/compl.c --- 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; diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/events.c --- 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 + * Copyrigth (C) 2010 Myhailo Danylenko * * 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... */ diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/events.h --- 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__ */ diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/main.c --- 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(); diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/xmpp.c --- 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); diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/xmpp_muc.c --- 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 #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); diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/xmpp_muc.h --- 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, diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/xmpp_s10n.c --- 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... */ diff -r 95df4ea512c8 -r 1342df44c814 mcabber/mcabber/xmpp_s10n.h --- 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 -int evscallback_subscription(eviqs *evp, guint evcontext); +gboolean evscallback_subscription(guint evcontext, const char *arg, gpointer userdata); #endif /* __MCABBER_XMPP_S10N_H__ */