2004-05-09 Michael Poole <mdpoole@troilus.org>
[ircu2.10.12-pk.git] / ircd / ircd.c
index e05d426d9adeaa75c2527c3b95a831c3213df27b..065487c61cd10d62cadf7427e758f9c0eb8812f6 100644 (file)
@@ -42,6 +42,7 @@
 #include "msg.h"
 #include "numeric.h"
 #include "numnicks.h"
+#include "opercmds.h"
 #include "parse.h"
 #include "res.h"
 #include "s_auth.h"
@@ -49,6 +50,7 @@
 #include "s_conf.h"
 #include "s_debug.h"
 #include "s_misc.h"
+#include "s_stats.h"
 #include "send.h"
 #include "sys.h"
 #include "uping.h"
@@ -75,6 +77,7 @@
  * External stuff
  *--------------------------------------------------------------------------*/
 extern void init_counters(void);
+extern void mem_dbg_initialise(void);
 
 /*----------------------------------------------------------------------------
  * Constants / Enums
@@ -114,7 +117,8 @@ int running = 1;
 /*----------------------------------------------------------------------------
  * API: server_die
  *--------------------------------------------------------------------------*/
-void server_die(const char* message) {
+void server_die(const char *message)
+{
   /* log_write will send out message to both log file and as server notice */
   log_write(LS_SYSTEM, L_CRIT, 0, "Server terminating: %s", message);
   flush_connections(0);
@@ -122,11 +126,24 @@ void server_die(const char* message) {
   running = 0;
 }
 
+/*----------------------------------------------------------------------------
+ * API: server_panic
+ *--------------------------------------------------------------------------*/
+void server_panic(const char *message)
+{
+  /* inhibit sending server notice--we may be panicing due to low memory */
+  log_write(LS_SYSTEM, L_CRIT, LOG_NOSNOTICE, "Server panic: %s", message);
+  flush_connections(0);
+  log_close();
+  close_connections(1);
+  exit(1);
+}
 
 /*----------------------------------------------------------------------------
  * API: server_restart
  *--------------------------------------------------------------------------*/
-void server_restart(const char* message) {
+void server_restart(const char *message)
+{
   static int restarting = 0;
 
   /* inhibit sending any server notices; we may be in a loop */
@@ -238,7 +255,7 @@ static void try_connections(struct Event* ev) {
   Debug((DEBUG_NOTICE, "Connection check at   : %s", myctime(CurrentTime)));
   for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
     /* Also when already connecting! (update holdtimes) --SRB */
-    if (!(aconf->status & CONF_SERVER) || aconf->port == 0)
+    if (!(aconf->status & CONF_SERVER) || aconf->port == 0 || aconf->hold == 0)
       continue;
 
     /* Also skip juped servers */
@@ -291,7 +308,7 @@ static void try_connections(struct Event* ev) {
       (*pconf = con_conf)->next = 0;
     }
 
-    if (connect_server(con_conf, 0, 0))
+    if (connect_server(con_conf, 0))
       sendto_opmask_butone(0, SNO_OLDSNO, "Connection to %s activated.",
                           con_conf->name);
   }
@@ -344,7 +361,7 @@ static void check_pings(struct Event* ev) {
    
     Debug((DEBUG_DEBUG, "check_pings(%s)=status:%s limit: %d current: %d",
           cli_name(cptr),
-          (cli_flags(cptr) & FLAGS_PINGSENT) ? "[Ping Sent]" : "[]", 
+          IsPingSent(cptr) ? "[Ping Sent]" : "[]", 
           max_ping, (int)(CurrentTime - cli_lasttime(cptr))));
           
 
@@ -358,50 +375,58 @@ static void check_pings(struct Event* ev) {
       continue;
     }
 
+    /* Quit the client after max_ping*2 - they should have answered by now */
+    if (CurrentTime-cli_lasttime(cptr) >= (max_ping*2) )
+    {
+      /* If it was a server, then tell ops about it. */
+      if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
+        sendto_opmask_butone(0, SNO_OLDSNO,
+                             "No response from %s, closing link",
+                             cli_name(cptr));
+      exit_client_msg(cptr, cptr, &me, "Ping timeout");
+      continue;
+    }
+
     /* Unregistered clients pingout after max_ping seconds, they don't
      * get given a second chance - if they were then people could not quite
      * finish registration and hold resources without being subject to k/g
      * lines
      */
-    if (!IsRegistered(cptr)) {
+    if (!IsRegistered(cptr))
+    {
       /* Display message if they have sent a NICK and a USER but no
        * nospoof PONG.
        */
-      if (*(cli_name(cptr)) && cli_user(cptr) && *(cli_user(cptr))->username) {
+      if (*(cli_name(cptr)) && cli_user(cptr) && *(cli_user(cptr))->username)
+      {
        send_reply(cptr, SND_EXPLICIT | ERR_BADPING,
                   ":Your client may not be compatible with this server.");
        send_reply(cptr, SND_EXPLICIT | ERR_BADPING,
-                  ":Compatible clients are available at "
-                  URL_CLIENTS);
+                   ":Compatible clients are available at %s",
+                   feature_str(FEAT_URL_CLIENTS));
       }    
       exit_client_msg(cptr,cptr,&me, "Ping Timeout");
       continue;
     }
     
-    if (!(cli_flags(cptr) & FLAGS_PINGSENT)) {
+    if (!IsPingSent(cptr))
+    {
       /* If we havent PINGed the connection and we havent heard from it in a
        * while, PING it to make sure it is still alive.
        */
-      cli_flags(cptr) |= FLAGS_PINGSENT;
+      SetPingSent(cptr);
 
       /* If we're late in noticing don't hold it against them :) */
       cli_lasttime(cptr) = CurrentTime - max_ping;
       
       if (IsUser(cptr))
-       sendrawto_one(cptr, MSG_PING " :%s", cli_name(&me));
+        sendrawto_one(cptr, MSG_PING " :%s", cli_name(&me));
       else
-       sendcmdto_one(&me, CMD_PING, cptr, ":%s", cli_name(&me));
-    }
-    
-    /* Quit the client after max_ping*2 - they should have answered by now */
-    if (CurrentTime-cli_lasttime(cptr) >= (max_ping*2) ) {
-      /* If it was a server, then tell ops about it. */
-      if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
-       sendto_opmask_butone(0, SNO_OLDSNO,
-                            "No response from %s, closing link",
-                            cli_name(cptr));
-      exit_client_msg(cptr, cptr, &me, "Ping timeout");
-      continue;
+      {
+        char *asll_ts = militime_float(NULL);
+        sendcmdto_one(&me, CMD_PING, cptr, "!%s %s %s", asll_ts,
+                      cli_name(cptr), asll_ts);
+      }
     }
     
     expire = cli_lasttime(cptr) + max_ping * 2;
@@ -572,6 +597,10 @@ int main(int argc, char **argv) {
   thisServer.uid  = getuid();
   thisServer.euid = geteuid();
 
+#ifdef MDEBUG
+  mem_dbg_initialise();
+#endif
+
 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CORE)
   set_core_limit();
 #endif
@@ -604,10 +633,6 @@ int main(int argc, char **argv) {
   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()) {
@@ -633,10 +658,17 @@ int main(int argc, char **argv) {
     return 7;
   }
 
+  if (check_pid()) {
+    Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork"));
+    exit(2);
+  }
+
   init_server_identity();
 
   uping_init();
 
+  stats_init();
+
   IPcheck_init();
   timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1);
   timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1);