we will make this configureable later.
Also some cleanups in the CitContext stuff to make it a bit more readable
though I thought I had already committed those :-(
* user also knows the rooms.
*/
void GenerateRoomDisplay(char *real_room,
- struct CitContext *viewed,
- struct CitContext *viewer) {
+ CitContext *viewed,
+ CitContext *viewer) {
int ra;
void cmd_term(char *cmdbuf)
{
int session_num;
- struct CitContext *ccptr;
+ CitContext *ccptr;
int found_it = 0;
int allowed = 0;
* RFC 1725 et al specify a PID to be placed in front of the nonce.
* Quoth BTX: That would be stupid.
*/
-void generate_nonce(struct CitContext *con) {
+void generate_nonce(CitContext *con) {
struct timeval tv;
memset(con->cs_nonce, NONCE_SIZE, 0);
/*
* Back-end function for starting a session
*/
-void begin_session(struct CitContext *con)
+void begin_session(CitContext *con)
{
socklen_t len;
struct sockaddr_in sin;
*/
#include "serv_extensions.h"
+#include "context.h"
/* Simple linked list structures ... used in a bunch of different places. */
struct RoomProcList {
void begin_session(struct CitContext *con);
void citproto_begin_session(void);
void GenerateRoomDisplay(char *real_room,
- struct CitContext *viewed,
- struct CitContext *viewer);
+ CitContext *viewed,
+ CitContext *viewer);
extern int panic_fd;
char CtdlCheckExpress(void);
citthread_key_t MyConKey; /* TSD key for MyContext() */
-struct CitContext masterCC;
-struct CitContext *ContextList = NULL;
-// struct CitContext* next_session = NULL;
+CitContext masterCC;
+CitContext *ContextList = NULL;
time_t last_purge = 0; /* Last dead session purge */
int num_sessions = 0; /* Current number of sessions */
*
* This function is used *VERY* frequently and must be kept small.
*/
-struct CitContext *MyContext(void) {
+CitContext *MyContext(void) {
- register struct CitContext *c;
+ register CitContext *c;
- return ((c = (struct CitContext *) citthread_getspecific(MyConKey),
+ return ((c = (CitContext *) citthread_getspecific(MyConKey),
c == NULL) ? &masterCC : c
);
}
/*
* Terminate a session.
*/
-void RemoveContext (struct CitContext *con)
+void RemoveContext (CitContext *con)
{
if (con==NULL) {
CtdlLogPrintf(CTDL_ERR,
-
/*
* Initialize a new context and place it in the list. The session number
* used to be the PID (which is why it's called cs_pid), but that was when we
* had one process per session. Now we just assign them sequentially, starting
* at 1 (don't change it to 0 because masterCC uses 0).
*/
-struct CitContext *CreateNewContext(void) {
- struct CitContext *me;
+CitContext *CreateNewContext(void) {
+ CitContext *me;
static int next_pid = 0;
- me = (struct CitContext *) malloc(sizeof(struct CitContext));
+ me = (CitContext *) malloc(sizeof(CitContext));
if (me == NULL) {
CtdlLogPrintf(CTDL_ALERT, "citserver: can't allocate memory!!\n");
return NULL;
}
-
- memset(me, 0, sizeof(struct CitContext));
+ memset(me, 0, sizeof(CitContext));
/* Give the contaxt a name. Hopefully makes it easier to track */
strcpy (me->user.fullname, "SYS_notauth");
}
-struct CitContext *CtdlGetContextArray(int *count)
+CitContext *CtdlGetContextArray(int *count)
{
int nContexts, i;
- struct CitContext *nptr, *cptr;
+ CitContext *nptr, *cptr;
nContexts = num_sessions;
- nptr = malloc(sizeof(struct CitContext) * nContexts);
+ nptr = malloc(sizeof(CitContext) * nContexts);
if (!nptr)
return NULL;
begin_critical_section(S_SESSION_TABLE);
for (cptr = ContextList, i=0; cptr != NULL && i < nContexts; cptr = cptr->next, i++)
- memcpy(&nptr[i], cptr, sizeof (struct CitContext));
+ memcpy(&nptr[i], cptr, sizeof (CitContext));
end_critical_section (S_SESSION_TABLE);
*count = i;
* This function fills in a context and its user field correctly
* Then creates/loads that user
*/
-void CtdlFillSystemContext(struct CitContext *context, char *name)
+void CtdlFillSystemContext(CitContext *context, char *name)
{
char sysname[USERNAME_SIZE];
- memset(context, 0, sizeof(struct CitContext));
+ memset(context, 0, sizeof(CitContext));
context->internal_pgm = 1;
context->cs_pid = 0;
strcpy (sysname, "SYS_");
*/
void context_cleanup(void)
{
- struct CitContext *ptr = NULL;
- struct CitContext *rem = NULL;
+ CitContext *ptr = NULL;
+ CitContext *rem = NULL;
/*
* Clean up the contexts.
* no longer does anything that is system-dependent.)
*/
void kill_session(int session_to_kill) {
- struct CitContext *ptr;
+ CitContext *ptr;
begin_critical_section(S_SESSION_TABLE);
for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
* anyway, set "force" to nonzero.
*/
void dead_session_purge(int force) {
- struct CitContext *ptr, *ptr2; /* general-purpose utility pointer */
- struct CitContext *rem = NULL; /* list of sessions to be destroyed */
+ 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 ) {
* function initializes it.
*/
void InitializeMasterCC(void) {
- memset(&masterCC, 0, sizeof(struct CitContext));
+ memset(&masterCC, 0, sizeof( CitContext));
masterCC.internal_pgm = 1;
masterCC.cs_pid = 0;
}
/*
* Bind a thread to a context. (It's inline merely to speed things up.)
*/
-INLINE void become_session(struct CitContext *which_con) {
+INLINE void become_session(CitContext *which_con) {
citthread_setspecific(MyConKey, (void *)which_con );
}
#include "threads.h"
+/*
+ * Here's the big one... the Citadel context structure.
+ *
+ * This structure keeps track of all information relating to a running
+ * session on the server. We keep one of these for each session thread.
+ *
+ */
+struct CitContext {
+ struct CitContext *prev; /* Link to previous session in list */
+ struct CitContext *next; /* Link to next session in the list */
+
+ int state; /* thread state (see CON_ values below) */
+ int kill_me; /* Set to nonzero to flag for termination */
+ int client_socket;
+ int cs_pid; /* session ID */
+ int dont_term; /* for special activities like artv so we don't get killed */
+ time_t lastcmd; /* time of last command executed */
+ time_t lastidle; /* For computing idle time */
+
+ char curr_user[USERNAME_SIZE]; /* name of current user */
+ int logged_in; /* logged in */
+ int internal_pgm; /* authenticated as internal program */
+ int nologin; /* not allowed to log in */
+ int is_local_socket; /* set to 1 if client is on unix domain sock */
+ int curr_view; /* The view type for the current user/room */
+ int is_master; /* Is this session logged in using the master user? */
+
+ char net_node[32] ;/* Is the client another Citadel server? */
+ time_t previous_login; /* Date/time of previous login */
+ char lastcmdname[5]; /* name of last command executed */
+ unsigned cs_flags; /* miscellaneous flags */
+ void (*h_command_function) (void) ; /* service command function */
+ void (*h_async_function) (void) ; /* do async msgs function */
+ int is_async; /* Nonzero if client accepts async msgs */
+ int async_waiting; /* Nonzero if there are async msgs waiting */
+ int input_waiting; /* Nonzero if there is client input waiting */
+ int can_receive_im; /* Session is capable of receiving instant messages */
+
+ /* Client information */
+ int cs_clientdev; /* client developer ID */
+ int cs_clienttyp; /* client type code */
+ int cs_clientver; /* client version number */
+ uid_t cs_UDSclientUID; /* the uid of the client when talking via UDS */
+ char cs_clientname[32]; /* name of client software */
+ char cs_host[64]; /* host logged in from */
+ char cs_addr[64]; /* address logged in from */
+
+ /* The Internet type of thing */
+ char cs_inet_email[128]; /* Return address of outbound Internet mail */
+ char cs_inet_other_emails[1024]; /* User's other valid Internet email addresses */
+ char cs_inet_fn[128]; /* Friendly-name of outbound Internet mail */
+
+ FILE *download_fp; /* Fields relating to file transfer */
+ char download_desired_section[128];
+ FILE *upload_fp;
+ char upl_file[256];
+ char upl_path[PATH_MAX];
+ char upl_comment[256];
+ char upl_filedir[PATH_MAX];
+ char upl_mimetype[64];
+ char dl_is_net;
+ char upload_type;
+
+ struct ctdluser user; /* Database record buffers */
+ struct ctdlroom room;
+
+ /* Beginning of cryptography - session nonce */
+ char cs_nonce[NONCE_SIZE]; /* The nonce for this session's next auth transaction */
+
+ /* Redirect this session's output to a memory buffer? */
+ char *redirect_buffer; /* the buffer */
+ size_t redirect_len; /* length of data in buffer */
+ size_t redirect_alloc; /* length of allocated buffer */
+#ifdef HAVE_OPENSSL
+ SSL *ssl;
+ int redirect_ssl;
+#endif
+
+ /* A linked list of all instant messages sent to us. */
+ struct ExpressMessage *FirstExpressMessage;
+ int disable_exp; /* Set to 1 to disable incoming pages */
+ int newmail; /* Other sessions increment this */
+
+ /* Masqueraded values in the 'who is online' list */
+ char fake_username[USERNAME_SIZE];
+ char fake_hostname[64];
+ char fake_roomname[ROOMNAMELEN];
+
+ /* Preferred MIME formats */
+ char preferred_formats[256];
+ int msg4_dont_decode;
+
+ /* Dynamically allocated session data */
+ char *session_specific_data; /* Used by individual protocol modules */
+ struct cit_ical *CIT_ICAL; /* calendaring data */
+ struct ma_info *ma; /* multipart/alternative data */
+ const char *ServiceName; /* readable purpose of this session */
+ void *openid_data; /* Data stored by the OpenID module */
+ char *ldap_dn; /* DN of user when using AUTHMODE_LDAP */
+};
+
+typedef struct CitContext CitContext;
+
+/*
+ * Values for CitContext.state
+ *
+ * A session that is doing nothing is in CON_IDLE state. When activity
+ * is detected on the socket, it goes to CON_READY, indicating that it
+ * needs to have a worker thread bound to it. When a thread binds to
+ * the session, it goes to CON_EXECUTING and does its thing. When the
+ * transaction is finished, the thread sets it back to CON_IDLE and lets
+ * it go.
+ */
+enum {
+ CON_IDLE, /* This context is doing nothing */
+ CON_READY, /* This context needs attention */
+ CON_EXECUTING /* This context is bound to a thread */
+};
+
+#define CC MyContext()
+
+
extern citthread_key_t MyConKey; /* TSD key for MyContext() */
extern int num_sessions;
-extern struct CitContext masterCC;
+extern CitContext masterCC;
+extern CitContext *ContextList;
-struct CitContext *MyContext (void);
+CitContext *MyContext (void);
void RemoveContext (struct CitContext *);
-struct CitContext *CreateNewContext (void);
+CitContext *CreateNewContext (void);
void context_cleanup(void);
void kill_session (int session_to_kill);
INLINE void become_session(struct CitContext *which_con);
/*
* abort an upload
*/
-void abort_upl(struct CitContext *who)
+void abort_upl(CitContext *who)
{
if (who->upload_fp != NULL) {
fclose(who->upload_fp);
/* $Id$ */
+#ifndef FILE_OPS_H
+#define FILE_OPS_H
+
+#include "context.h"
+
void OpenCmdResult (char *, const char *);
-void abort_upl (struct CitContext *who);
+void abort_upl (CitContext *who);
int network_talking_to(char *nodename, int operation);
NTT_REMOVE,
NTT_CHECK
};
+
+#endif /* FILE_OPS_H */
\ No newline at end of file
* beginning because the pointer to our place in the list becomes invalid.
*/
void terminate_idle_sessions(void) {
- struct CitContext *ccptr;
+ CitContext *ccptr;
time_t now;
int session_to_kill;
int killed = 0;
#include "sysdep_decls.h"
#include "config.h"
#include "domain.h"
+#include "context.h"
#include "ctdl_module.h"
#ifdef HAVE_RESOLV_H
struct addresses_to_be_filed *aptr = NULL;
char *saved_rfc822_version = NULL;
int qualified_for_journaling = 0;
- struct CitContext *CCC = CC; /* CachedCitContext - performance boost */
+ CitContext *CCC = CC; /* CachedCitContext - performance boost */
char bounce_to[1024] = "";
size_t tmp = 0;
int rv = 0;
-/*
- * Here's the big one... the Citadel context structure.
- *
- * This structure keeps track of all information relating to a running
- * session on the server. We keep one of these for each session thread.
- *
- */
-struct CitContext {
- struct CitContext *prev; /* Link to previous session in list */
- struct CitContext *next; /* Link to next session in the list */
-
- int state; /* thread state (see CON_ values below) */
- int kill_me; /* Set to nonzero to flag for termination */
- int client_socket;
- int cs_pid; /* session ID */
- int dont_term; /* for special activities like artv so we don't get killed */
- time_t lastcmd; /* time of last command executed */
- time_t lastidle; /* For computing idle time */
-
- char curr_user[USERNAME_SIZE]; /* name of current user */
- int logged_in; /* logged in */
- int internal_pgm; /* authenticated as internal program */
- int nologin; /* not allowed to log in */
- int is_local_socket; /* set to 1 if client is on unix domain sock */
- int curr_view; /* The view type for the current user/room */
- int is_master; /* Is this session logged in using the master user? */
-
- char net_node[32] ;/* Is the client another Citadel server? */
- time_t previous_login; /* Date/time of previous login */
- char lastcmdname[5]; /* name of last command executed */
- unsigned cs_flags; /* miscellaneous flags */
- void (*h_command_function) (void) ; /* service command function */
- void (*h_async_function) (void) ; /* do async msgs function */
- int is_async; /* Nonzero if client accepts async msgs */
- int async_waiting; /* Nonzero if there are async msgs waiting */
- int input_waiting; /* Nonzero if there is client input waiting */
- int can_receive_im; /* Session is capable of receiving instant messages */
-
- /* Client information */
- int cs_clientdev; /* client developer ID */
- int cs_clienttyp; /* client type code */
- int cs_clientver; /* client version number */
- uid_t cs_UDSclientUID; /* the uid of the client when talking via UDS */
- char cs_clientname[32]; /* name of client software */
- char cs_host[64]; /* host logged in from */
- char cs_addr[64]; /* address logged in from */
-
- /* The Internet type of thing */
- char cs_inet_email[128]; /* Return address of outbound Internet mail */
- char cs_inet_other_emails[1024]; /* User's other valid Internet email addresses */
- char cs_inet_fn[128]; /* Friendly-name of outbound Internet mail */
-
- FILE *download_fp; /* Fields relating to file transfer */
- char download_desired_section[128];
- FILE *upload_fp;
- char upl_file[256];
- char upl_path[PATH_MAX];
- char upl_comment[256];
- char upl_filedir[PATH_MAX];
- char upl_mimetype[64];
- char dl_is_net;
- char upload_type;
-
- struct ctdluser user; /* Database record buffers */
- struct ctdlroom room;
-
- /* Beginning of cryptography - session nonce */
- char cs_nonce[NONCE_SIZE]; /* The nonce for this session's next auth transaction */
-
- /* Redirect this session's output to a memory buffer? */
- char *redirect_buffer; /* the buffer */
- size_t redirect_len; /* length of data in buffer */
- size_t redirect_alloc; /* length of allocated buffer */
-#ifdef HAVE_OPENSSL
- SSL *ssl;
- int redirect_ssl;
-#endif
-
- /* A linked list of all instant messages sent to us. */
- struct ExpressMessage *FirstExpressMessage;
- int disable_exp; /* Set to 1 to disable incoming pages */
- int newmail; /* Other sessions increment this */
-
- /* Masqueraded values in the 'who is online' list */
- char fake_username[USERNAME_SIZE];
- char fake_hostname[64];
- char fake_roomname[ROOMNAMELEN];
-
- /* Preferred MIME formats */
- char preferred_formats[256];
- int msg4_dont_decode;
-
- /* Dynamically allocated session data */
- char *session_specific_data; /* Used by individual protocol modules */
- struct cit_ical *CIT_ICAL; /* calendaring data */
- struct ma_info *ma; /* multipart/alternative data */
- const char *ServiceName; /* readable purpose of this session */
- void *openid_data; /* Data stored by the OpenID module */
- char *ldap_dn; /* DN of user when using AUTHMODE_LDAP */
-};
-
-typedef struct CitContext t_context;
-
-/*
- * Values for CitContext.state
- *
- * A session that is doing nothing is in CON_IDLE state. When activity
- * is detected on the socket, it goes to CON_READY, indicating that it
- * needs to have a worker thread bound to it. When a thread binds to
- * the session, it goes to CON_EXECUTING and does its thing. When the
- * transaction is finished, the thread sets it back to CON_IDLE and lets
- * it go.
- */
-enum {
- CON_IDLE, /* This context is doing nothing */
- CON_READY, /* This context needs attention */
- CON_EXECUTING /* This context is bound to a thread */
-};
-
-
#define CS_STEALTH 1 /* stealth mode */
#define CS_CHAT 2 /* chat mode */
#define CS_POSTING 4 /* Posting */
-struct CitContext *MyContext(void);
-#define CC MyContext()
/*
* This is the control record for the message base...
int MMdbversion; /* Version of Berkeley DB used on previous server run */
};
-extern struct CitContext *ContextList;
extern int ScheduledShutdown;
extern struct CitControl CitControl;
struct timeval tv;
struct tm tim;
time_t unixtime;
- struct CitContext *CCC = CC;
+ CitContext *CCC = CC;
gettimeofday(&tv, NULL);
/* Promote to time_t; types differ on some OSes (like darwin) */
int old_buffer_len = 0;
#endif
fd_set wset;
- t_context *Ctx;
+ CitContext *Ctx;
int fdflags;
Ctx = CC;
void *worker_thread(void *arg) {
int i;
int highest;
- struct CitContext *ptr;
- struct CitContext *bind_me = NULL;
+ CitContext *ptr;
+ CitContext *bind_me = NULL;
fd_set readfds;
int retval = 0;
- struct CitContext *con= NULL; /* Temporary context pointer */
+ CitContext *con= NULL; /* Temporary context pointer */
struct ServiceFunctionHook *serviceptr;
int ssock; /* Descriptor for client socket */
struct timeval tv;
CtdlThreadNode *last_worker;
struct timeval start, now, result;
double last_duration;
-
+
/*
* Initialise the thread system
*/
#endif /* NEW_WORKER */
{
/* Only start new threads if we are not going to overload the machine */
- if (CtdlThreadGetLoadAvg() < ((double)1.00)) {
+ /* Temporarily set to 10 should be enough to make sure we don't stranglew the server
+ * at least until we make this a config option */
+ if (CtdlThreadGetLoadAvg() < ((double)10.00)) {
for (i=0; i<5 ; i++) {
#ifdef NEW_WORKER
CtdlThreadCreate("Worker Thread (new)",
int m, i;
int retval = 0;
struct timeval tv;
- struct CitContext *con;
+ CitContext *con;
const char *old_name;
* If the select succeeds the thread goes off to handle the client request.
* If the list of client connections is empty the threads all sleep for one second
*/
-struct CitContext *select_on_client(void)
+CitContext *select_on_client(void)
{
fd_set readfds;
struct timeval tv;
/*
* Do the worker threads work when needed
*/
-int execute_session(struct CitContext *bind_me)
+int execute_session(CitContext *bind_me)
{
int force_purge;
void *new_worker_thread(void *arg)
{
- struct CitContext *bind_me;
+ CitContext *bind_me;
int force_purge;
while (!CtdlThreadCheckStop()) {
#include "genstamp.h"
#include "threads.h"
#include "citadel_ldap.h"
+#include "context.h"
#include "ctdl_module.h"
*
*/
int rename_user(char *oldname, char *newname) {
- struct CitContext *cptr;
+ CitContext *cptr;
int retcode = RENAMEUSER_OK;
struct ctdluser usbuf;
char newnamekey[USERNAME_SIZE];
/* We cannot rename a user who is currently logged in */
+/* FIXME: This is very broken!!!!
+ * We check that the user is not already logged in because we can't rename them
+ * if they are logged in.
+ * BUT THEN WE LEAVE A HUGE WINDOW FOR THEM TO LOG IN BEFORE WE LOCK TO RENAME THEM!!!!!
+ */
for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
if (!strcasecmp(cptr->user.fullname, oldname)) {
return(RENAMEUSER_LOGGED_IN);
*/
void logout(void)
{
- struct CitContext *CCC = CC; /* CachedCitContext - performance boost */
+ CitContext *CCC = CC; /* CachedCitContext - performance boost */
/*
* If there is a download in progress, abort it.
*/
char filename[64];
struct ctdluser usbuf;
char usernamekey[USERNAME_SIZE];
- struct CitContext *ccptr;
+ CitContext *ccptr;
int user_is_logged_in = 0;
makeuserkey(usernamekey, pname);
* receive a new mail notification without having to hit the database.
*/
void BumpNewMailCounter(long which_user) {
- struct CitContext *ptr;
+ CitContext *ptr;
begin_critical_section(S_SESSION_TABLE);