]> jfr.im git - irc/quakenet/newserv.git/commitdiff
SPLITLIST/SERVERLIST: Add logic to determine the type of server.
authorChris Porter <redacted>
Sat, 25 Feb 2012 03:51:34 +0000 (03:51 +0000)
committerChris Porter <redacted>
Sat, 25 Feb 2012 03:51:34 +0000 (03:51 +0000)
chanfix/chanfix.c
request/request.c
serverlist/Makefile.in
serverlist/serverlist.c
splitlist/splitlist.c
splitlist/splitlist.h
splitlist/splitlist_commands.c

index 31698d94106e3eaf4801d06d32788787d7511625..01a5a1c64f60a537c0b968c3d79db1f2293be9b8 100644 (file)
@@ -446,7 +446,7 @@ int cfcmd_chanfix(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
-  if (sp_countsplitservers() > 0) {
+  if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0) {
     controlreply(np, "Chanfix cannot be used during a netsplit.");
 
     return CMD_ERROR;
@@ -586,7 +586,7 @@ int cfcmd_requestop(void *source, int cargc, char **cargv) {
     }
   }
 
-  if (sp_countsplitservers() > 0) {
+  if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0) {
     controlreply(np, "One or more servers are currently split. Wait until the"
                  " netsplit is over and try again.");
 
@@ -689,7 +689,7 @@ void cfsched_dosample(void *arg) {
 
   cfuhost = cfscore = cfnewro = 0;
 
-  if (sp_countsplitservers() > CFMAXSPLITSERVERS)
+  if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > CFMAXSPLITSERVERS)
     return;
 
   gettimeofday(&start, NULL);
@@ -857,7 +857,7 @@ void cfhook_autofix(int hook, void *arg) {
       hook == HOOK_CHANNEL_KICK || hook == HOOK_CHANNEL_JOIN) {
     cp = args[0];
 
-    if (sp_countsplitservers() > 0)
+    if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0)
       return;
 
     for(a=0;a<cp->users->hashsize;a++) {
index 2cd84a36f824be51743445040a9d5162a77758e1..1d04e6202c9d7bba24b75aa675da61791105e679 100644 (file)
@@ -535,7 +535,7 @@ int rqcmd_requestop(void *source, int cargc, char **cargv) {
     }
   }
 
-  if (sp_countsplitservers() > 0) {
+  if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0) {
     sendnoticetouser(rqnick, np, "One or more servers are currently split. Wait until the"
                    " netsplit is over and try again.");
 
index 3ab82de3468019c6eccbaeceb565a7cfe9e828bf..3f8162f9602443565480e75a49a60b1576cd8cfc 100644 (file)
@@ -1,5 +1,8 @@
 @include@ @includel@../build.mk@includel@\r
 \r
+CFLAGS+=$(INCPCRE)\r
+LDFLAGS+=$(LIBPCRE)\r
+\r
 .PHONY: all\r
 all: serverlist.so\r
 \r
index 47e9ba7c52f51b0eba673524d7af8f9de1422463..b045636dec09b77747b9d061305a59e92ac871f8 100644 (file)
@@ -6,27 +6,60 @@
 #include "../control/control.h"
 #include "../usercount/usercount.h"
 #include "../lib/version.h"
+#include "../serverlist/serverlist.h"
+#include "../core/config.h"
+#include "../lib/strlfunc.h"
 
 MODULE_VERSION("")
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <pcre.h>
 
 int cmd_serverlist(void *sender, int cargc, char **cargv);
 void serverlist_hook_newserver(int hook, void *arg);
 void serverlist_hook_lostserver(int hook, void *arg);
 int serverlist_versionreply(void *source, int cargc, char **cargv);
 
+const flag servertypeflags[] = {
+  { 'c', SERVERTYPEFLAG_CLIENT_SERVER },
+  { 'h', SERVERTYPEFLAG_HUB },
+  { 's', SERVERTYPEFLAG_SERVICE },
+  { 'Q', SERVERTYPEFLAG_CHANSERV },
+  { 'S', SERVERTYPEFLAG_SPAMSCAN },
+  { 'X', SERVERTYPEFLAG_CRITICAL_SERVICE },
+  { '\0', 0 }
+};
+
 struct {
   int used;
   time_t ts;
   sstring *version1;
   sstring *version2;
+  flag_t type;
 } serverinfo[MAXSERVERS];
 
 void serverlist_doversion(void);
 
+static sstring *s_server, *q_server;
+static pcre *service_re, *hub_re, *not_client_re;
+
+static pcre *compilefree(sstring *re) {
+  const char *err;
+  int erroffset;
+  pcre *r;
+
+  r = pcre_compile(re->content, 0, &err, &erroffset, NULL);
+  if(r == NULL) {
+    Error("serverlist", ERR_WARNING, "Unable to compile RE %s (offset: %d, reason: %s)", re->content, erroffset, err);
+    freesstring(re);
+    return NULL;
+  }
+
+  freesstring(re);
+  return r;
+}
 
 void _init(void) {
   registercontrolhelpcmd("serverlist",NO_OPER,1,&cmd_serverlist,"Usage: serverlist [pattern]\nShows all currently connected servers");
@@ -35,6 +68,13 @@ void _init(void) {
   registerhook(HOOK_SERVER_LOSTSERVER, &serverlist_hook_lostserver);
   int i;
 
+  q_server = getcopyconfigitem("serverlist", "q_server", "CServe.quakenet.org", HOSTLEN);
+  s_server = getcopyconfigitem("serverlist", "s_server", "services2.uk.quakenet.org", HOSTLEN);
+
+  service_re = compilefree(getcopyconfigitem("serverlist", "service_re", "^services\\d*\\..*$", 256));
+  hub_re = compilefree(getcopyconfigitem("serverlist", "hub_re", "^hub\\d*\\..*$", 256));
+  not_client_re = compilefree(getcopyconfigitem("serverlist", "not_client_re", "^(testserv\\d*\\.|irc\\.ipv6\\.).*$", 256));
+
   for (i = 0; i < MAXSERVERS; i++) {
     if (serverlist[i].linkstate == LS_LINKED)
       serverinfo[i].used = 1;
@@ -44,9 +84,9 @@ void _init(void) {
     serverinfo[i].ts = getnettime();
     serverinfo[i].version1 = NULL;
     serverinfo[i].version2 = NULL;
+    serverinfo[i].type = getservertype(&serverlist[i]);
   }
   registernumerichandler(351, &serverlist_versionreply, 2);
-
 }
 
 void _fini(void) {
@@ -63,13 +103,20 @@ void _fini(void) {
   deregisterhook(HOOK_SERVER_LOSTSERVER, &serverlist_hook_lostserver);
 
   deregistercontrolcmd("serverlist",cmd_serverlist);
+
+  freesstring(q_server);
+  freesstring(s_server);
+  pcre_free(service_re);
+  pcre_free(hub_re);
+  pcre_free(not_client_re);
 }
 
 int cmd_serverlist(void *sender, int cargc, char **cargv) {
   nick *np = (nick*)sender;
   int a, i, ucount, acount, scount;
+  char buf[512];
 
-  controlreply(np, "%-7s %-30s %5s/%5s/%-5s %-7s %-15s %-20s", "Numeric", "Hostname", "ECl", "Cl", "MaxCl", "Flags", "Connected for", "Version");
+  controlreply(np, "%-7s %-30s %5s/%5s/%-5s %-7s %-7s %-15s %-20s", "Numeric", "Hostname", "ECl", "Cl", "MaxCl", "Flags", "Type", "Connected for", "Version");
 
   scount = acount = 0;
 
@@ -84,9 +131,11 @@ int cmd_serverlist(void *sender, int cargc, char **cargv) {
       acount += ucount;
       scount++;
 
-      controlreply(np, "%-7d %-30s %5d/%5d/%-5d %-7s %-15s %-20s - %s", i, serverlist[i].name->content,
+      strlcpy(buf, printflags(serverinfo[i].type, servertypeflags), sizeof(buf));
+
+      controlreply(np, "%-7d %-30s %5d/%5d/%-5d %-7s %-7s %-15s %-20s - %s", i, serverlist[i].name->content,
             servercount[i], ucount, serverlist[i].maxusernum,
-            printflags(serverlist[i].flags, smodeflags),
+            printflags(serverlist[i].flags, smodeflags), buf,
             longtoduration(getnettime() - serverinfo[i].ts, 0),
             serverinfo[i].version1 ? serverinfo[i].version1->content : "Unknown",
             serverinfo[i].version2 ? serverinfo[i].version2->content : "Unknown");
@@ -142,13 +191,14 @@ void serverlist_hook_newserver(int hook, void *arg) {
   char *num1, *numeric;
   long num = (long)arg;
 
-  if (mynick == NULL)
-    return;
-
   serverinfo[num].used = 1;
   serverinfo[num].ts = getnettime();
   serverinfo[num].version1 = NULL;
   serverinfo[num].version2 = NULL;
+  serverinfo[num].type = getservertype(&serverlist[num]);
+
+  if (mynick == NULL) /* bleh this is buggy... doesn't do it when mynick appears */
+    return;
 
   numeric = longtonumeric(mynick->numeric,5);
   num1 = (char*)malloc(strlen(numeric) + 1); /* bleh.. longtonumeric() is using static variables */
@@ -167,3 +217,57 @@ void serverlist_hook_lostserver(int hook, void *arg) {
   freesstring(serverinfo[num].version2);
 }
 
+flag_t getservertype(server *server) {
+  flag_t result = 0;
+  char *server_name;
+  int server_len;
+
+  if(server == NULL || server->name == NULL)
+    return 0;
+
+  server_name = server->name->content;
+  server_len = server->name->length;
+
+  if(server->flags & SMODE_SERVICE)
+    result|=SERVERTYPEFLAG_SERVICE;
+
+  if(!strcmp(server_name, q_server->content)) {
+    result|=SERVERTYPEFLAG_CHANSERV;
+    result|=SERVERTYPEFLAG_CRITICAL_SERVICE;
+  } else if(!strcmp(server_name, s_server->content)) {
+    result|=SERVERTYPEFLAG_SPAMSCAN;
+    result|=SERVERTYPEFLAG_CRITICAL_SERVICE;
+  } else {
+    if(service_re && (pcre_exec(service_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+      /* matches service re */
+      if((server->flags & SMODE_SERVICE) == 0) {
+        /* is not a service */
+        Error("serverlist", ERR_WARNING, "Non-service server (%s) matched service RE.", server_name);
+      }
+    } else {
+      /* does not match service re */
+      if((server->flags & SMODE_SERVICE) != 0) {
+        result|=SERVERTYPEFLAG_SERVICE;
+        Error("serverlist", ERR_WARNING, "Service server (%s) that does not match service RE.", server_name);
+      }
+    }
+  }
+
+  if(hub_re && (pcre_exec(hub_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+    if((server->flags & SMODE_HUB) != 0) {
+      result|=SERVERTYPEFLAG_HUB;
+    } else {
+      Error("serverlist", ERR_WARNING, "Server matched hub re but isn't a hub (%s).", server_name);
+    }
+  }
+
+
+  if(not_client_re && (pcre_exec(not_client_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+    /* noop */
+  } else if(result == 0) {
+    result|=SERVERTYPEFLAG_CLIENT_SERVER;
+  }
+
+  return result;
+}
+
index 88cf39356e0514bb29e899f628cc37278de93725..29859c31181e60568383f58f8563da78f150f375 100644 (file)
@@ -10,8 +10,9 @@ MODULE_VERSION("");
 
 array splitlist;
 
-void sphook_newserver(int hook, void *arg);
-void sphook_lostserver(int hook, void *arg);
+static void sphook_newserver(int hook, void *arg);
+static void sphook_lostserver(int hook, void *arg);
+static void sp_addsplit(const char *name, time_t ts, flag_t flags);
 
 void _init(void) {
   registerhook(HOOK_SERVER_NEWSERVER, &sphook_newserver);
@@ -21,7 +22,7 @@ void _init(void) {
   array_setlim1(&splitlist, 5);
   array_setlim2(&splitlist, 5);
 
-  sp_addsplit("default.split.quakenet.org", getnettime());
+  sp_addsplit("default.split.quakenet.org", getnettime(), SERVERTYPEFLAG_CRITICAL_SERVICE | SERVERTYPEFLAG_SERVICE);
 }
 
 void _fini(void) {
@@ -37,27 +38,24 @@ void _fini(void) {
   array_free(&splitlist);
 }
 
-void sphook_newserver(int hook, void *arg) {
+static void sphook_newserver(int hook, void *arg) {
   sp_deletesplit(serverlist[(long)arg].name->content);
 }
 
-void sphook_lostserver(int hook, void *arg) {
-  sp_addsplit(serverlist[(long)arg].name->content, getnettime());
+static void sphook_lostserver(int hook, void *arg) {
+  server *server = &serverlist[(long)arg];
+  sp_addsplit(server->name->content, getnettime(), getservertype(server));
 }
 
-int sp_countsplitservers(void) {
-  return splitlist.cursi;
-}
-
-int sp_issplitserver(const char *name) {
+int sp_countsplitservers(flag_t orflags) {
+  int result = 0;
   int i;
 
-  for (i = 0; i < splitlist.cursi; i++) {
-    if (strcmp(name, ((splitserver*)splitlist.content)[i].name->content) == 0)
-      return 1;
-  }
+  for (i = 0; i < splitlist.cursi; i++)
+    if((((splitserver*)splitlist.content)[i].type | orflags) != 0)
+      result++;
 
-  return 0;
+  return result;
 }
 
 void sp_deletesplit(const char *name) {
@@ -74,7 +72,7 @@ void sp_deletesplit(const char *name) {
   }
 }
 
-void sp_addsplit(const char *name, time_t ts) {
+static void sp_addsplit(const char *name, time_t ts, flag_t type) {
   int slot;
   splitserver *srv;
 
@@ -84,4 +82,5 @@ void sp_addsplit(const char *name, time_t ts) {
 
   srv->name = getsstring(name, HOSTLEN);
   srv->ts = ts;
+  srv->type = type;
 }
index a8a0726daf4b3b0dbdf154c4991ca1cd3f008107..eaa2e0eed0ac1a138fe3794647dde71a3d130a7b 100644 (file)
@@ -3,19 +3,24 @@
 
 #include <time.h>
 #include "../server/server.h"
+#include "../serverlist/serverlist.h"
 #include "../lib/array.h"
+#include "../lib/flags.h"
 
 typedef struct {
   sstring        *name;      /* name of the server */
   time_t         ts;         /* timestamp of the split */
+  flag_t         type;
 } splitserver;
 
 extern array splitlist;
 
-int sp_countsplitservers(void);
-int sp_issplitserver(const char *name);
 void sp_deletesplit(const char *name);
+int sp_countsplitservers(flag_t orflags);
+/* I don't see why these are exported... */
+/*
+int sp_issplitserver(const char *name);
 void sp_addsplit(const char *name, time_t ts);
-int sp_countsplitservers(void);
+*/
 
 #endif /* __SPLITLIST_H */
index 6255baa65848827130097388bd08b5cbc1b9b8e9..fc8a4753250cd685319da39b8f02f98bdc8a292f 100644 (file)
@@ -3,6 +3,7 @@
 #include "../lib/irc_string.h"
 #include "../irc/irc.h"
 #include "../splitlist/splitlist.h"
+#include "../serverlist/serverlist.h"
 #include "../control/control.h"
 #include "../lib/version.h"
 
@@ -12,7 +13,7 @@ int spcmd_splitlist(void *source, int cargc, char **cargv);
 int spcmd_splitdel(void *source, int cargc, char **cargv);
 
 void _init(void) {
-  registercontrolhelpcmd("splitlist", NO_STAFF, 0, &spcmd_splitlist, "Usage: splitlist\nLists servers currently split from the netowkr");
+  registercontrolhelpcmd("splitlist", NO_STAFF, 0, &spcmd_splitlist, "Usage: splitlist\nLists servers currently split from the network.");
   registercontrolcmd("splitdel", 10, 1, &spcmd_splitdel);
 }
 
@@ -38,7 +39,7 @@ int spcmd_splitlist(void *source, int cargc, char **cargv) {
   for (i = 0; i < splitlist.cursi; i++) {
     srv = ((splitserver*)splitlist.content)[i];
 
-    controlreply(np, "%s M.I.A. %s", srv.name->content, longtoduration(getnettime() - srv.ts, 1));
+    controlreply(np, "%s M.I.A. %s (%s)", srv.name->content, longtoduration(getnettime() - srv.ts, 1), printflags(srv.type, servertypeflags));
   }
 
   controlreply(np, "--- End of splitlist");