/* $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
+ */
+
+#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.
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;
+ 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 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];
- THREAD mythread;
+ char net_node[32]; /* Is the client another Citadel server? */
int client_socket;
- int cs_pid; /* session ID */
- char cs_room[ROOMNAMELEN]; /* current room */
- 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 */
-
- /* 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;
- char upl_file[256];
- char upl_path[256];
- char upl_comment[256];
- char upl_filedir[256];
- char chat_room[20]; /* The chat room */
+ 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 */
- char fake_username[32]; /* Fake username <bc> */
- char fake_postname[32]; /* Fake postname <bc> */
- char fake_hostname[25]; /* Name of the fake hostname <bc> */
- char fake_roomname[ROOMNAMELEN];/* Name of the fake room <bc> */
+ /* Masquerade... */
+ char fake_username[USERNAME_SIZE]; /* Fake username <bc> */
+ char fake_postname[USERNAME_SIZE]; /* Fake postname <bc> */
+ char fake_hostname[25]; /* Fake hostname <bc> */
+ char fake_roomname[ROOMNAMELEN]; /* Fake roomname <bc> */
- int FloorBeingSearched; /* This is used by cmd_lrms() etc. */
- char desired_section[64]; /* This is used for MIME downloads */
- };
+ /* Dynamically allocated session data */
+ struct CtdlSessData *FirstSessData;
+};
typedef struct CitContext t_context;
-#define CS_STEALTH 1 /* stealth mode */
-#define CS_CHAT 2 /* chat mode */
-#define CS_POSTING 4 /* Posting */
+/* 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 struct CitContext *ContextList;
-extern int ScheduledShutdown;
-extern struct CitControl CitControl;
+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) */
- };
+ 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 */
+#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[256];
- char chat_room[20];
- char chat_username[32];
- };
+ char chat_text[SIZ];
+ char chat_username[USERNAME_SIZE];
+ char chat_room[ROOMNAMELEN];
+};
/*
* 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 S_DATABASE 10
-#define MAX_SEMAPHORES 11
+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,
+ MAX_SEMAPHORES
+};
/*
/*
* message transfer formats
*/
-#define MT_CITADEL 0 /* Citadel proprietary */
-#define MT_DATE 1 /* We're only looking for the date */
-#define MT_RFC822 2 /* RFC822 */
-#define MT_RAW 3 /* IGnet raw format */
-#define MT_MIME 4 /* MIME-formatted message */
-#define MT_DOWNLOAD 5 /* Download a component */
+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_VISIT 5 /* user/room relationships */
-#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 *next;
int loglevel;
void (*h_function_pointer) (char *);
- };
-extern struct LogFunctionHook *LogHookTable;
+};
+extern DLEXP struct LogFunctionHook *LogHookTable;
struct CleanupFunctionHook {
struct CleanupFunctionHook *next;
void (*h_function_pointer) (void);
- };
-extern struct CleanupFunctionHook *CleanupHookTable;
+};
+extern DLEXP struct CleanupFunctionHook *CleanupHookTable;
+
+
/*
struct SessionFunctionHook *next;
void (*h_function_pointer) (void);
int eventtype;
- };
-extern struct SessionFunctionHook *SessionHookTable;
+};
+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
struct UserFunctionHook *next;
void (*h_function_pointer) (char *username, long usernum);
int eventtype;
- };
-extern struct UserFunctionHook *UserHookTable;
+};
+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_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 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_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 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;
- };
+ struct TheHeap *next;
+ char h_file[32];
+ int h_line;
+ void *h_ptr;
+};
-extern struct TheHeap *heap;
+extern DLEXP struct TheHeap *heap;
#else
-#define mallok(howbig) malloc(howbig)
-#define phree(whichptr) free(whichptr)
+#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 */