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) {
/*
* Cleanup routine to be called when the server is shutting down.
- * WARNING: It's no longer safe to call this function to force a shutdown.
- * Instead, set time_to_die = 1.
*/
-void master_cleanup(void) {
+void master_cleanup(int exitcode) {
struct CleanupFunctionHook *fcn;
+ static int already_cleaning_up = 0;
+
+ if (already_cleaning_up) while(1) sleep(1);
+ already_cleaning_up = 1;
/* Run any cleanup routines registered by loadable modules */
for (fcn = CleanupHookTable; fcn != NULL; fcn = fcn->next) {
#endif
/* Now go away. */
- lprintf(CTDL_NOTICE, "citserver: exiting.\n");
+ lprintf(CTDL_NOTICE, "citserver: Exiting with status %d.\n", exitcode);
fflush(stdout); fflush(stderr);
- exit(0);
+ exit(exitcode);
}
*/
void RemoveContext (struct CitContext *con)
{
- struct CitContext *ptr = NULL;
- struct CitContext *ToFree = NULL;
-
if (con==NULL) {
lprintf(CTDL_ERR, "WARNING: RemoveContext() called with NULL!\n");
return;
*/
lprintf(CTDL_DEBUG, "Removing context for session %d\n", con->cs_pid);
begin_critical_section(S_SESSION_TABLE);
- if (ContextList == con) {
- ToFree = ContextList;
- ContextList = ContextList->next;
- --num_sessions;
- }
- 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;
- }
- }
- }
+ if (con->prev) con->prev->next = con->next; else ContextList = con->next;
+ if (con->next) con->next->prev = con->prev;
+ --num_sessions;
end_critical_section(S_SESSION_TABLE);
- if (ToFree == NULL) {
- lprintf(CTDL_DEBUG, "RemoveContext() found nothing to remove\n");
- return;
- }
-
/* Run any cleanup routines registered by loadable modules.
* Note 1: This must occur *before* deallocate_user_data() because the
* cleanup functions might touch dynamic session data.
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);
}
cprintf("%d %s\n", SEND_LISTING, targ);
- while (client_gets(buf), strcmp(buf, "000")) {
+ while (client_getln(buf, sizeof buf), strcmp(buf, "000")) {
fprintf(mfp, "%s\n", buf);
}
struct CitContext *viewed,
struct CitContext *viewer) {
+ int ra;
+
strcpy(real_room, viewed->room.QRname);
if (viewed->room.QRflags & QR_MAILBOX) {
strcpy(real_room, &real_room[11]);
}
if (viewed->room.QRflags & QR_PRIVATE) {
- if ( (CtdlRoomAccess(&viewed->room, &viewer->user)
- & UA_KNOWN) == 0) {
+ CtdlRoomAccess(&viewed->room, &viewer->user, &ra, NULL);
+ if ( (ra & UA_KNOWN) == 0) {
strcpy(real_room, "<private room>");
}
}
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;
/*
strcpy(con->fake_hostname, "");
strcpy(con->fake_roomname, "");
generate_nonce(con);
- snprintf(con->temp, sizeof con->temp, tmpnam(NULL));
+ safestrncpy(con->temp, tmpnam(NULL), sizeof con->temp);
safestrncpy(con->cs_host, config.c_fqdn, sizeof con->cs_host);
safestrncpy(con->cs_addr, "", sizeof con->cs_addr);
con->cs_host[sizeof con->cs_host - 1] = 0;
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);
time(&CC->lastcmd);
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
- if (client_gets(cmdbuf) < 1) {
+ if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
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.
ERROR + CMD_NOT_SUPPORTED);
}
+ unbuffer_output();
+
/* Run any after-each-command routines registered by modules */
PerformSessionHooks(EVT_CMD);
}