"Error: %s\n",
(home_specified ? ctdl_home_directory : CTDLDIR),
strerror(errno));
- exit(1);
+ exit(CTDLEXIT_HOME);
}
cfp = fopen(file_citadel_config, "rb");
if (cfp == NULL) {
"Error: %s\n",
file_citadel_config,
strerror(errno));
- exit(1);
+ exit(CTDLEXIT_CONFIG);
}
fread((char *) &config, sizeof(struct config), 1, cfp);
if (fstat(fileno(cfp), &st)) {
perror(file_citadel_config);
- exit(1);
+ exit(CTDLEXIT_CONFIG);
}
#ifndef __CYGWIN__
if (st.st_uid != CTDLUID || st.st_mode != (S_IFREG | S_IRUSR | S_IWUSR)) {
fprintf(stderr, "check the permissions on %s\n", file_citadel_config);
// fprintf(stderr, "check the permissions on citadel.config\n");
- exit(1);
+ exit(CTDLEXIT_CONFIG);
}
#endif
fclose(cfp);
" Data files are currently at %d.%02d\n",
(config.c_setup_level / 100),
(config.c_setup_level % 100));
- exit(1);
+ exit(CTDLEXIT_OOD);
}
/* Default maximum message length is 10 megabytes. This is site
if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) {
lprintf(CTDL_EMERG, "citserver: unable to lock %s.\n", file_citadel_control);
lprintf(CTDL_EMERG, "Is another citserver already running?\n");
- exit(1);
+ exit(CTDLEXIT_CONTROL);
}
}
if (ret) {
lprintf(CTDL_EMERG, "cdb_*: db_env_create: %s\n",
db_strerror(ret));
- exit(ret);
+ exit(CTDLEXIT_DB);
}
dbenv->set_errpfx(dbenv, "citserver");
dbenv->set_paniccall(dbenv, dbpanic);
lprintf(CTDL_EMERG, "cdb_*: set_cachesize: %s\n",
db_strerror(ret));
dbenv->close(dbenv, 0);
- exit(ret);
+ exit(CTDLEXIT_DB);
}
if ((ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT))) {
lprintf(CTDL_EMERG, "cdb_*: set_lk_detect: %s\n",
db_strerror(ret));
dbenv->close(dbenv, 0);
- exit(ret);
+ exit(CTDLEXIT_DB);
}
flags =
lprintf(CTDL_DEBUG, "cdb_*: dbenv->open: %s\n",
db_strerror(ret));
dbenv->close(dbenv, 0);
- exit(ret);
+ exit(CTDLEXIT_DB);
}
lprintf(CTDL_INFO, "cdb_*: Starting up DB\n");
if (ret) {
lprintf(CTDL_DEBUG, "cdb_*: db_create: %s\n",
db_strerror(ret));
- exit(ret);
+ exit(CTDLEXIT_DB);
}
if (ret) {
lprintf(CTDL_EMERG, "cdb_*: db_open[%d]: %s\n", i,
db_strerror(ret));
- exit(ret);
+ exit(CTDLEXIT_DB);
}
}
if ((ret = pthread_key_create(&tsdkey, dest_tsd))) {
lprintf(CTDL_EMERG, "cdb_*: pthread_key_create: %s\n",
strerror(ret));
- exit(1);
+ exit(CTDLEXIT_DB);
}
cdb_allocate_tsd();
#define CM_SKIP_HOOKS 0x01 /* Don't run server-side handlers */
+
+/*
+ * Exit codes 101 through 109 are used for conditions in which
+ * we deliberately do NOT want the service to automatically
+ * restart.
+ */
+#define CTDLEXIT_CONFIG 101 /* Could not read citadel.config */
+#define CTDLEXIT_CONTROL 102 /* Could not acquire lock */
+#define CTDLEXIT_HOME 103 /* Citadel home directory not found */
+#define CTDLEXIT_OOD 104 /* Out Of Date config - rerun setup */
+#define CTDLEXIT_DB 105 /* Unable to initialize database */
+
+
+
+
/*
* Here's the big one... the Citadel context structure.
*
"#\n"
"# chkconfig: - 79 30\n"
"# description: Citadel service\n"
- "# processname: ctdlsvc\n"
- "# pidfile: /var/run/citadel.pid\n"
+ "# processname: citserver\n"
+ "# pidfile: %s/citadel.pid\n"
"\n"
- "CITADEL_DIR=%s\n", setup_directory);
+ "CITADEL_DIR=%s\n"
+ ,
+ setup_directory,
+ setup_directory
+ );
fprintf(fp, "\n"
"test -x $CITADEL_DIR/ctdlsvc || exit 0\n"
"test -d /var/run || exit 0\n"
"case \"$1\" in\n"
"\n"
"start) echo -n \"Starting Citadel... \"\n"
- " if $CITADEL_DIR/ctdlsvc /var/run/citadel.pid "
- "$CITADEL_DIR/citserver "
- "-t/dev/null\n"
+ " if $CITADEL_DIR/citserver -d\n"
" then\n"
" echo \"ok\"\n"
" else\n"
" else\n"
" echo \"failed\"\n"
" fi\n"
- " rm -f /var/run/citadel.pid 2>/dev/null\n");
+ " rm -f %s/citadel.pid 2>/dev/null\n"
+ ,
+ setup_directory
+ );
fprintf(fp, " ;;\n"
"restart) $0 stop\n"
" $0 start\n"
int status = 0;
pid_t child = 0;
FILE *fp;
+ int do_restart = 0;
current_child = 0;
signal(SIGQUIT, SIG_IGN);
setsid();
-// umask(0);
+ umask(0);
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
waitpid(current_child, &status, 0);
}
- } while (status != 0);
+ do_restart = 0;
- unlink(file_pid_file);
- exit(0);
+ /* Did the main process exit with an actual exit code? */
+ if (WIFEXITED(status)) {
+
+ /* Exit code 0 means the watcher should exit */
+ if (WEXITSTATUS(status) == 0) {
+ do_restart = 0;
+ }
+ /* Exit code 101-109 means the watcher should exit */
+ else if ( (WEXITSTATUS(status) >= 101) && (WEXITSTATUS(status) <= 109) ) {
+ do_restart = 0;
+ }
+
+ /* Any other exit code means we should restart. */
+ else {
+ do_restart = 1;
+ }
+ }
+
+ /* Any other type of termination (signals, etc.) should also restart. */
+ else {
+ do_restart = 1;
+ }
+
+ } while (do_restart);
+
+ unlink(file_pid_file);
+ exit(WEXITSTATUS(status));
}