#include "../../ctdl_module.h"
-// Shut down or restart the server
+// Shut down the server
void cmd_down(char *argbuf) {
- char *Reply ="%d Shutting down server. Goodbye.\n";
-
if (CtdlAccessCheck(ac_aide)) return;
-
- if (!IsEmptyStr(argbuf)) {
- int state = CIT_OK;
- restart_server = extract_int(argbuf, 0);
-
- if (restart_server > 0) {
- Reply = "%d citserver will now shut down and automatically restart.\n";
- }
- cprintf(Reply, state);
- }
- else {
- cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN);
- }
+ cprintf("%d Shutting down server. Goodbye.\n", CIT_OK + SERVER_SHUTTING_DOWN);
CC->kill_me = KILLME_SERVER_SHUTTING_DOWN;
server_shutting_down = 1;
}
// parse command-line arguments
int g;
- while ((g=getopt(argc, argv, "cl:dh:x:t:B:Dru:s:R:")) != EOF) switch(g) {
+ while ((g=getopt(argc, argv, "cl:h:x:t:B:Dru:s:R:")) != EOF) switch(g) {
// test this binary for compatibility and exit
case 'c':
syslog_facility = SyslogFacility(facility);
break;
- // run in the background if -d was specified
- case 'd':
- running_as_daemon = 1;
- break;
-
// specify the data directory
case 'h':
ctdldir = optarg;
max_log_level = atoi(optarg);
break;
- // deprecated flags from old versions -- ignore silently to prevent breaking scripts
- case 't':
- case 'B':
- case 'D':
- break;
-
// -r tells the server not to drop root permissions.
// Don't use this unless you know what you're doing.
case 'r':
syslog_facility
);
- // daemonize, if we were asked to
- if (running_as_daemon) {
- start_daemon(0);
- drop_root_perms = 1;
- }
-
if ((mkdir(ctdl_run_dir, 0755) != 0) && (errno != EEXIST)) {
syslog(LOG_ERR, "main: unable to create run directory [%s]: %m", ctdl_run_dir);
}
start_chkpwd_daemon();
}
- // check, whether we're fired up another time after a crash.
- // if, post an aide message, so the admin has a chance to react.
- checkcrash();
-
// Now that we've bound the sockets, change to the Citadel user id and its corresponding group ids
if (drop_root_perms) {
cdb_chmod_data(); // make sure we own our data files
}
-pid_t current_child;
-void supervisor_process_shutdown(int signum) {
- kill(current_child, signum);
- unlink(file_pid_file);
- exit(0);
-}
-
-int nFireUps = 0;
-int nFireUpsNonRestart = 0;
-pid_t ForkedPid = 1;
-
-// Start running as a daemon.
-void start_daemon(int unused) {
- int status = 0;
- pid_t child = 0;
- FILE *fp;
- int do_restart = 0;
- current_child = 0;
-
- // Close stdin/stdout/stderr and replace them with /dev/null.
- // We don't just call close() because we don't want these fd's
- // to be reused for other files.
- child = fork();
- if (child != 0) {
- exit(0);
- }
-
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-
- setsid();
- umask(0);
- if ( (freopen("/dev/null", "r", stdin) != stdin) ||
- (freopen("/dev/null", "w", stdout) != stdout) ||
- (freopen("/dev/null", "w", stderr) != stderr)
- ) {
- syslog(LOG_ERR, "sysdep: unable to reopen stdio: %m");
- }
-
- do {
- current_child = fork();
- signal(SIGTERM, supervisor_process_shutdown);
- if (current_child < 0) {
- perror("fork");
- exit(errno);
- }
- else if (current_child == 0) {
- return; // continue starting citadel.
- }
- else {
- fp = fopen(file_pid_file, "w");
- if (fp != NULL) {
- fprintf(fp, ""F_PID_T"\n", getpid());
- fclose(fp);
- }
- waitpid(current_child, &status, 0);
- }
- nFireUpsNonRestart = nFireUps;
-
- // Exit code 0 means the watcher should exit
- if (WIFEXITED(status) && (WEXITSTATUS(status) == CTDLEXIT_SHUTDOWN)) {
- do_restart = 0;
- }
-
- // Exit code 101-109 means the watcher should exit
- else if (WIFEXITED(status) && (WEXITSTATUS(status) >= 101) && (WEXITSTATUS(status) <= 109)) {
- do_restart = 0;
- }
-
- // Any other exit code, or no exit code, means we should restart.
- else {
- do_restart = 1;
- nFireUps++;
- ForkedPid = current_child;
- }
-
- } while (do_restart);
-
- unlink(file_pid_file);
- exit(WEXITSTATUS(status));
-}
-
-
-void checkcrash(void) {
- if (nFireUpsNonRestart != nFireUps) {
- StrBuf *CrashMail;
- CrashMail = NewStrBuf();
- syslog(LOG_ALERT, "sysdep: posting crash message");
- StrBufPrintf(CrashMail,
- " \n"
- " The Citadel server process (citserver) terminated unexpectedly."
- "\n \n"
- " This could be the result of a bug in the server program, or some external "
- "factor.\n \n"
- " You can obtain more information about this by enabling core dumps.\n \n"
- " For more information, please see:\n \n"
- " http://citadel.org/doku.php?id=faq:mastering_your_os:gdb#how.do.i.make.my.system.produce.core-files"
- "\n \n"
-
- " If you have already done this, the core dump is likely to be found at %score.%d\n"
- ,
- ctdl_run_dir, ForkedPid);
- CtdlAideMessage(ChrPtr(CrashMail), "Citadel server process terminated unexpectedly");
- FreeStrBuf(&CrashMail);
- }
-}
-
-
// Generic routine to convert a login name to a full name (gecos)
// Returns nonzero if a conversion took place
int convert_login(char NameToConvert[]) {