Back to index

citadel  8.12
xmpp_queue.c
Go to the documentation of this file.
00001 /*
00002  * XMPP event queue
00003  *
00004  * Copyright (c) 2007-2009 by Art Cancro
00005  *
00006  *  This program is open source software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License version 3.
00008  *  
00009  *  
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  
00017  *  
00018  *  
00019  *
00020  */
00021 
00022 #include "sysdep.h"
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <stdio.h>
00026 #include <fcntl.h>
00027 #include <signal.h>
00028 #include <pwd.h>
00029 #include <errno.h>
00030 #include <sys/types.h>
00031 
00032 #if TIME_WITH_SYS_TIME
00033 # include <sys/time.h>
00034 # include <time.h>
00035 #else
00036 # if HAVE_SYS_TIME_H
00037 #  include <sys/time.h>
00038 # else
00039 #  include <time.h>
00040 # endif
00041 #endif
00042 
00043 #include <sys/wait.h>
00044 #include <string.h>
00045 #include <limits.h>
00046 #include <ctype.h>
00047 #include <expat.h>
00048 #include <libcitadel.h>
00049 #include "citadel.h"
00050 #include "server.h"
00051 #include "citserver.h"
00052 #include "support.h"
00053 #include "config.h"
00054 #include "internet_addressing.h"
00055 #include "md5.h"
00056 #include "ctdl_module.h"
00057 #include "serv_xmpp.h"
00058 
00059 int queue_event_seq = 0;
00060 
00061 void xmpp_queue_event(int event_type, char *email_addr) {
00062 
00063        struct xmpp_event *xptr = NULL;
00064        struct xmpp_event *new_event = NULL;
00065        struct xmpp_event *last = NULL;
00066        int purged_something = 0;
00067        struct CitContext *cptr;
00068 
00069        XMPP_syslog(LOG_DEBUG, "xmpp_queue_event(%d, %s)\n", event_type, email_addr);
00070 
00071        /* Purge events more than a minute old */
00072        begin_critical_section(S_XMPP_QUEUE);
00073        do {
00074               purged_something = 0;
00075               if (xmpp_queue != NULL) {
00076                      if ((time(NULL) - xmpp_queue->event_time) > 60) {
00077                             xptr = xmpp_queue->next;
00078                             free(xmpp_queue);
00079                             xmpp_queue = xptr;
00080                             purged_something = 1;
00081                      }
00082               }
00083        } while(purged_something);
00084        end_critical_section(S_XMPP_QUEUE);
00085 
00086        /* Create a new event */
00087        new_event = (struct xmpp_event *) malloc(sizeof(struct xmpp_event));
00088        new_event->next = NULL;
00089        new_event->event_time = time(NULL);
00090        new_event->event_seq = ++queue_event_seq;
00091        new_event->event_type = event_type;
00092        new_event->session_which_generated_this_event = CC->cs_pid;
00093        safestrncpy(new_event->event_jid, email_addr, sizeof new_event->event_jid);
00094 
00095        /* Add it to the list */
00096        begin_critical_section(S_XMPP_QUEUE);
00097        if (xmpp_queue == NULL) {
00098               xmpp_queue = new_event;
00099        }
00100        else {
00101               for (xptr = xmpp_queue; xptr != NULL; xptr = xptr->next) {
00102                      if (xptr->next == NULL) {
00103                             last = xptr;
00104                      }
00105               }
00106               last->next = new_event;
00107        }
00108        end_critical_section(S_XMPP_QUEUE);
00109 
00110        /* Tell the sessions that something is happening */
00111        begin_critical_section(S_SESSION_TABLE);
00112        for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
00113               if ((cptr->logged_in) && (cptr->h_async_function == xmpp_async_loop)) {
00114                      set_async_waiting(cptr);
00115               }
00116        }
00117        end_critical_section(S_SESSION_TABLE);
00118 }
00119 
00120 
00121 /* 
00122  * Are we interested in anything from the queue?  (Called in async loop)
00123  */
00124 void xmpp_process_events(void) {
00125        struct xmpp_event *xptr = NULL;
00126        int highest_event = 0;
00127 
00128        for (xptr=xmpp_queue; xptr!=NULL; xptr=xptr->next) {
00129               if (xptr->event_seq > XMPP->last_event_processed) {
00130 
00131                      switch(xptr->event_type) {
00132 
00133                             case XMPP_EVT_LOGIN:
00134                             case XMPP_EVT_LOGOUT:
00135                                    if (xptr->session_which_generated_this_event != CC->cs_pid) {
00136                                           xmpp_presence_notify(xptr->event_jid, xptr->event_type);
00137                                    }
00138                                    break;
00139                      }
00140 
00141                      if (xptr->event_seq > highest_event) {
00142                             highest_event = xptr->event_seq;
00143                      }
00144               }
00145        }
00146 
00147        XMPP->last_event_processed = highest_event;
00148 }
00149 
00150 
00151 void xmpp_cleanup_events(void)
00152 {
00153         struct xmpp_event *ptr, *ptr2;
00154         begin_critical_section(S_XMPP_QUEUE);
00155        ptr = xmpp_queue;
00156        xmpp_queue = NULL;
00157        while (ptr != NULL) {
00158               ptr2 = ptr->next;
00159               free(ptr);
00160               ptr = ptr2;
00161        }
00162         end_critical_section(S_XMPP_QUEUE);
00163 
00164 }