Back to index

citadel  8.12
Classes | Defines | Typedefs | Enumerations | Functions | Variables
context.h File Reference
#include <stdarg.h>
#include "sysdep.h"
#include "server.h"
#include "sysdep_decls.h"
#include "threads.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  CitContext

Defines

#define CC   MyContext()
#define TERM_FOUND   0x01
#define TERM_ALLOWED   0x02
#define TERM_KILLED   0x03
#define TERM_NOTALLOWED   -1
#define CONDBGLOG(LEVEL)   if ((LEVEL != LOG_DEBUG) || (DebugSession != 0))
#define CON_syslog(LEVEL, FORMAT,...)
#define CONM_syslog(LEVEL, FORMAT)

Typedefs

typedef enum __CCState CCState
typedef struct CitContext

Enumerations

enum  __CCState {
  CON_IDLE, CON_GREETING, CON_STARTING, CON_READY,
  CON_EXECUTING, CON_SYS
}

Functions

CitContextMyContext (void)
void RemoveContext (struct CitContext *)
CitContextCreateNewContext (void)
void context_cleanup (void)
void kill_session (int session_to_kill)
void InitializeMasterCC (void)
void dead_session_purge (int force)
void set_async_waiting (struct CitContext *ccptr)
CitContextCloneContext (CitContext *CloneMe)
void terminate_all_sessions (void)
void BumpNewMailCounter (long) __attribute__((deprecated))
void terminate_idle_sessions (void)
int CtdlTerminateOtherSession (int session_num)
static INLINE void become_session (CitContext *which_con)

Variables

pthread_key_t MyConKey
int num_sessions
CitContext masterCC
CitContextContextList
int DebugSession

Define Documentation

#define CC   MyContext()

Definition at line 148 of file context.h.

#define CON_syslog (   LEVEL,
  FORMAT,
  ... 
)
Value:
CONDBGLOG(LEVEL) syslog(LEVEL,                          \
                            "Context: " FORMAT, __VA_ARGS__)

Definition at line 204 of file context.h.

#define CONDBGLOG (   LEVEL)    if ((LEVEL != LOG_DEBUG) || (DebugSession != 0))

Definition at line 202 of file context.h.

#define CONM_syslog (   LEVEL,
  FORMAT 
)
Value:
CONDBGLOG(LEVEL) syslog(LEVEL,                   \
                            "Context: " FORMAT);

Definition at line 208 of file context.h.

#define TERM_ALLOWED   0x02

Definition at line 177 of file context.h.

#define TERM_FOUND   0x01

Definition at line 176 of file context.h.

#define TERM_KILLED   0x03

Definition at line 178 of file context.h.

#define TERM_NOTALLOWED   -1

Definition at line 179 of file context.h.


Typedef Documentation

typedef enum __CCState CCState
typedef struct CitContext

Definition at line 145 of file context.h.


Enumeration Type Documentation

enum __CCState
Enumerator:
CON_IDLE 
CON_GREETING 
CON_STARTING 
CON_READY 
CON_EXECUTING 
CON_SYS 

Definition at line 22 of file context.h.

                       {
       CON_IDLE,            /* This context is doing nothing */
       CON_GREETING,        /* This context needs to output its greeting */
       CON_STARTING,        /* This context is outputting its greeting */
       CON_READY,           /* This context needs attention */
       CON_EXECUTING,              /* This context is bound to a thread */
       CON_SYS                 /* This is a system context and mustn't be purged */
} CCState;

Function Documentation

static INLINE void become_session ( CitContext which_con) [static]

Definition at line 184 of file context.h.

                                                         {
/*
       pid_t tid = syscall(SYS_gettid);
*/
       pthread_setspecific(MyConKey, (void *)which_con );
/*
       syslog(LOG_DEBUG, "[%d]: Now doing %s\n", 
                    (int) tid, 
                    ((which_con != NULL) && (which_con->ServiceName != NULL)) ? 
                    which_con->ServiceName:"");
*/
}

Here is the caller graph for this function:

void BumpNewMailCounter ( long  )

Definition at line 185 of file context.c.

{
       CtdlBumpNewMailCounter(which_user);
}

Here is the call graph for this function:

TODO: what about the room/user?

