From c90234687ee8cff0d623acca4e6d2cbe091791d6 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 3 Dec 2007 07:22:43 +0000 Subject: [PATCH] Only send presence notifications when the first concurrent session for a user logs in, or when the last session logs out. Also handle stealth mode semantics. --- citadel/modules/jabber/serv_xmpp.c | 3 +- citadel/modules/jabber/xmpp_presence.c | 38 ++++++++++++++++++-------- citadel/modules/rwho/serv_rwho.c | 2 ++ citadel/server.h | 2 ++ 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/citadel/modules/jabber/serv_xmpp.c b/citadel/modules/jabber/serv_xmpp.c index 210d19820..b73579257 100644 --- a/citadel/modules/jabber/serv_xmpp.c +++ b/citadel/modules/jabber/serv_xmpp.c @@ -446,7 +446,8 @@ CTDL_MODULE_INIT(jabber) CtdlRegisterSessionHook(xmpp_cleanup_function, EVT_STOP); CtdlRegisterSessionHook(xmpp_login_hook, EVT_LOGIN); CtdlRegisterSessionHook(xmpp_logout_hook, EVT_LOGOUT); - + CtdlRegisterSessionHook(xmpp_login_hook, EVT_UNSTEALTH); + CtdlRegisterSessionHook(xmpp_logout_hook, EVT_STEALTH); #else lprintf(CTDL_INFO, "This server is missing the Expat XML parser. Jabber service will be disabled.\n"); #endif diff --git a/citadel/modules/jabber/xmpp_presence.c b/citadel/modules/jabber/xmpp_presence.c index 96b533c2a..0bce01b13 100644 --- a/citadel/modules/jabber/xmpp_presence.c +++ b/citadel/modules/jabber/xmpp_presence.c @@ -75,18 +75,27 @@ void jabber_wholist_presence_dump(void) void xmpp_presence_notify(char *presence_jid, char *presence_type) { struct CitContext *cptr; static int unsolicited_id; + int visible_sessions = 0; + int aide = (CC->user.axlevel >= 6); + + if (IsEmptyStr(presence_jid)) return; - /* FIXME subject this to the same conditions as above */ + /* Count the visible sessions for this user */ + for (cptr = ContextList; cptr != NULL; cptr = cptr->next) { + if ( (!strcasecmp(cptr->cs_inet_email, presence_jid)) + && (((cptr->cs_flags&CS_STEALTH)==0) || (aide)) + ) { + ++visible_sessions; + } + } - /* FIXME make sure don't do this for multiple logins of the same user (login) - * or until the last concurrent login is logged out (logout) - */ + lprintf(CTDL_DEBUG, "%d sessions for <%s> are now visible to session %d\n", + visible_sessions, presence_jid, CC->cs_pid); - if (IsEmptyStr(presence_jid)) return; - lprintf(CTDL_DEBUG, "Sending presence info about <%s> to session %d\n", presence_jid, CC->cs_pid); + if ( (strcasecmp(presence_type, "unavailable")) && (visible_sessions == 1) ) { + lprintf(CTDL_DEBUG, "Telling session %d that <%s> logged in\n", CC->cs_pid, presence_jid); - /* Transmit an unsolicited roster update if the presence is anything other than "unavailable" */ - if (strcasecmp(presence_type, "unavailable")) { + /* Do an unsolicited roster update that adds a new contact. */ for (cptr = ContextList; cptr != NULL; cptr = cptr->next) { if (!strcasecmp(cptr->cs_inet_email, presence_jid)) { cprintf("", ++unsolicited_id); @@ -96,13 +105,18 @@ void xmpp_presence_notify(char *presence_jid, char *presence_type) { ""); } } + + /* Transmit presence information */ + cprintf("", presence_type, presence_jid); } - /* Now transmit unsolicited presence information */ - cprintf("", presence_type, presence_jid); + if ( (!strcasecmp(presence_type, "unavailable")) && (visible_sessions == 0) ) { + lprintf(CTDL_DEBUG, "Telling session %d that <%s> logged out\n", CC->cs_pid, presence_jid); + + /* Transmit non-presence information */ + cprintf("", presence_type, presence_jid); - /* For "unavailable" we do an unsolicited roster update that deletes the contact. */ - if (!strcasecmp(presence_type, "unavailable")) { + /* Do an unsolicited roster update that deletes the contact. */ cprintf("", ++unsolicited_id); cprintf(""); cprintf("", presence_jid); diff --git a/citadel/modules/rwho/serv_rwho.c b/citadel/modules/rwho/serv_rwho.c index b09605d1f..793272773 100644 --- a/citadel/modules/rwho/serv_rwho.c +++ b/citadel/modules/rwho/serv_rwho.c @@ -238,9 +238,11 @@ void cmd_stel(char *cmdbuf) if (requested_mode == 1) { CC->cs_flags = CC->cs_flags | CS_STEALTH; + PerformSessionHooks(EVT_STEALTH); } if (requested_mode == 0) { CC->cs_flags = CC->cs_flags & ~CS_STEALTH; + PerformSessionHooks(EVT_UNSTEALTH); } cprintf("%d %d\n", CIT_OK, diff --git a/citadel/server.h b/citadel/server.h index f88d37fd6..d77726a44 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -308,6 +308,8 @@ struct cdbdata { #define EVT_CMD 6 /* Called after each server command */ #define EVT_RWHO 7 /* An RWHO command is being executed */ #define EVT_ASYNC 8 /* Doing asynchronous messages */ +#define EVT_STEALTH 9 /* Entering stealth mode */ +#define EVT_UNSTEALTH 10 /* Exiting stealth mode */ #define EVT_TIMER 50 /* Timer events are called once per minute and are not tied to any session */ -- 2.30.2