/* $Id$ */ /* 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 */ #ifndef SERVER_H #define SERVER_H #ifdef __CYGWIN__ #ifdef IN_LIBCIT #define DLEXP __declspec(dllexport) #else #define DLEXP __declspec(dllimport) #endif #else #define DLEXP #endif /* __CYGWIN__ */ #include "citadel.h" #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 }; /* * 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. * * Note that the first element is "*next" so that it may be used without * modification in a linked list. */ struct CitContext { struct CitContext *next; /* Link to next session in the list */ 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[USERNAME_SIZE]; /* 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 */ int is_local_socket; /* set to 1 if client is on unix domain sock */ char net_node[32]; /* Is the client another Citadel server? */ int client_socket; 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 */ int is_async; /* Nonzero if client accepts async msgs */ /* 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 */ /* Beginning of cryptography - session nonce */ char cs_nonce[NONCE_SIZE]; /* The nonce for this session's next auth transaction */ FILE *download_fp; /* Fields relating to file transfer */ FILE *upload_fp; char upl_file[SIZ]; char upl_path[SIZ]; char upl_comment[SIZ]; char upl_filedir[SIZ]; char dl_is_net; char upload_type; /* 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; int disable_exp; /* Set to 1 to disable incoming pages */ /* Masquerade... */ char fake_username[USERNAME_SIZE]; /* Fake username */ char fake_postname[USERNAME_SIZE]; /* Fake postname */ char fake_hostname[25]; /* Fake hostname */ char fake_roomname[ROOMNAMELEN]; /* Fake roomname */ /* Dynamically allocated session data */ struct CtdlSessData *FirstSessData; }; typedef struct CitContext t_context; /* 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 */ struct CitContext *MyContext(void); #define CC ((struct CitContext *)MyContext()) extern DLEXP struct CitContext *ContextList; extern DLEXP int ScheduledShutdown; extern DLEXP 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; time_t chat_time; char chat_text[SIZ]; char chat_username[USERNAME_SIZE]; char chat_room[ROOMNAMELEN]; }; /* * Various things we need to lock and unlock */ enum { S_USERSUPP, S_QUICKROOM, S_SESSION_TABLE, S_FLOORTAB, S_CHATQUEUE, S_CONTROL, S_DATABASE, S_NETDB, S_SUPPMSGMAIN, S_I_WANNA_SELECT, S_CONFIG, S_WORKER_LIST, S_HOUSEKEEPING, S_NTTLIST, MAX_SEMAPHORES }; /* * Upload types */ #define UPL_FILE 0 #define UPL_NET 1 #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) */ 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 DLEXP struct LogFunctionHook *LogHookTable; struct CleanupFunctionHook { struct CleanupFunctionHook *next; void (*h_function_pointer) (void); }; extern DLEXP 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 DLEXP 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 DLEXP 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 DLEXP 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 DLEXP 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; char *sockpath; void (*h_greeting_function) (void) ; void (*h_command_function) (void) ; int msock; }; extern DLEXP 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; char v_seen[SIZ]; }; #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]; char smi_mod; /* Moderated to what level? */ /* 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 DLEXP 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" #endif /* SERVER_H */