}
+/*
+ * Free any per-session data allocated by modules or whatever
+ */
+void deallocate_user_data(struct CitContext *con)
+{
+ struct CtdlSessData *ptr;
+
+ begin_critical_section(S_SESSION_TABLE);
+ while (con->FirstSessData != NULL) {
+ lprintf(9, "Deallocating user data symbol %ld\n",
+ con->FirstSessData->sym_id);
+ if (con->FirstSessData->sym_data != NULL)
+ phree(con->FirstSessData->sym_data);
+ ptr = con->FirstSessData->next;
+ phree(con->FirstSessData);
+ con->FirstSessData = ptr;
+ }
+ end_critical_section(S_SESSION_TABLE);
+}
+
+
+
+
/*
* Gracefully terminate the session and thread.
* (This is called as a cleanup handler by the thread library.)
/* Deallocate any message list we might have in memory */
if (CC->msglist != NULL) phree(CC->msglist);
+ /* Deallocate any user-data attached to this session */
+ deallocate_user_data(CC);
+
/* Now get rid of the session and context */
lprintf(7, "cleanup_stuff() calling RemoveContext(%d)\n", CC->cs_pid);
RemoveContext(CC);
}
+
+/*
+ * Return a pointer to some generic per-session user data.
+ * (This function returns NULL if the requested symbol is not allocated.)
+ *
+ * NOTE: we use critical sections for allocating and de-allocating these,
+ * but not for locating one.
+ */
+void *CtdlGetUserData(unsigned long requested_sym)
+{
+ struct CtdlSessData *ptr;
+
+ for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next)
+ if (ptr->sym_id == requested_sym)
+ return(ptr->sym_data);
+
+ lprintf(2, "ERROR! CtdlGetUserData(%ld) symbol not allocated\n",
+ requested_sym);
+ return NULL;
+}
+
+
+/*
+ * Allocate some generic per-session user data.
+ */
+void CtdlAllocUserData(unsigned long requested_sym, size_t num_bytes)
+{
+ struct CtdlSessData *ptr;
+
+ lprintf(9, "CtdlAllocUserData(%ld) called\n", requested_sym);
+
+ for (ptr = CC->FirstSessData; ptr != NULL; ptr = ptr->next) {
+ if (ptr->sym_id == requested_sym) {
+ lprintf(2, "ERROR: CtdlAllocUserData() requested for"
+ " symbol id %ld already registered\n",
+ requested_sym);
+ return;
+ }
+ }
+
+ ptr = mallok(sizeof(struct CtdlSessData));
+ ptr->sym_id = requested_sym;
+ ptr->sym_data = mallok(num_bytes);
+
+ begin_critical_section(S_SESSION_TABLE);
+ ptr->next = CC->FirstSessData;
+ CC->FirstSessData = ptr;
+ end_critical_section(S_SESSION_TABLE);
+
+ lprintf(9, "CtdlAllocUserData(%ld) finished\n", requested_sym);
+}
+
+
+
+
+
/*
* set_wtmpsupp() - alter the session listing
*/
CC->cs_flags = 0;
CC->upload_type = UPL_FILE;
CC->dl_is_net = 0;
+ CC->FirstSessData = NULL;
num_sessions = session_count();
CC->nologin = 0;
/* #define DEBUG_MEMORY_LEAKS */
+/*
+ * Generic per-session variable or data structure storage
+ */
+struct CtdlSessData {
+ struct CtdlSessData *next;
+ unsigned long sym_id;
+ void *sym_data;
+};
+
+/*
+ * For the time being, all known userdata symbols are defined here.
+ */
+#define SYM_DESIRED_SECTION 0x00000001
+
+
/*
* 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;
-
+ struct usersupp usersupp; /* Database record buffers */
+ struct quickroom quickroom;
+
long *msglist;
int num_msgs;
- 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[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];
+ char net_node[32];
THREAD mythread;
- int n_crit; /* number of critical sections open */
+ int n_crit; /* number of critical sections open */
int client_socket;
- int cs_pid; /* session ID */
+ 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;
+ 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 */
+ char chat_room[20]; /* The chat room */
char dl_is_net;
char upload_type;
struct ExpressMessage *FirstExpressMessage;
- 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> */
+ 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> */
- int FloorBeingSearched; /* This is used by cmd_lrms() etc. */
- char desired_section[64]; /* This is used for MIME downloads */
- };
+ int FloorBeingSearched; /* This is used by cmd_lrms() etc. */
+ 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 */
+#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())
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;
char chat_text[256];
char chat_room[20];
char chat_username[32];
- };
+};
/*
* Various things we need to lock and unlock
/*
* 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 */
+#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 */
/*
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;
struct CleanupFunctionHook {
struct CleanupFunctionHook *next;
void (*h_function_pointer) (void);
- };
+};
extern struct CleanupFunctionHook *CleanupHookTable;
struct SessionFunctionHook *next;
void (*h_function_pointer) (void);
int eventtype;
- };
+};
extern struct SessionFunctionHook *SessionHookTable;
#define EVT_STOP 0 /* Session is terminating */
struct UserFunctionHook *next;
void (*h_function_pointer) (char *username, long usernum);
int eventtype;
- };
+};
extern struct UserFunctionHook *UserHookTable;
#define EVT_PURGEUSER 100 /* Deleting a user */
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 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
void dump_tracked(void);
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;