Back to index

citadel  8.12
context.h
Go to the documentation of this file.
00001 
00002 #ifndef CONTEXT_H
00003 #define CONTEXT_H
00004 
00005 #include <stdarg.h>
00006 #include "sysdep.h"
00007 #include "server.h"
00008 #include "sysdep_decls.h"
00009 #include "threads.h"
00010 
00011 
00012 /*
00013  * Values for CitContext.state
00014  * 
00015  * A session that is doing nothing is in CON_IDLE state.  When activity
00016  * is detected on the socket, it goes to CON_READY, indicating that it
00017  * needs to have a worker thread bound to it.  When a thread binds to
00018  * the session, it goes to CON_EXECUTING and does its thing.  When the
00019  * transaction is finished, the thread sets it back to CON_IDLE and lets
00020  * it go.
00021  */
00022 typedef enum __CCState {
00023        CON_IDLE,            /* This context is doing nothing */
00024        CON_GREETING,        /* This context needs to output its greeting */
00025        CON_STARTING,        /* This context is outputting its greeting */
00026        CON_READY,           /* This context needs attention */
00027        CON_EXECUTING,              /* This context is bound to a thread */
00028        CON_SYS                 /* This is a system context and mustn't be purged */
00029 } CCState;
00030 
00031 
00032 /*
00033  * Here's the big one... the Citadel context structure.
00034  *
00035  * This structure keeps track of all information relating to a running 
00036  * session on the server.  We keep one of these for each session thread.
00037  *
00038  */
00039 struct CitContext {
00040        struct CitContext *prev;    /* Link to previous session in list */
00041        struct CitContext *next;    /* Link to next session in the list */
00042 
00043        int cs_pid;          /* session ID */
00044        int dont_term;              /* for special activities like artv so we don't get killed */
00045        double created;      /* time of birth */
00046        time_t lastcmd;             /* time of last command executed */
00047        time_t lastidle;     /* For computing idle time */
00048        CCState state;              /* thread state (see CON_ values below) */
00049        int kill_me;         /* Set to nonzero to flag for termination */
00050 
00051        IOBuffer SendBuf, /* Our write Buffer */
00052               RecvBuf, /* Our block buffered read buffer */
00053               SBuf; /* Our block buffered read buffer for clients */
00054 
00055        StrBuf *MigrateBuf;        /* Our block buffered read buffer */
00056        StrBuf *sMigrateBuf;        /* Our block buffered read buffer */
00057 
00058        int client_socket;
00059        int is_local_socket; /* set to 1 if client is on unix domain sock */
00060        /* Redirect this session's output to a memory buffer? */
00061        StrBuf *redirect_buffer;           /* the buffer */
00062        StrBuf *StatusMessage;
00063 #ifdef HAVE_OPENSSL
00064        SSL *ssl;
00065        int redirect_ssl;
00066 #endif
00067 
00068        char curr_user[USERNAME_SIZE];     /* name of current user */
00069        int logged_in;              /* logged in */
00070        int internal_pgm;    /* authenticated as internal program */
00071        int nologin;         /* not allowed to log in */
00072        int curr_view;              /* The view type for the current user/room */
00073        int is_master;              /* Is this session logged in using the master user? */
00074 
00075        char net_node[32]    ;/* Is the client another Citadel server? */
00076        time_t previous_login;      /* Date/time of previous login */
00077        char lastcmdname[5]; /* name of last command executed */
00078        unsigned cs_flags;   /* miscellaneous flags */
00079        int is_async;        /* Nonzero if client accepts async msgs */
00080        int async_waiting;   /* Nonzero if there are async msgs waiting */
00081        int input_waiting;   /* Nonzero if there is client input waiting */
00082        int can_receive_im;  /* Session is capable of receiving instant messages */
00083 
00084        /* Client information */
00085        int cs_clientdev;    /* client developer ID */
00086        int cs_clienttyp;    /* client type code */
00087        int cs_clientver;    /* client version number */
00088        char cs_clientinfo[256];/* if its a unix domain socket, some info for logging. */
00089        uid_t cs_UDSclientUID;  /* the uid of the client when talking via UDS */
00090        char cs_clientname[32];     /* name of client software */
00091        char cs_host[64];    /* host logged in from */
00092        char cs_addr[64];    /* address logged in from */
00093 
00094        /* The Internet type of thing */
00095        char cs_inet_email[128];           /* Return address of outbound Internet mail */
00096        char cs_inet_other_emails[1024];   /* User's other valid Internet email addresses */
00097        char cs_inet_fn[128];                     /* Friendly-name of outbound Internet mail */
00098 
00099        FILE *download_fp;   /* Fields relating to file transfer */
00100        size_t download_fp_total;
00101        char download_desired_section[128];
00102        FILE *upload_fp;
00103        char upl_file[256];
00104        char upl_path[PATH_MAX];
00105        char upl_comment[256];
00106        char upl_filedir[PATH_MAX];
00107        char upl_mimetype[64];
00108        char dl_is_net;
00109        char upload_type;
00110 
00111        struct ctdluser user;       /* Database record buffers */
00112        struct ctdlroom room;
00113 
00114        /* A linked list of all instant messages sent to us. */
00115        struct ExpressMessage *FirstExpressMessage;
00116        int disable_exp;     /* Set to 1 to disable incoming pages */
00117        int newmail;         /* Other sessions increment this */
00118 
00119        /* Masqueraded values in the 'who is online' list */
00120        char fake_username[USERNAME_SIZE];
00121        char fake_hostname[64];
00122        char fake_roomname[ROOMNAMELEN];
00123 
00124        /* Preferred MIME formats */
00125        char preferred_formats[256];
00126        int msg4_dont_decode;
00127 
00128        /* Dynamically allocated session data */
00129        char *session_specific_data;              /* Used by individual protocol modules */
00130        struct cit_ical *CIT_ICAL;         /* calendaring data */
00131        struct ma_info *ma;                /* multipart/alternative data */
00132        const char *ServiceName;           /* readable purpose of this session */
00133        long tcp_port;
00134        void *openid_data;                 /* Data stored by the OpenID module */
00135        char *ldap_dn;                            /* DN of user when using AUTHMODE_LDAP */
00136 
00137        void (*h_command_function) (void) ;       /* service command function */
00138        void (*h_async_function) (void) ;  /* do async msgs function */
00139        void (*h_greeting_function) (void) ;      /* greeting function for session startup */
00140 
00141        long *cached_msglist;                     /* results of the previous CtdlForEachMessage() */
00142        int cached_num_msgs;
00143 };
00144 
00145 typedef struct CitContext CitContext;
00146 
00147 
00148 #define CC MyContext()
00149 
00150 
00151 extern pthread_key_t MyConKey;                   /* TSD key for MyContext() */
00152 extern int num_sessions;
00153 extern CitContext masterCC;
00154 extern CitContext *ContextList;
00155 
00156 CitContext *MyContext (void);
00157 void RemoveContext (struct CitContext *);
00158 CitContext *CreateNewContext (void);
00159 void context_cleanup(void);
00160 void kill_session (int session_to_kill);
00161 void InitializeMasterCC(void);
00162 void dead_session_purge(int force);
00163 void set_async_waiting(struct CitContext *ccptr);
00164 
00165 CitContext *CloneContext(CitContext *CloneMe);
00166 
00167 /* forcibly close and flush fd's on shutdown */
00168 void terminate_all_sessions(void);
00169 
00170 /* Deprecated, user CtdlBumpNewMailCounter() instead */
00171 void BumpNewMailCounter(long) __attribute__ ((deprecated));
00172 
00173 void terminate_idle_sessions(void);
00174 int CtdlTerminateOtherSession (int session_num);
00175 /* bits returned by CtdlTerminateOtherSession */
00176 #define TERM_FOUND   0x01
00177 #define TERM_ALLOWED 0x02
00178 #define TERM_KILLED  0x03
00179 #define TERM_NOTALLOWED -1
00180 
00181 /*
00182  * Bind a thread to a context.  (It's inline merely to speed things up.)
00183  */
00184 static INLINE void become_session(CitContext *which_con) {
00185 /*
00186        pid_t tid = syscall(SYS_gettid);
00187 */
00188        pthread_setspecific(MyConKey, (void *)which_con );
00189 /*
00190        syslog(LOG_DEBUG, "[%d]: Now doing %s\n", 
00191                     (int) tid, 
00192                     ((which_con != NULL) && (which_con->ServiceName != NULL)) ? 
00193                     which_con->ServiceName:"");
00194 */
00195 }
00196 
00197 
00198 
00199 /* typedef void (*CtdlDbgFunction) (const int); */
00200 
00201 extern int DebugSession;
00202 #define CONDBGLOG(LEVEL) if ((LEVEL != LOG_DEBUG) || (DebugSession != 0))
00203 
00204 #define CON_syslog(LEVEL, FORMAT, ...)                         \
00205        CONDBGLOG(LEVEL) syslog(LEVEL,                          \
00206                             "Context: " FORMAT, __VA_ARGS__)
00207 
00208 #define CONM_syslog(LEVEL, FORMAT)               \
00209        CONDBGLOG(LEVEL) syslog(LEVEL,                   \
00210                             "Context: " FORMAT);
00211 
00212 
00213 #endif /* CONTEXT_H */