X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fxmpp%2Fxmpp_presence.c;fp=citadel%2Fmodules%2Fxmpp%2Fxmpp_presence.c;h=0000000000000000000000000000000000000000;hb=f6fcf350671e3661f8f22696eb35133014ab6a14;hp=00fb4e3bd77534c9ee48bbea95bf814def457fee;hpb=2e4e67a1f7f65568abace99d13a71024ad06ebde;p=citadel.git diff --git a/citadel/modules/xmpp/xmpp_presence.c b/citadel/modules/xmpp/xmpp_presence.c deleted file mode 100644 index 00fb4e3bd..000000000 --- a/citadel/modules/xmpp/xmpp_presence.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Handle XMPP presence exchanges - * - * Copyright (c) 2007-2021 by Art Cancro and citadel.org - * - * This program is open source 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 3 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 "sysdep.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "server.h" -#include "citserver.h" -#include "support.h" -#include "config.h" -#include "internet_addressing.h" -#include "ctdl_module.h" -#include "serv_xmpp.h" - - -/* - * Indicate the presence of another user to the client - * (used in several places) - */ -void xmpp_indicate_presence(char *presence_jid) { - char xmlbuf[256]; - - syslog(LOG_DEBUG, "xmpp: indicating presence of <%s> to <%s>", presence_jid, XMPP->client_jid); - cprintf("", xmlesc(xmlbuf, XMPP->client_jid, sizeof xmlbuf)); -} - - -/* - * Convenience function to determine whether any given session is 'visible' to any other given session, - * and is capable of receiving instant messages from that session. - */ -int xmpp_is_visible(struct CitContext *cptr, struct CitContext *to_whom) { - int aide = (to_whom->user.axlevel >= AxAideU); - - if ( (cptr->logged_in) - && (((cptr->cs_flags&CS_STEALTH)==0) || (aide)) /* aides see everyone */ - && (cptr->user.usernum != to_whom->user.usernum) /* don't show myself */ - && (cptr->can_receive_im) /* IM-capable session */ - ) { - return(1); - } - else { - return(0); - } -} - - -/* - * Initial dump of the entire wholist - */ -void xmpp_wholist_presence_dump(void) { - struct CitContext *cptr = NULL; - int nContexts, i; - - cptr = CtdlGetContextArray(&nContexts); - if (!cptr) { - return; - } - - for (i=0; iclient_jid) return; - - /* Transmit non-presence information */ - cprintf("", - xmlesc(xmlbuf1, presence_jid, sizeof xmlbuf1), - xmlesc(xmlbuf2, XMPP->client_jid, sizeof xmlbuf2) - ); - - /* - * Setting the "aggressively" flag also sends an "unsubscribed" presence update. - * We only ask for this when flushing the client side roster, because if we do it - * in the middle of a session when another user logs off, some clients (Jitsi) interpret - * it as a rejection of a subscription request. - */ - if (aggressively) { - cprintf("", - xmlesc(xmlbuf1, presence_jid, sizeof xmlbuf1), - xmlesc(xmlbuf2, XMPP->client_jid, sizeof xmlbuf2) - ); - } - - // note: we should implement xmpp_indicate_nonpresence so we can use it elsewhere - - /* Do an unsolicited roster update that deletes the contact. */ - cprintf("", - xmlesc(xmlbuf1, CC->cs_principal_id, sizeof xmlbuf1), - xmlesc(xmlbuf2, XMPP->client_jid, sizeof xmlbuf2), - ++unsolicited_id - ); - cprintf(""); - cprintf("", xmlesc(xmlbuf1, presence_jid, sizeof xmlbuf1)); - cprintf("%s", xmlesc(xmlbuf1, CtdlGetConfigStr("c_humannode"), sizeof xmlbuf1)); - cprintf(""); - cprintf("" - "" - ); -} - - -/* - * When a user logs in or out of the local Citadel system, notify all XMPP sessions about it. - * THIS FUNCTION HAS A BUG IN IT THAT ENUMERATES THE SESSIONS WRONG. - */ -void xmpp_presence_notify(char *presence_jid, int event_type) { - struct CitContext *cptr; - static int unsolicited_id = 12345; - int visible_sessions = 0; - int nContexts, i; - int which_cptr_is_relevant = (-1); - - if (IsEmptyStr(presence_jid)) return; - if (CC->kill_me) return; - - cptr = CtdlGetContextArray(&nContexts); - if (!cptr) { - return; - } - - /* Count the visible sessions for this user */ - for (i=0; i are now visible to session %d", visible_sessions, presence_jid, CC->cs_pid); - - if ( (event_type == XMPP_EVT_LOGIN) && (visible_sessions == 1) ) { - - syslog(LOG_DEBUG, "xmpp: telling session %d that <%s> logged in", CC->cs_pid, presence_jid); - - /* Do an unsolicited roster update that adds a new contact. */ - assert(which_cptr_is_relevant >= 0); - cprintf("", ++unsolicited_id); - cprintf(""); - xmpp_roster_item(&cptr[which_cptr_is_relevant]); - cprintf(""); - - /* Transmit presence information */ - xmpp_indicate_presence(presence_jid); - } - - if (visible_sessions == 0) { - syslog(LOG_DEBUG, "xmpp: telling session %d that <%s> logged out", CC->cs_pid, presence_jid); - xmpp_destroy_buddy(presence_jid, 0); /* non aggressive presence update */ - } - - free(cptr); -} - - -void xmpp_fetch_mortuary_backend(long msgnum, void *userdata) { - HashList *mortuary = (HashList *) userdata; - struct CtdlMessage *msg; - char *ptr = NULL; - char *lasts = NULL; - - msg = CtdlFetchMessage(msgnum, 1); - if (msg == NULL) { - return; - } - - /* now add anyone we find into the hashlist */ - - /* skip past the headers */ - ptr = strstr(msg->cm_fields[eMesageText], "\n\n"); - if (ptr != NULL) { - ptr += 2; - } - else { - ptr = strstr(msg->cm_fields[eMesageText], "\n\r\n"); - if (ptr != NULL) { - ptr += 3; - } - } - - /* the remaining lines are addresses */ - if (ptr != NULL) { - ptr = strtok_r(ptr, "\n", &lasts); - while (ptr != NULL) { - char *pch = strdup(ptr); - Put(mortuary, pch, strlen(pch), pch, NULL); - ptr = strtok_r(NULL, "\n", &lasts); - } - } - - CM_Free(msg); -} - - -/* - * Fetch the "mortuary" - a list of dead buddies which we keep around forever - * so we can remove them from any client's roster that still has them listed - */ -HashList *xmpp_fetch_mortuary(void) { - HashList *mortuary = NewHash(1, NULL); - if (!mortuary) { - syslog(LOG_ALERT, "xmpp: NewHash() failed!"); - return(NULL); - } - - if (CtdlGetRoom(&CC->room, USERCONFIGROOM) != 0) { - /* no config room exists - no further processing is required. */ - return(mortuary); - } - CtdlForEachMessage(MSGS_LAST, 1, NULL, XMPPMORTUARY, NULL, - xmpp_fetch_mortuary_backend, (void *)mortuary ); - - return(mortuary); -} - - -/* - * Fetch the "mortuary" - a list of dead buddies which we keep around forever - * so we can remove them from any client's roster that still has them listed - */ -void xmpp_store_mortuary(HashList *mortuary) { - HashPos *HashPos; - long len; - void *Value; - const char *Key; - StrBuf *themsg; - - themsg = NewStrBuf(); - StrBufPrintf(themsg, "Content-type: " XMPPMORTUARY "\n" - "Content-transfer-encoding: 7bit\n" - "\n" - ); - - HashPos = GetNewHashPos(mortuary, 0); - while (GetNextHashPos(mortuary, HashPos, &len, &Key, &Value) != 0) { - StrBufAppendPrintf(themsg, "%s\n", (char *)Value); - } - DeleteHashPos(&HashPos); - - /* Delete the old mortuary */ - CtdlDeleteMessages(USERCONFIGROOM, NULL, 0, XMPPMORTUARY); - - /* And save the new one to disk */ - quickie_message(CC->user.fullname, NULL, NULL, USERCONFIGROOM, ChrPtr(themsg), 4, "XMPP Mortuary"); - FreeStrBuf(&themsg); -} - - -/* - * Upon logout we make an attempt to delete the whole roster, in order to - * try to keep "ghost" buddies from remaining in the client-side roster. - * - * Since the client is probably not still alive, also remember the current - * roster for next time so we can delete dead buddies then. - */ -void xmpp_massacre_roster(void) { - struct CitContext *cptr; - int nContexts, i; - HashList *mortuary = xmpp_fetch_mortuary(); - - cptr = CtdlGetContextArray(&nContexts); - if (cptr) { - for (i=0; i