#include <errno.h>
#include <limits.h>
#include <sys/types.h>
+#include <sys/file.h>
#include "citadel.h"
#include "server.h"
#include "control.h"
extern struct config config;
FILE *control_fp = NULL;
+
+
+/*
+ * lock_control - acquire a lock on the control record file.
+ * This keeps multiple citservers from running concurrently.
+ */
+void lock_control(void)
+{
+ 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);
+ }
+}
+
+
/*
* get_control - read the control record into memory.
*/
void get_control(void)
{
-
/* Zero it out. If the control record on disk is missing or short,
* the system functions with all control record fields initialized
* to zero.
if (control_fp == NULL) {
control_fp = fopen(file_citadel_control, "rb+");
if (control_fp != NULL) {
+ lock_control();
fchown(fileno(control_fp), config.c_ctdluid, -1);
}
}
if (control_fp == NULL) {
control_fp = fopen(file_citadel_control, "wb+");
if (control_fp != NULL) {
+ lock_control();
fchown(fileno(control_fp), config.c_ctdluid, -1);
memset(&CitControl, 0, sizeof(struct CitControl));
fwrite(&CitControl, sizeof(struct CitControl),
#include "citserver.h"
#include "support.h"
#include "config.h"
+#include "control.h"
#include "database.h"
#include "housekeeping.h"
#include "tools.h"
config.c_ipgm_secret = rand();
put_config();
+ lprintf(CTDL_INFO, "Acquiring control record\n");
+ get_control();
+
#ifdef HAVE_RUN_DIR
/* on some dists rundir gets purged on startup. so we need to recreate it. */
* Start running as a daemon.
*/
void start_daemon(int unused) {
- close(0); close(1); close(2);
+ int nullfd;
+
+ /* 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.
+ */
+ nullfd = open("/dev/null", O_RDWR);
+ if (nullfd < 0) {
+ fprintf(stderr, "/dev/null: %s\n", strerror(errno));
+ exit(2);
+ }
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ close(nullfd);
+
if (fork()) exit(0);
setsid();
signal(SIGHUP,SIG_IGN);