#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
+#include <syslog.h>
#include <sys/syslog.h>
#if TIME_WITH_SYS_TIME
#endif
#include "citadel.h"
#include "server.h"
-#include "serv_extensions.h"
#include "sysdep_decls.h"
#include "citserver.h"
#include "support.h"
#include "database.h"
#include "housekeeping.h"
#include "tools.h"
-#include "serv_crypto.h"
-#include "serv_fulltext.h"
+#include "modules/crypto/serv_crypto.h" /* Needed for init_ssl, client_write_ssl, client_read_ssl, destruct_ssl */
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
time_t last_purge = 0; /* Last dead session purge */
static int num_threads = 0; /* Current number of threads */
int num_sessions = 0; /* Current number of sessions */
-pthread_t indexer_thread_tid;
-pthread_t checkpoint_thread_tid;
int syslog_facility = LOG_DAEMON;
int enable_syslog = 0;
-extern int running_as_daemon;
+
+void DestroyWorkerList(void);
/*
* lprintf() ... Write logging information
volatile int time_to_die = 0;
volatile int shutdown_and_halt = 0;
+volatile int restart_server = 0;
+volatile int running_as_daemon = 0;
static RETSIGTYPE signal_cleanup(int signum) {
lprintf(CTDL_DEBUG, "Caught signal %d; shutting down.\n", signum);
master_cleanup(signum);
}
-
/*
* Some initialization stuff...
*/
sin.sin_addr.s_addr = inet_addr(ip_addr);
}
- if (sin.sin_addr.s_addr == INADDR_NONE) {
+ if (sin.sin_addr.s_addr == !INADDR_ANY) {
sin.sin_addr.s_addr = INADDR_ANY;
}
* native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with
* user-space buffering.
*/
+#ifndef HAVE_DARWIN
#ifdef TCP_CORK
# define HAVE_TCP_BUFFERING
#else
# define HAVE_TCP_BUFFERING
# define TCP_CORK TCP_NOPUSH
# endif
-#endif
-
+#endif /* TCP_CORK */
+#endif /* HAVE_DARWIN */
#ifdef HAVE_TCP_BUFFERING
static unsigned on = 1, off = 0;
setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
setsockopt(ctx->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
}
+#elif HAVE_DARWIN
+/* Stub functions for Darwin/OS X where TCP buffering isn't liked at all */
+void buffer_output(void) {
+CC->buffering = 0;
+}
+void unbuffer_output(void) {
+CC->buffering = 0;
+}
+void flush_output(void) {
+}
#else
void buffer_output(void) {
if (CC->buffering == 0) {
/* Strip the trailing LF, and the trailing CR if present.
*/
buf[i] = 0;
- while ( (strlen(buf) > 0) && ((buf[strlen(buf)-1]==10) || (buf[strlen(buf)-1] == 13)) ) {
+ while ( (!IsEmptyStr(buf)) && ((buf[strlen(buf)-1]==10) || (buf[strlen(buf)-1] == 13)) ) {
buf[strlen(buf)-1] = 0;
}
if (retval < 0) safestrncpy(buf, "000", bufsize);
void sysdep_master_cleanup(void) {
struct ServiceFunctionHook *serviceptr;
+///// DestroyWorkerList();
/*
* close all protocol master sockets
*/
unlink(serviceptr->sockpath);
}
}
+#ifdef HAVE_OPENSSL
+ destruct_ssl();
+#endif
+ serv_calendar_destroy();
+ CtdlDestroyProtoHooks();
+ CtdlDestroyDeleteHooks();
+ CtdlDestroyXmsgHooks();
+ CtdlDestroyNetprocHooks();
+ CtdlDestroyUserHooks();
+ CtdlDestroyMessageHook();
+ CtdlDestroyCleanupHooks();
+ CtdlDestroyFixedOutputHooks();
+ CtdlDestroySessionHooks();
+ CtdlDestroyServiceHook();
}
+
+
/*
* Terminate another session.
* (This could justifiably be moved out of sysdep.c because it
int status = 0;
pid_t child = 0;
FILE *fp;
+ int do_restart = 0;
current_child = 0;
child = fork();
if (child != 0) {
- fp = fopen(file_pid_file, "w");
- if (fp != NULL) {
- fprintf(fp, "%d\n", child);
- fclose(fp);
- }
exit(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);
}
else {
+ fp = fopen(file_pid_file, "w");
+ if (fp != NULL) {
+ fprintf(fp, ""F_PID_T"\n", child);
+ fclose(fp);
+ }
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));
}
pthread_attr_destroy(&attr);
}
+void DestroyWorkerList(void)
+{
+ struct CitContext *ptr; /* general-purpose utility pointer */
+ struct CitContext *rem = NULL; /* list of sessions to be destroyed */
+
+ begin_critical_section(S_SESSION_TABLE);
+ ptr = ContextList;
+ while (ptr != NULL){
+ /* Remove the session from the active list */
+ rem = ptr->next;
+ --num_sessions;
+
+ lprintf(CTDL_DEBUG, "Purging session %d\n", rem->cs_pid);
+ end_critical_section(S_SESSION_TABLE);
+ RemoveContext(ptr);
+ begin_critical_section(S_SESSION_TABLE);
+ free (ptr);
+ ptr = rem;
+ }
+ end_critical_section(S_SESSION_TABLE);
+
+ struct worker_node *cur, *p;
+ cur = worker_list;
+ while (cur != NULL)
+ {
+ p = cur->next;
+ free (cur);
+ cur = p;
+ }
+ worker_list = NULL;
+}
/*
- * Create the indexer thread and begin its operation.
- * Then create the checkpoint thread and begin its operation.
+ * Create the maintenance threads and begin their operation.
*/
void create_maintenance_threads(void) {
int ret;
pthread_attr_destroy(&attr);
return;
}
+
+ struct MaintenanceThreadHook *fcn;
- if ((ret = pthread_create(&indexer_thread_tid, &attr, indexer_thread, NULL) != 0)) {
- lprintf(CTDL_ALERT, "Can't create thread: %s\n", strerror(ret));
- }
+ lprintf(CTDL_DEBUG, "Performing startup of maintenance thread hooks\n");
- if ((ret = pthread_create(&checkpoint_thread_tid, &attr, checkpoint_thread, NULL) != 0)) {
- lprintf(CTDL_ALERT, "Can't create thread: %s\n", strerror(ret));
+ for (fcn = MaintenanceThreadHookTable; fcn != NULL; fcn = fcn->next) {
+ if ((ret = pthread_create(&(fcn->MaintenanceThread_tid), &attr, fcn->fcn_ptr, NULL) != 0)) {
+ lprintf(CTDL_ALERT, "Can't create thread: %s\n", strerror(ret));
+ }
+ else
+ {
+ lprintf(CTDL_NOTICE, "Spawned a new maintenance thread \"%s\" (%ld). \n", fcn->name,
+ fcn->MaintenanceThread_tid);
+ }
}
+
pthread_attr_destroy(&attr);
}
do_housekeeping();
check_sched_shutdown();
}
-
+ if (con != NULL) free (con);//// TODO: could this harm other threads?
/* If control reaches this point, the server is shutting down */
return(NULL);
}