X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fserver.h;h=10a6f853bd1f8f0064236f54ef22d567338d8b0c;hb=2579891f090700c01844dff9a29e249eece3e529;hp=60becc03e383ec786231cc5c010228851a5f77ed;hpb=9550c03f491fdb2aaada8ddec438a9347be758d3;p=citadel.git diff --git a/citadel/server.h b/citadel/server.h index 60becc03e..10a6f853b 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -1,11 +1,44 @@ +/* $Id$ */ -typedef pthread_t THREAD; +/* Uncomment this if you want to track memory leaks. + * This incurs some overhead, so don't use it unless you're debugging the code! + */ +/* #define DEBUG_MEMORY_LEAKS */ + +/* + * New format for a message in memory + */ +#define CTDLMESSAGE_MAGIC 0x159d +struct CtdlMessage { + int cm_magic; /* Self-check */ + char cm_anon_type; /* Anonymous or author-visible */ + char cm_format_type; /* Format type */ + char *cm_fields[256]; /* Data fields */ + unsigned int cm_flags; /* How to handle (NOT SAVED TO DISK) */ +}; +#define CM_SKIP_HOOKS 0x01 /* Don't run server-side handlers */ + + +/* + * Generic per-session variable or data structure storage + */ +struct CtdlSessData { + struct CtdlSessData *next; + unsigned long sym_id; + void *sym_data; +}; + +/* + * Static user data symbol types + */ +enum { + SYM_DESIRED_SECTION, /* Used by the MIME parser */ + SYM_MA_INFO, /* Handles multipart/alternative */ + SYM_REPL, /* Used for replication checking */ + SYM_MAX +}; -struct ExpressMessage { - struct ExpressMessage *next; - char em_text[300]; - }; /* * Here's the big one... the Citadel context structure. @@ -19,62 +52,74 @@ struct ExpressMessage { struct CitContext { struct CitContext *next; /* Link to next session in the list */ - struct usersupp usersupp; /* Database record buffers */ - struct quickroom quickroom; - - long *msglist; - int num_msgs; - - char curr_user[32]; /* name of current user */ - int curr_rm; /* index of current room */ - int logged_in; /* logged in */ - int internal_pgm; /* authenticated as internal program */ - char temp[32]; /* temp file name */ - int nologin; /* not allowed to log in */ - - char net_node[32]; - THREAD mythread; + struct usersupp usersupp; /* Database record buffers */ + struct quickroom quickroom; + + int state; /* thread state (see CON_ values below) */ + int kill_me; /* Set to nonzero to flag for termination */ + + char curr_user[32]; /* name of current user */ + int logged_in; /* logged in */ + int internal_pgm; /* authenticated as internal program */ + char temp[32]; /* temp file name */ + int nologin; /* not allowed to log in */ + + char net_node[32]; /* Is the client another Citadel server? */ int client_socket; - struct ExpressMessage *FirstExpressMessage; - int cs_pid; /* session ID */ - char cs_room[20]; /* current room */ - long cs_lastupdt; /* time of last update */ - time_t lastcmd; /* time of last command executed */ - time_t lastidle; /* For computing idle time */ - char lastcmdname[5]; /* name of last command executed */ - unsigned cs_flags; /* miscellaneous flags */ - - /* feeping creaturisms... */ - int cs_clientdev; /* client developer ID */ - int cs_clienttyp; /* client type code */ - int cs_clientver; /* client version number */ - char cs_clientname[32]; /* name of client software */ - char cs_host[25]; /* host logged in from */ - - FILE *download_fp; /* Fields relating to file transfer */ - FILE *upload_fp; + int cs_pid; /* session ID */ + time_t cs_lastupdt; /* time of last update */ + time_t lastcmd; /* time of last command executed */ + time_t lastidle; /* For computing idle time */ + char lastcmdname[5]; /* name of last command executed */ + unsigned cs_flags; /* miscellaneous flags */ + void (*h_command_function) (void) ; /* service command function */ + + /* feeping creaturisms... */ + int cs_clientdev; /* client developer ID */ + int cs_clienttyp; /* client type code */ + int cs_clientver; /* client version number */ + char cs_clientname[32]; /* name of client software */ + char cs_host[26]; /* host logged in from */ + + FILE *download_fp; /* Fields relating to file transfer */ + FILE *upload_fp; char upl_file[256]; char upl_path[256]; char upl_comment[256]; char upl_filedir[256]; - char chat_room[20]; /* The chat room */ + char chat_room[20]; /* The chat room */ char dl_is_net; char upload_type; - char ucache_name[32]; /* For a performance boost, we cache */ - long ucache_pos; /* the position of the last user rec */ - char fake_username[32]; /* Fake username */ - char fake_postname[32]; /* Fake postname */ - char fake_hostname[25]; /* Name of the fake hostname */ - char fake_roomname[20]; /* Name of the fake room */ - char last_pager[32]; /* The username of the last pager */ + /* Redirect this session's output to somewhere else? */ + FILE *redirect_fp; + int redirect_sock; + + /* A linked list of all express messages sent to us. */ + struct ExpressMessage *FirstExpressMessage; + + /* Masquerade... */ + char fake_username[32]; /* Fake username */ + char fake_postname[32]; /* Fake postname */ + char fake_hostname[25]; /* Name of the fake hostname */ + char fake_roomname[ROOMNAMELEN]; /* Name of the fake room */ + + /* Dynamically allocated session data */ + struct CtdlSessData *FirstSessData; +}; + +typedef struct CitContext t_context; - int CtdlErrno; /* Error return for CitadelAPI calls */ - }; +/* Values for CitContext.state */ +enum { + CON_IDLE, /* This context is doing nothing */ + 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 */ + +#define CS_STEALTH 1 /* stealth mode */ +#define CS_CHAT 2 /* chat mode */ +#define CS_POSTING 4 /* Posting */ struct CitContext *MyContext(void); #define CC ((struct CitContext *)MyContext()) @@ -83,6 +128,19 @@ extern struct CitContext *ContextList; extern int ScheduledShutdown; extern struct CitControl CitControl; + +struct ExpressMessage { + struct ExpressMessage *next; + time_t timestamp; /* When this message was sent */ + unsigned flags; /* Special instructions */ + char sender[64]; /* Name of sending user */ + char *text; /* Message text (if applicable) */ +}; + +#define EM_BROADCAST 1 /* Broadcast message */ +#define EM_GO_AWAY 2 /* Server requests client log off */ +#define EM_CHAT 4 /* Server requests client enter chat */ + struct ChatLine { struct ChatLine *next; int chat_seq; @@ -90,22 +148,29 @@ struct ChatLine { char chat_text[256]; char chat_room[20]; char chat_username[32]; - }; +}; /* * Various things we need to lock and unlock */ -#define S_USERSUPP 0 -#define S_USER_TRANS 1 -#define S_QUICKROOM 2 -#define S_MSGMAIN 3 -#define S_CALLLOG 4 -#define S_SESSION_TABLE 5 -#define S_FLOORTAB 6 -#define S_CHATQUEUE 7 -#define S_CONTROL 8 -#define S_HOUSEKEEPING 9 -#define MAX_SEMAPHORES 10 +enum { + S_USERSUPP, + S_USER_TRANS, + S_QUICKROOM, + S_MSGMAIN, + S_CALLLOG, + S_SESSION_TABLE, + S_FLOORTAB, + S_CHATQUEUE, + S_CONTROL, + S_HOUSEKEEPING, + S_DATABASE, + S_NETDB, + S_SUPPMSGMAIN, + S_I_WANNA_SELECT, + S_CONFIG, + MAX_SEMAPHORES +}; /* @@ -116,19 +181,239 @@ struct ChatLine { #define UPL_IMAGE 2 +/* + * message transfer formats + */ +enum { + MT_CITADEL, /* Citadel proprietary */ + MT_RFC822, /* RFC822 */ + MT_MIME, /* MIME-formatted message */ + MT_DOWNLOAD /* Download a component */ +}; + +/* + * Message format types in the database + */ +#define FMT_CITADEL 0 /* Citadel vari-format (proprietary) */ +#define FMT_FIXED 1 /* Fixed format (proprietary) */ +#define FMT_RFC822 4 /* Standard (headers are in M field) */ + /* * Citadel DataBases (define one for each cdb we need to open) */ -#define CDB_MSGMAIN 0 /* message base */ -#define CDB_USERSUPP 1 /* user file */ -#define CDB_QUICKROOM 2 /* room index */ -#define CDB_FLOORTAB 3 /* floor index */ -#define CDB_MSGLISTS 4 /* room message lists */ -#define CDB_MAILBOXES 5 /* mailbox message lists */ -#define MAXCDB 6 /* total number of CDB's defined */ +enum { + CDB_MSGMAIN, /* message base */ + CDB_USERSUPP, /* user file */ + CDB_QUICKROOM, /* room index */ + CDB_FLOORTAB, /* floor index */ + CDB_MSGLISTS, /* room message lists */ + CDB_VISIT, /* user/room relationships */ + MAXCDB /* total number of CDB's defined */ +}; struct cdbdata { size_t len; char *ptr; - }; +}; + + + +/* Structures and declarations for function hooks of various types */ + +struct LogFunctionHook { + struct LogFunctionHook *next; + int loglevel; + void (*h_function_pointer) (char *); +}; +extern struct LogFunctionHook *LogHookTable; + +struct CleanupFunctionHook { + struct CleanupFunctionHook *next; + void (*h_function_pointer) (void); +}; +extern struct CleanupFunctionHook *CleanupHookTable; + + + + +/* + * SessionFunctionHook extensions are used for any type of hook for which + * the context in which it's being called (which is determined by the event + * type) will make it obvious for the hook function to know where to look for + * pertinent data. + */ +struct SessionFunctionHook { + struct SessionFunctionHook *next; + void (*h_function_pointer) (void); + int eventtype; +}; +extern struct SessionFunctionHook *SessionHookTable; + +/* + * Event types can't be enum'ed, because they must remain consistent between + * builds (to allow for binary modules built somewhere else) + */ +#define EVT_STOP 0 /* Session is terminating */ +#define EVT_START 1 /* Session is starting */ +#define EVT_LOGIN 2 /* A user is logging in */ +#define EVT_NEWROOM 3 /* Changing rooms */ +#define EVT_LOGOUT 4 /* A user is logging out */ +#define EVT_SETPASS 5 /* Setting or changing password */ +#define EVT_CMD 6 /* Called after each server command */ +#define EVT_RWHO 7 /* An RWHO command is being executed */ + + +#define EVT_TIMER 50 /* Timer events are called once per minute + and are not tied to any session */ + +/* + * UserFunctionHook extensions are used for any type of hook which implements + * an operation on a user or username (potentially) other than the one + * operating the current session. + */ +struct UserFunctionHook { + struct UserFunctionHook *next; + void (*h_function_pointer) (char *username, long usernum); + int eventtype; +}; +extern struct UserFunctionHook *UserHookTable; + +#define EVT_PURGEUSER 100 /* Deleting a user */ +#define EVT_OUTPUTMSG 101 /* Outputting a message */ + + +/* + * MessageFunctionHook extensions are used for hooks which implement handlers + * for various types of message operations (save, read, etc.) + */ +struct MessageFunctionHook { + struct MessageFunctionHook *next; + int (*h_function_pointer) (struct CtdlMessage *msg); + int eventtype; +}; +extern struct MessageFunctionHook *MessageHookTable; + +#define EVT_BEFOREREAD 200 +#define EVT_BEFORESAVE 201 +#define EVT_AFTERSAVE 202 + + +/* + * ExpressMessageFunctionHook extensions are used for hooks which implement + * the sending of an express message through various channels. Any function + * registered should return the number of recipients to whom the message was + * successfully transmitted. + */ +struct XmsgFunctionHook { + struct XmsgFunctionHook *next; + int (*h_function_pointer) (char *, char *, char *); + int order; +}; +extern struct XmsgFunctionHook *XmsgHookTable; + +/* Priority levels for paging functions (lower is better) */ +enum { + XMSG_PRI_LOCAL, /* Other users on -this- server */ + XMSG_PRI_REMOTE, /* Other users on a Citadel network (future) */ + XMSG_PRI_FOREIGN, /* Contacts on foreign instant message hosts */ + MAX_XMSG_PRI +}; + + + +/* + * ServiceFunctionHook extensions are used for hooks which implement various + * non-Citadel services (on TCP protocols) directly in the Citadel server. + */ +struct ServiceFunctionHook { + struct ServiceFunctionHook *next; + int tcp_port; + void (*h_greeting_function) (void) ; + void (*h_command_function) (void) ; + int msock; +}; +extern struct ServiceFunctionHook *ServiceHookTable; + + + +/* Defines the relationship of a user to a particular room */ +struct visit { + long v_roomnum; + long v_roomgen; + long v_usernum; + long v_lastseen; + unsigned int v_flags; +}; + +#define V_FORGET 1 /* User has zapped this room */ +#define V_LOCKOUT 2 /* User is locked out of this room */ +#define V_ACCESS 4 /* Access is granted to this room */ + +#define UA_KNOWN 2 +#define UA_GOTOALLOWED 4 +#define UA_HASNEWMSGS 8 +#define UA_ZAPPED 16 + + +/* Supplementary data for a message on disk + * (These are kept separately from the message itself because they are + * fields whose values may change at some point after the message is saved.) + */ +struct SuppMsgInfo { + long smi_msgnum; /* Message number in *local* message base */ + int smi_refcount; /* Number of rooms which point to this msg */ + char smi_content_type[64]; + /* more stuff will be added to this record in the future */ +}; + + + +/* Built-in debuggable stuff for checking for memory leaks */ +#ifdef DEBUG_MEMORY_LEAKS + +#define mallok(howbig) tracked_malloc(howbig, __FILE__, __LINE__) +#define phree(whichptr) tracked_free(whichptr) +#define reallok(whichptr,howbig) tracked_realloc(whichptr,howbig) +#define strdoop(orig) tracked_strdup(orig, __FILE__, __LINE__) + +void *tracked_malloc(size_t, char *, int); +void tracked_free(void *); +void *tracked_realloc(void *, size_t); +void dump_tracked(void); +char *tracked_strdup(const char *, char *, int); + +struct TheHeap { + struct TheHeap *next; + char h_file[32]; + int h_line; + void *h_ptr; +}; + +extern struct TheHeap *heap; + +#else + +#define mallok(howbig) malloc(howbig) +#define phree(whichptr) free(whichptr) +#define reallok(whichptr,howbig) realloc(whichptr,howbig) +#define strdoop(orig) strdup(orig) + + +#endif + + +/* + * Serialization routines use this struct to return a pointer and a length + */ +struct ser_ret { + size_t len; + char *ser; +}; + + +/* Preferred field order */ +/* ********** Important fields */ +/* *************** Semi-important fields */ +/* * Message text (MUST be last) */ +#define FORDER "IPTAFONHRDBCEGJKLQSUVWXYZM"