Definition at line 445 of file context.c.

                                              {
       CitContext *me;
       static int next_pid = 0;

       me = (CitContext *) malloc(sizeof(CitContext));
       if (me == NULL) {
              CONM_syslog(LOG_ALERT, "citserver: can't allocate memory!!\n");
              return NULL;
       }
       memcpy(me, CloneMe, sizeof(CitContext));

       memset(&me->RecvBuf, 0, sizeof(IOBuffer));
       memset(&me->SendBuf, 0, sizeof(IOBuffer));
       memset(&me->SBuf, 0, sizeof(IOBuffer));
       me->MigrateBuf = NULL;
       me->sMigrateBuf = NULL;
       me->redirect_buffer = NULL;
#ifdef HAVE_OPENSSL
       me->ssl = NULL;
#endif

       me->download_fp = NULL;
       me->upload_fp = NULL;
       me->ma = NULL;
       me->openid_data = NULL;
       me->ldap_dn = NULL;
       me->session_specific_data = NULL;

       me->download_fp = NULL;
       me->upload_fp = NULL;
       me->client_socket = 0;

       me->MigrateBuf = NewStrBuf();
       me->RecvBuf.Buf = NewStrBuf();
       
       begin_critical_section(S_SESSION_TABLE);
       {
              me->cs_pid = ++next_pid;
              me->prev = NULL;
              me->next = ContextList;
              me->lastcmd = time(NULL);   /* set lastcmd to now to prevent idle timer infanticide */
              ContextList = me;
              if (me->next != NULL) {
                     me->next->prev = me;
              }
              ++num_sessions;
       }
       end_critical_section(S_SESSION_TABLE);
       return (me);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void context_cleanup ( void  )

Definition at line 566 of file context.c.

{
       CitContext *ptr = NULL;
       CitContext *rem = NULL;

       /*
        * Clean up the contexts.
        * There are no threads so no critical_section stuff is needed.
        */
       ptr = ContextList;
       
       /* We need to update the ContextList because some modules may want to itterate it
        * Question is should we NULL it before iterating here or should we just keep updating it
        * as we remove items?
        *
        * Answer is to NULL it first to prevent modules from doing any actions on the list at all
        */
       ContextList=NULL;
       while (ptr != NULL){
              /* Remove the session from the active list */
              rem = ptr->next;
              --num_sessions;

              CON_syslog(LOG_DEBUG, "context_cleanup(): purging session %d\n", ptr->cs_pid);
              RemoveContext(ptr);
              free (ptr);
              ptr = rem;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 395 of file context.c.

                                   {
       CitContext *me;
       static int next_pid = 0;

       me = (CitContext *) malloc(sizeof(CitContext));
       if (me == NULL) {
              CONM_syslog(LOG_ALERT, "citserver: can't allocate memory!!\n");
              return NULL;
       }
       memset(me, 0, sizeof(CitContext));

       /* Give the context a name. Hopefully makes it easier to track */
       strcpy (me->user.fullname, "SYS_notauth");
       
       /* The new context will be created already in the CON_EXECUTING state
        * in order to prevent another thread from grabbing it while it's
        * being set up.
        */
       me->state = CON_EXECUTING;
       /*
        * Generate a unique session number and insert this context into
        * the list.
        */
       me->MigrateBuf = NewStrBuf();

       me->RecvBuf.Buf = NewStrBuf();

       me->lastcmd = time(NULL);   /* set lastcmd to now to prevent idle timer infanticide TODO: if we have a valid IO, use that to set the timer. */


       begin_critical_section(S_SESSION_TABLE);
       me->cs_pid = ++next_pid;
       me->prev = NULL;
       me->next = ContextList;
       ContextList = me;
       if (me->next != NULL) {
              me->next->prev = me;
       }
       ++num_sessions;
       end_critical_section(S_SESSION_TABLE);
       return (me);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlTerminateOtherSession ( int  session_num)

Definition at line 153 of file context.c.

{
       int ret = 0;
       CitContext *ccptr;

       if (session_num == CC->cs_pid) {
              return TERM_NOTALLOWED;
       }

       CONM_syslog(LOG_DEBUG, "Locating session to kill\n");
       begin_critical_section(S_SESSION_TABLE);
       for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
              if (session_num == ccptr->cs_pid) {
                     ret |= TERM_FOUND;
                     if ((ccptr->user.usernum == CC->user.usernum)
                        || (CC->user.axlevel >= AxAideU)) {
                            ret |= TERM_ALLOWED;
                            ccptr->kill_me = KILLME_ADMIN_TERMINATE;
                     }
              }
       }
       end_critical_section(S_SESSION_TABLE);
       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dead_session_purge ( int  force)

Definition at line 605 of file context.c.

                                   {
       CitContext *ptr, *ptr2;            /* general-purpose utility pointer */
       CitContext *rem = NULL;            /* list of sessions to be destroyed */
       
       if (force == 0) {
              if ( (time(NULL) - last_purge) < 5 ) {
                     return;       /* Too soon, go away */
              }
       }
       time(&last_purge);

       if (try_critical_section(S_SESSION_TABLE))
              return;
              
       ptr = ContextList;
       while (ptr) {
              ptr2 = ptr;
              ptr = ptr->next;
              
              if ( (ptr2->state == CON_IDLE) && (ptr2->kill_me) ) {
                     /* Remove the session from the active list */
                     if (ptr2->prev) {
                            ptr2->prev->next = ptr2->next;
                     }
                     else {
                            ContextList = ptr2->next;
                     }
                     if (ptr2->next) {
                            ptr2->next->prev = ptr2->prev;
                     }

                     --num_sessions;
                     /* And put it on our to-be-destroyed list */
                     ptr2->next = rem;
                     rem = ptr2;
              }
       }
       end_critical_section(S_SESSION_TABLE);

       /* Now that we no longer have the session list locked, we can take
        * our time and destroy any sessions on the to-be-killed list, which
        * is allocated privately on this thread's stack.
        */
       while (rem != NULL) {
              CON_syslog(LOG_DEBUG, "dead_session_purge(): purging session %d, reason=%d\n", rem->cs_pid, rem->kill_me);
              RemoveContext(rem);
              ptr = rem;
              rem = rem->next;
              free(ptr);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitializeMasterCC ( void  )

Definition at line 665 of file context.c.

                              {
       memset(&masterCC, 0, sizeof(struct CitContext));
       masterCC.internal_pgm = 1;
       masterCC.cs_pid = 0;
}

Here is the caller graph for this function:

void kill_session ( int  session_to_kill)
CitContext* MyContext ( void  )

Definition at line 261 of file context.c.

                            {
       register CitContext *c;
       return ((c = (CitContext *) pthread_getspecific(MyConKey), c == NULL) ? &masterCC : c);
}

Here is the caller graph for this function:

void RemoveContext ( struct CitContext )

cit_backtrace();

Definition at line 336 of file context.c.

{
       const char *c;
       if (con == NULL) {
              CONM_syslog(LOG_ERR, "WARNING: RemoveContext() called with NULL!");
              return;
       }
       c = con->ServiceName;
       if (c == NULL) {
              c = "WTF?";
       }
       CON_syslog(LOG_DEBUG, "RemoveContext(%s) session %d", c, con->cs_pid);

       /* Run any cleanup routines registered by loadable modules.
        * Note: We have to "become_session()" because the cleanup functions
        *       might make references to "CC" assuming it's the right one.
        */
       become_session(con);
       CtdlUserLogout();
       PerformSessionHooks(EVT_STOP);
       client_close();                           /* If the client is still connected, blow 'em away. */
       become_session(NULL);

       CON_syslog(LOG_NOTICE, "[%3d]SRV[%s] Session ended.", con->cs_pid, c);

       /* 
        * If the client is still connected, blow 'em away. 
        * if the socket is 0 or -1, its already gone or was never there.
        */
       if (con->client_socket > 0)
       {
              CON_syslog(LOG_NOTICE, "Closing socket %d", con->client_socket);
              close(con->client_socket);
       }

       /* If using AUTHMODE_LDAP, free the DN */
       if (con->ldap_dn) {
              free(con->ldap_dn);
              con->ldap_dn = NULL;
       }
       FreeStrBuf(&con->StatusMessage);
       FreeStrBuf(&con->MigrateBuf);
       FreeStrBuf(&con->RecvBuf.Buf);
       if (con->cached_msglist) {
              free(con->cached_msglist);
       }

       CONM_syslog(LOG_DEBUG, "Done with RemoveContext()");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void set_async_waiting ( struct CitContext ccptr)

Definition at line 678 of file context.c.

{
       CON_syslog(LOG_DEBUG, "Setting async_waiting flag for session %d\n", ccptr->cs_pid);
       if (ccptr->is_async) {
              ccptr->async_waiting++;
              if (ccptr->state == CON_IDLE) {
                     ccptr->state = CON_READY;
              }
       }
}

Here is the caller graph for this function:

void terminate_all_sessions ( void  )

Definition at line 310 of file context.c.

{
       CitContext *ccptr;
       int killed = 0;

       begin_critical_section(S_SESSION_TABLE);
       for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
              if (ccptr->client_socket != -1)
              {
                     CON_syslog(LOG_INFO, "terminate_all_sessions() is murdering %s", ccptr->curr_user);
                     close(ccptr->client_socket);
                     ccptr->client_socket = -1;
                     killed++;
              }
       }
       end_critical_section(S_SESSION_TABLE);
       if (killed > 0) {
              CON_syslog(LOG_INFO, "Flushed %d stuck sessions\n", killed);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void terminate_idle_sessions ( void  )

Definition at line 275 of file context.c.

{
       CitContext *ccptr;
       time_t now;
       int killed = 0;
       int longrunners = 0;

       now = time(NULL);
       begin_critical_section(S_SESSION_TABLE);
       for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
              if (
                     (ccptr != CC)
                     && (config.c_sleeping > 0)
                     && (now - (ccptr->lastcmd) > config.c_sleeping)
              ) {
                     if (!ccptr->dont_term) {
                            ccptr->kill_me = KILLME_IDLE;
                            ++killed;
                     }
                     else {
                            ++longrunners;
                     }
              }
       }
       end_critical_section(S_SESSION_TABLE);
       if (killed > 0)
              CON_syslog(LOG_INFO, "Scheduled %d idle sessions for termination\n", killed);
       if (longrunners > 0)
              CON_syslog(LOG_INFO, "Didn't terminate %d protected idle sessions", longrunners);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 93 of file context.c.

Definition at line 87 of file context.c.

Definition at line 92 of file context.c.

pthread_key_t MyConKey

Definition at line 89 of file context.c.

Definition at line 96 of file context.c.