*
* $Id$
*/
+#include "config.h"
+
#include "ircd.h"
#include "IPcheck.h"
#include "class.h"
#include "crule.h"
#include "hash.h"
#include "ircd_alloc.h"
+#include "ircd_features.h"
#include "ircd_log.h"
#include "ircd_reply.h"
#include "ircd_signal.h"
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
/*----------------------------------------------------------------------------
* Global data (YUCK!)
*--------------------------------------------------------------------------*/
-struct Client me; // That's me
-struct Client *GlobalClientList = &me; // Pointer to beginning of Client list
-time_t TSoffset = 0; // Offset of timestamps to system clock
-int GlobalRehashFlag = 0; // do a rehash if set
-int GlobalRestartFlag = 0; // do a restart if set
-time_t CurrentTime; // Updated every time we leave select()
-
-char *configfile = CPATH; // Server configuration file
-int debuglevel = -1; // Server debug level
-char *debugmode = ""; // Server debug level
+struct Client me; /* That's me */
+struct Connection me_con; /* That's me too */
+struct Client *GlobalClientList = &me; /* Pointer to beginning of
+ Client list */
+time_t TSoffset = 0;/* Offset of timestamps to system clock */
+int GlobalRehashFlag = 0; /* do a rehash if set */
+int GlobalRestartFlag = 0; /* do a restart if set */
+time_t CurrentTime; /* Updated every time we leave select() */
+
+char *configfile = CPATH; /* Server configuration file */
+int debuglevel = -1; /* Server debug level */
+char *debugmode = ""; /* Server debug level */
static char *dpath = DPATH;
-time_t nextconnect = 1; // time for next try_connections call
-time_t nextping = 1; // same as above for check_pings()
+time_t nextconnect = 1; /* time for next try_connections call */
+time_t nextping = 1; /* same as above for check_pings() */
-static struct Daemon thisServer = { 0 }; // server process info
+static struct Daemon thisServer = { 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0 };
* write_pidfile
*--------------------------------------------------------------------------*/
static void write_pidfile(void) {
- FILE *pidf;
-
- if (!(pidf = fopen(PPATH, "w+"))) {
- Debug((DEBUG_NOTICE,
- "Error opening pid file \"%s\": %s", PPATH, strerror(errno)));
+ char buff[20];
+
+ if (thisServer.pid_fd >= 0) {
+ memset(buff, 0, sizeof(buff));
+ sprintf(buff, "%5d\n", (int)getpid());
+ if (write(thisServer.pid_fd, buff, strlen(buff)) == -1)
+ Debug((DEBUG_NOTICE, "Error writing to pid file %s: %m",
+ feature_str(FEAT_PPATH)));
return;
}
-
- if (fprintf(pidf, "%5d\n", getpid()) < 5)
- Debug((DEBUG_NOTICE, "Error writing to pid file %s", PPATH));
-
- fclose(pidf);
+ Debug((DEBUG_NOTICE, "Error opening pid file %s: %m",
+ feature_str(FEAT_PPATH)));
}
+/* check_pid
+ *
+ * inputs:
+ * none
+ * returns:
+ * true - if the pid file exists (and is readable), and the pid refered
+ * to in the file is still running.
+ * false - otherwise.
+ */
+static int check_pid(void)
+{
+ struct flock lock;
+
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+
+ if ((thisServer.pid_fd = open(feature_str(FEAT_PPATH), O_CREAT | O_RDWR,
+ 0600)) >= 0)
+ return fcntl(thisServer.pid_fd, F_SETLK, &lock);
+
+ return 0;
+}
+
/*----------------------------------------------------------------------------
* try_connections
*--------------------------------------------------------------------------*/
static time_t check_pings(void) {
int expire = 0;
- int next_check = CurrentTime + PINGFREQUENCY;
+ int next_check = CurrentTime;
int max_ping = 0;
int i;
+
+ next_check += feature_int(FEAT_PINGFREQUENCY);
/* Scan through the client table */
for (i=0; i <= HighestFd; i++) {
continue;
}
- max_ping = IsRegistered(cptr) ? client_get_ping(cptr) : CONNECTTIMEOUT;
+ max_ping = IsRegistered(cptr) ? client_get_ping(cptr) :
+ feature_int(FEAT_CONNECTTIMEOUT);
Debug((DEBUG_DEBUG, "check_pings(%s)=status:%s limit: %d current: %d",
cli_name(cptr), (cli_flags(cptr) & FLAGS_PINGSENT) ? "[Ping Sent]" : "[]",
if (delay < 1)
read_message(1);
else
- read_message(IRCD_MIN(delay, TIMESEC));
+ read_message(IRCD_MIN(delay, feature_int(FEAT_TIMESEC)));
/* ...perhaps should not do these loops every time, but only if there is
* some chance of something happening (but, note that conf->hold times may
umask(077); /* better safe than sorry --SRB */
memset(&me, 0, sizeof(me));
+ memset(&me_con, 0, sizeof(me_con));
+ cli_connect(&me) = &me_con;
cli_fd(&me) = -1;
parse_command_line(argc, argv);
/* Check paths for accessibility */
if (!check_file_access(SPATH, 'S', X_OK) ||
- !check_file_access(configfile, 'C', R_OK) ||
- !check_file_access(MPATH, 'M', R_OK) ||
- !check_file_access(RPATH, 'R', R_OK))
+ !check_file_access(configfile, 'C', R_OK))
return 4;
#ifdef DEBUG
daemon_init(thisServer.bootopt & BOOT_TTY);
setup_signals();
+ feature_init(); /* initialize features... */
log_init(*argv);
-
+ if (check_pid()) {
+ Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork"));
+ exit(2);
+ }
set_nomem_handler(outofmemory);
if (!init_string()) {