#include <dirent.h>
#include <errno.h>
#include <limits.h>
-/* #include <dlfcn.h> */
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
lputroom(&qrbuf);
}
- /*
- * Create a room in which we can deposit "deleted" messages for
- * deferred deletion. This will silently fail if the room already
- * exists, and that's perfectly ok, because we want it to exist.
- */
- create_room(DELETED_MSGS_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX);
-
- /*
- * Make sure it's set to be a "system room" so it doesn't show up
- * in the <K>nown rooms list for Aides. Also set the message expire
- * policy to "by count, 1 message" so everything gets deleted all
- * the time (we can't set it to 0 because that's invalid, so we keep
- * a single message around).
- */
- if (lgetroom(&qrbuf, DELETED_MSGS_ROOM) == 0) {
- qrbuf.QRflags2 |= QR2_SYSTEM;
- qrbuf.QRep.expire_mode = EXPIRE_NUMMSGS;
- qrbuf.QRep.expire_value = 1;
- lputroom(&qrbuf);
- }
-
lprintf(CTDL_INFO, "Seeding the pseudo-random number generator...\n");
urandom = fopen("/dev/urandom", "r");
if (urandom != NULL) {
(*fcn->h_function_pointer)();
}
+ /* Close the AdjRefCount queue file */
+ AdjRefCount(-1, 0);
+
/* Shut down the indexer thread */
lprintf(CTDL_INFO, "Waiting for the indexer thread to shut down\n");
pthread_join(indexer_thread_tid, NULL);
dump_heap();
#endif
+ /* If the operator requested a halt but not an exit, halt here. */
+ if (shutdown_and_halt) {
+ lprintf(CTDL_NOTICE, "citserver: Halting server without exiting.\n");
+ fflush(stdout); fflush(stderr);
+ while(1) {
+ sleep(32767);
+ }
+ }
+
/* Now go away. */
lprintf(CTDL_NOTICE, "citserver: Exiting with status %d\n", exitcode);
fflush(stdout); fflush(stderr);
cprintf("1\n"); /* 1 = we support the extended paging options */
cprintf("%s\n", CC->cs_nonce);
cprintf("1\n"); /* 1 = yes, this system supports the QNOP command */
+
#ifdef HAVE_LDAP
cprintf("1\n"); /* 1 = yes, this server is LDAP-enabled */
#else
cprintf("0\n"); /* 1 = no, this server is not LDAP-enabled */
#endif
+
+ if (config.c_auth_mode == 1) {
+ cprintf("1\n"); /* "create new user" never works with host auth */
+ }
+ else {
+ cprintf("%d\n", config.c_disable_newu); /* otherwise, site defined */
+ }
+
+ cprintf("%s\n", config.c_default_cal_zone);
+
cprintf("000\n");
}
if ((strlen(public_clients) +
strlen(addrbuf) + 2)
< sizeof(public_clients)) {
+ strcat(public_clients, "|");
strcat(public_clients, addrbuf);
}
}
/* If the client requested "?" then produce a listing */
if (!strcmp(buf, "?")) {
- cprintf("%d %s\n",LISTING_FOLLOWS,buf);
+ cprintf("%d %s\n", LISTING_FOLLOWS, buf);
dp = opendir(dirs[1]);
if (dp != NULL) {
while (d = readdir(dp), d != NULL) {
free(dirs[1]);
if (strlen(targ)==0) {
- cprintf("%d '%s' not found.\n",ERROR + FILE_NOT_FOUND, mname);
+ cprintf("%d '%s' not found. (Searching in %s and %s)\n",
+ ERROR + FILE_NOT_FOUND,
+ mname,
+ ctdl_message_dir,
+ ctdl_hlp_dir
+ );
return;
}
- mfp = fopen(targ,"r");
+ mfp = fopen(targ, "r");
if (mfp==NULL) {
cprintf("%d Cannot open '%s': %s\n",
ERROR + INTERNAL_ERROR, targ, strerror(errno));
return;
}
- cprintf("%d %s\n",LISTING_FOLLOWS,buf);
+ cprintf("%d %s\n", LISTING_FOLLOWS,buf);
while (fgets(buf, (sizeof buf - 1), mfp) != NULL) {
buf[strlen(buf)-1] = 0;
time_to_die = 1;
}
+/*
+ * Halt the server without exiting the server process.
+ */
+void cmd_halt(void) {
+
+ if (CtdlAccessCheck(ac_aide)) return;
+
+ cprintf("%d Halting server. Goodbye.\n", CIT_OK);
+ time_to_die = 1;
+ shutdown_and_halt = 1;
+}
+
/*
* Schedule or cancel a server shutdown
*/
*/
void begin_session(struct CitContext *con)
{
- int len;
+ socklen_t len;
struct sockaddr_in sin;
/*
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)) /* should be socklen_t but doesn't work on Macintosh */
+ if (!getpeername(con->client_socket, (struct sockaddr *) &sin, &len)) {
locate_host(con->cs_host, sizeof con->cs_host,
con->cs_addr, sizeof con->cs_addr,
- &sin.sin_addr);
+ &sin.sin_addr
+ );
+ }
}
else {
strcpy(con->cs_host, "");
/*
* Let other clients see the last command we executed, and
- * update the idle time, but not NOOP, QNOP, PEXP, or GEXP.
+ * update the idle time, but not NOOP, QNOP, PEXP, GEXP, RWHO, or TIME.
*/
if ( (strncasecmp(cmdbuf, "NOOP", 4))
&& (strncasecmp(cmdbuf, "QNOP", 4))
&& (strncasecmp(cmdbuf, "PEXP", 4))
- && (strncasecmp(cmdbuf, "GEXP", 4)) ) {
+ && (strncasecmp(cmdbuf, "GEXP", 4))
+ && (strncasecmp(cmdbuf, "RWHO", 4))
+ && (strncasecmp(cmdbuf, "TIME", 4)) ) {
strcpy(CC->lastcmdname, " ");
safestrncpy(CC->lastcmdname, cmdbuf, sizeof(CC->lastcmdname));
time(&CC->lastidle);
cmd_opna(&cmdbuf[5]);
}
+ else if (!strncasecmp(cmdbuf,"DLAT",4)) {
+ cmd_dlat(&cmdbuf[5]);
+ }
+
else if (!strncasecmp(cmdbuf,"INFO",4)) {
cmd_info();
}
cmd_down();
}
+ else if (!strncasecmp(cmdbuf,"HALT",4)) {
+ cmd_halt();
+ }
+
else if (!strncasecmp(cmdbuf,"SCDN",4)) {
cmd_scdn(&cmdbuf[5]);
}