]> jfr.im git - irc/quakenet/newserv.git/commitdiff
splitlist: Add splitadd command.
authorPandame <redacted>
Fri, 12 Feb 2016 12:09:39 +0000 (13:09 +0100)
committerPandame <redacted>
Fri, 12 Feb 2016 12:09:39 +0000 (13:09 +0100)
splitlist/splitlist.c
splitlist/splitlist.h
splitlist/splitlist_commands.c

index 29859c31181e60568383f58f8563da78f150f375..4789a0ea7374fe946cf9e0f3a812c653d6c07826 100644 (file)
@@ -12,7 +12,6 @@ array splitlist;
 
 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);
@@ -72,7 +71,7 @@ void sp_deletesplit(const char *name) {
   }
 }
 
-static void sp_addsplit(const char *name, time_t ts, flag_t type) {
+void sp_addsplit(const char *name, time_t ts, flag_t type) {
   int slot;
   splitserver *srv;
 
index eaa2e0eed0ac1a138fe3794647dde71a3d130a7b..21e079923249ec9396f23a3c0288539b89c793d1 100644 (file)
@@ -17,10 +17,10 @@ extern array splitlist;
 
 void sp_deletesplit(const char *name);
 int sp_countsplitservers(flag_t orflags);
-/* I don't see why these are exported... */
+/* I don't see why this is exported... */
 /*
 int sp_issplitserver(const char *name);
-void sp_addsplit(const char *name, time_t ts);
 */
+void sp_addsplit(const char *name, time_t ts, flag_t type);
 
 #endif /* __SPLITLIST_H */
index fc8a4753250cd685319da39b8f02f98bdc8a292f..264a16834fdc737ebbd2cfc46330754917e60b9f 100644 (file)
@@ -1,25 +1,44 @@
 /* oper commands for the splitlist */
 
+#include <errno.h>
+#include <string.h>
+
 #include "../lib/irc_string.h"
 #include "../irc/irc.h"
+#include "../irc/irc_config.h"
 #include "../splitlist/splitlist.h"
 #include "../serverlist/serverlist.h"
 #include "../control/control.h"
 #include "../lib/version.h"
+#include "../lib/flags.h"
 
 MODULE_VERSION("");
 
 int spcmd_splitlist(void *source, int cargc, char **cargv);
 int spcmd_splitdel(void *source, int cargc, char **cargv);
+int spcmd_splitadd(void *source, int cargc, char **cargv);
 
 void _init(void) {
   registercontrolhelpcmd("splitlist", NO_STAFF, 0, &spcmd_splitlist, "Usage: splitlist\nLists servers currently split from the network.");
   registercontrolcmd("splitdel", 10, 1, &spcmd_splitdel);
+  registercontrolhelpcmd("splitadd", 10, 3, &spcmd_splitadd,
+      "Usage: splitadd <servername> [+flags] [split time as unix timestamp]\n"
+      " Adds a server as split from the network.\n"
+      " Flags:\n"
+      "  +c: Client server\n"
+      "  +h: Hub server\n"
+      "  +s: Service\n"
+      "  +Q: Q/CServe\n"
+      "  +S: S/spamscan\n"
+      "  +X: Other critical service\n"
+      " If no flags are given, an attempt to figure them out based on name\n"
+      " will be made, but it's likely not a good one.\n");
 }
 
 void _fini(void) {
   deregistercontrolcmd("splitlist", &spcmd_splitlist);
   deregistercontrolcmd("splitdel", &spcmd_splitdel);
+  deregistercontrolcmd("splitadd", &spcmd_splitadd);
 }
 
 /* todo: add RELINK status */
@@ -73,3 +92,81 @@ int spcmd_splitdel(void *source, int cargc, char **cargv) {
 
   return CMD_OK;
 }
+
+int spcmd_splitadd(void *source, int cargc, char **cargv) {
+  nick *np = (nick*)source;
+  unsigned long long num;
+  char *end;
+  flag_t servertype = 0;
+  char *servername;
+  size_t servernamelen;
+  time_t splittime;
+  server fake;
+
+  if (cargc < 1) {
+      controlreply(np, "Usage: splitadd <servername> [+flags] [split time as unix timestamp]");
+      return CMD_ERROR;
+  }
+
+  servername = cargv[0];
+  servernamelen = strlen(servername);
+
+  if (findserver(servername) != -1) {
+    controlreply(np, "Server %s is linked right now, refusing to add split.",
+        servername);
+    return CMD_ERROR;
+  }
+
+  if (servernamelen > SERVERLEN) {
+    controlreply(np, "Server name %s is too long (max: %d characters)",
+        servername, SERVERLEN);
+    return CMD_ERROR;
+  }
+
+  /* Handle flags */
+  if (cargc > 1) {
+    if (setflags(&servertype, (flag_t)-1, cargv[1], servertypeflags,
+          REJECT_UNKNOWN) != REJECT_NONE) {
+      controlreply(np, "Flag string %s contained invalid flags.\n", cargv[1]);
+      return CMD_ERROR;
+    }
+  } else {
+    /* Set up a fake server for getservertype. */
+    memset(&fake, 0, sizeof(fake));
+
+    fake.name = getsstring(servername, servernamelen);
+    servertype = getservertype(&fake);
+    freesstring(fake.name);
+  }
+
+  /* Handle timestamp */
+  if (cargc < 3) {
+    splittime = getnettime();
+  } else {
+    errno = 0;
+    num = strtoull(cargv[2], &end, 10);
+    if (errno == ERANGE) {
+      controlreply(np, "%s is out of range for a timestamp.\n", cargv[2]);
+      return CMD_ERROR;
+    }
+
+    /* Truncation may happen here. 
+     * However, there's no way to get the max time_t value, so we'll just try to
+     * find out after the fact.
+     */
+    splittime = (time_t)num;
+
+    if ((unsigned long long)splittime < num) {
+      controlreply(np, "Tried to use %llu as split time value, but it's too "
+          "large for the system to handle", num);
+      return CMD_ERROR;
+    }
+  }
+
+  sp_addsplit(servername, splittime, servertype);
+  controlreply(np, "Added split for %s (%s ago) with flags %s.",
+      servername, longtoduration(getnettime() - splittime, 1),
+      printflags(servertype, servertypeflags));
+
+  return CMD_OK;
+}