#endif
struct CitContext *ContextList = NULL;
+struct CitContext* next_session = NULL;
char *unique_session_numbers;
int ScheduledShutdown = 0;
int do_defrag = 0;
check_ref_counts();
lprintf(CTDL_INFO, "Creating base rooms (if necessary)\n");
- create_room(BASEROOM, 0, "", 0, 1, 0);
- create_room(AIDEROOM, 3, "", 0, 1, 0);
- create_room(SYSCONFIGROOM, 3, "", 0, 1, 0);
- create_room(config.c_twitroom, 0, "", 0, 1, 0);
+ create_room(BASEROOM, 0, "", 0, 1, 0, VIEW_BBS);
+ create_room(AIDEROOM, 3, "", 0, 1, 0, VIEW_BBS);
+ create_room(SYSCONFIGROOM, 3, "", 0, 1, 0, VIEW_BBS);
+ create_room(config.c_twitroom, 0, "", 0, 1, 0, VIEW_BBS);
/* The "Local System Configuration" room doesn't need to be visible */
if (lgetroom(&qrbuf, SYSCONFIGROOM) == 0) {
/* Do system-dependent stuff */
sysdep_master_cleanup();
+#ifdef DEBUG_MEMORY_LEAKS
+ dump_heap();
+#endif
+
/* Now go away. */
lprintf(CTDL_NOTICE, "citserver: exiting.\n");
fflush(stdout); fflush(stderr);
else {
for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
if (ptr->next == con) {
+ /* See fair scheduling in sysdep.c */
+ if (next_session == ptr->next)
+ next_session = ptr->next->next;
ToFree = ptr->next;
ptr->next = ptr->next->next;
--num_sessions;
logout(con);
unlink(con->temp);
- lprintf(CTDL_NOTICE, "Session %d: ended.\n", con->cs_pid);
+ lprintf(CTDL_NOTICE, "[%3d] Session ended.\n", con->cs_pid);
/* Deallocate any user-data attached to this session */
deallocate_user_data(con);
/*
- * returns an asterisk if there are any express messages waiting,
+ * returns an asterisk if there are any instant messages waiting,
* space otherwise.
*/
char CtdlCheckExpress(void) {
void cmd_time(void)
{
time_t tv;
- struct tm *tmp;
+ struct tm tmp;
tv = time(NULL);
- tmp = localtime(&tv);
+ localtime_r(&tv, &tmp);
/* timezone and daylight global variables are not portable. */
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
- cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, tmp->tm_gmtoff, tmp->tm_isdst);
+ cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, tmp.tm_gmtoff, tmp.tm_isdst);
#else
- cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, timezone, tmp->tm_isdst);
+ cprintf("%d %ld|%ld|%d\n", CIT_OK, (long)tv, timezone, tmp.tm_isdst);
#endif
}
char *dirs[2];
int a;
+ unbuffer_output();
+
if (CtdlAccessCheck(ac_aide)) return;
extract(buf,mname,0);
return(-1);
}
+ if ((required_level >= ac_logged_in) && (CC->logged_in == 0)) {
+ cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
+ return(-1);
+ }
+
if (CC->user.axlevel >= 6) return(0);
if (required_level >= ac_aide) {
cprintf("%d This command requires Aide access.\n",
return(-1);
}
- if (CC->logged_in) return(0);
- if (required_level >= ac_logged_in) {
- cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
- return(-1);
- }
-
/* shhh ... succeed quietly */
return(0);
}
*/
void begin_session(struct CitContext *con)
{
- int len; /* should be socklen_t but doesn't work on Macintosh */
+ int len;
struct sockaddr_in sin;
/*
len = sizeof sin;
if (!CC->is_local_socket) {
if (!getpeername(con->client_socket,
- (struct sockaddr *) &sin, &len))
+ (struct sockaddr *) &sin, &len)) /* should be socklen_t but doesn't work on Macintosh */
locate_host(con->cs_host, sizeof con->cs_host,
con->cs_addr, sizeof con->cs_addr,
&sin.sin_addr);
config.c_nodename, config.c_maxsessions);
}
else {
- cprintf("%d %s Citadel/UX server ready.\n",
+ cprintf("%d %s Citadel server ready.\n",
CIT_OK, config.c_nodename);
}
}
time(&CC->lastcmd);
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
if (client_gets(cmdbuf) < 1) {
- lprintf(CTDL_ERR, "Client socket is broken. Ending session.\n");
+ lprintf(CTDL_ERR, "Client socket is broken; ending session\n");
CC->kill_me = 1;
return;
}
lprintf(CTDL_INFO, "Citadel: %s\n", cmdbuf);
+ buffer_output();
+
/*
* Let other clients see the last command we executed, and
* update the idle time, but not NOOP, QNOP, PEXP, or GEXP.
}
if (!strncasecmp(cmdbuf,"NOOP",4)) {
- cprintf("%d%cok\n",CIT_OK,CtdlCheckExpress());
+ cprintf("%d%cok\n", CIT_OK, CtdlCheckExpress() );
}
else if (!strncasecmp(cmdbuf,"QNOP",4)) {
}
else if (!strncasecmp(cmdbuf,"QUIT",4)) {
- cprintf("%d Goodbye.\n",CIT_OK);
+ cprintf("%d Goodbye.\n", CIT_OK);
CC->kill_me = 1;
}
else if (!strncasecmp(cmdbuf,"LOUT",4)) {
if (CC->logged_in) logout(CC);
- cprintf("%d logged out.\n",CIT_OK);
+ cprintf("%d logged out.\n", CIT_OK);
}
else if (!strncasecmp(cmdbuf,"USER",4)) {
}
else if (!DLoader_Exec_Cmd(cmdbuf)) {
- cprintf("%d Unrecognized or unsupported command.\n", ERROR + CMD_NOT_SUPPORTED);
+ cprintf("%d Unrecognized or unsupported command.\n",
+ ERROR + CMD_NOT_SUPPORTED);
}
- /* Run any after-each-command outines registered by modules */
+ unbuffer_output();
+
+ /* Run any after-each-command routines registered by modules */
PerformSessionHooks(EVT_CMD);
}
+
+
+/*
+ * This loop performs all asynchronous functions.
+ */
+void do_async_loop(void) {
+ PerformSessionHooks(EVT_ASYNC);
+}