]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Link parents and children into a tree!
authorChris Porter <redacted>
Fri, 3 Oct 2008 23:26:35 +0000 (00:26 +0100)
committerChris Porter <redacted>
Fri, 3 Oct 2008 23:26:35 +0000 (00:26 +0100)
Trustlist now displays trees.

trusts/data.c
trusts/db.c
trusts/trusts.h
trusts/trusts_commands.c

index c0784394e96fcd78284c01de09bd84e3625d0395..b19e875792dfa5d202ab127bb1f6a703baee4651 100644 (file)
@@ -13,6 +13,8 @@ trustgroup *tglist;
 void th_dbupdatecounts(trusthost *);
 void tg_dbupdatecounts(trustgroup *);
 
+static trusthost *th_getnextchildbyhost(trusthost *, trusthost *);
+
 void trusts_freeall(void) {
   trustgroup *tg, *ntg;
   trusthost *th, *nth;
@@ -45,8 +47,38 @@ void th_free(trusthost *th) {
   nsfree(POOL_TRUSTS, th);
 }
 
+static void th_updatechildren(trusthost *th) {
+  trusthost *nth = NULL;
+
+  th->children = NULL;
+
+  for(;;) {
+    nth = th_getnextchildbyhost(th, nth);
+    if(!nth)
+      break;
+
+    nth->nextbychild = th->children;
+    th->children = nth;
+  }
+}
+
+void th_linktree(void) {
+  trustgroup *tg;
+  trusthost *th;
+
+  /* ugh */
+  for(tg=tglist;tg;tg=tg->next)
+    for(th=tg->hosts;th;th=th->next)
+      th->parent = th_getsmallestsupersetbyhost(th->ip, th->mask);
+
+  for(tg=tglist;tg;tg=tg->next)
+    for(th=tg->hosts;th;th=th->next)
+      if(th->parent)
+        th_updatechildren(th->parent);
+}
+
 trusthost *th_add(trustgroup *tg, unsigned int id, char *host, unsigned int maxusage, time_t lastseen) {
-  u_int32_t ip, mask;
+  uint32_t ip, mask;
   trusthost *th;
 
   if(!trusts_str2cidr(host, &ip, &mask))
@@ -66,6 +98,9 @@ trusthost *th_add(trustgroup *tg, unsigned int id, char *host, unsigned int maxu
   th->group = tg;
   th->count = 0;
 
+  th->parent = NULL;
+  th->children = NULL;
+
   th->next = tg->hosts;
   tg->hosts = th;
 
@@ -183,6 +218,40 @@ trusthost *th_getsubsetbyhost(uint32_t ip, uint32_t mask) {
   return NULL;
 }
 
+/* NOT reentrant obviously */
+static trusthost *th_getnextchildbyhost(trusthost *orig, trusthost *th) {
+  if(!th) {
+    trustgroup *tg;
+
+    tg = tglist;
+    for(tg=tglist;tg;tg=tg->next) {
+      th = tg->hosts;
+      if(th)
+        break;
+    }
+
+    /* INVARIANT: tg => th */
+    if(!tg)
+      return NULL;
+
+    if(th->parent == orig)
+      return th;
+  }
+
+  for(;;) {
+    if(th->next) {
+      th = th->next;
+    } else {
+      if(!th->group->next)
+        return NULL;
+      th = th->group->next->hosts;
+    }
+
+    if(th->parent == orig)
+      return th;
+  }
+}
+
 void th_getsuperandsubsets(uint32_t ip, uint32_t mask, trusthost **superset, trusthost **subset) {
   *superset = th_getsmallestsupersetbyhost(ip, mask);
   *subset = th_getsubsetbyhost(ip, mask);
index a740a616e4d2f8528f1d288a44a813575bc447e3..ae4af07eb79727538b07d2c9d097985a0e2bc52e 100644 (file)
@@ -48,6 +48,7 @@ static void loadcomplete(void) {
   if(loaderror)
     return;
 
+  th_linktree();
   trustsdbloaded = 1;
   flushschedule = schedulerecurring(time(NULL) + 300, 0, 300, flushdatabase, NULL);
 
@@ -250,6 +251,7 @@ trusthost *th_new(trustgroup *tg, char *host) {
 
   th_adjusthosts(th, subset, superset);
 
+  th_linktree();
   return th;
 }
 
index c596b080e058e42c9fce4d81956a8adc458be946..9437c96f2c70ba095c75a30bc626ec228c029c3a 100644 (file)
@@ -31,6 +31,9 @@ typedef struct trusthost {
 
   unsigned int count;
 
+  struct trusthost *parent, *children;
+  struct trusthost *nextbychild;
+
   struct trusthost *next;
 } trusthost;
 
@@ -92,7 +95,9 @@ trusthost *th_getsmallestsupersetbyhost(uint32_t, uint32_t);
 trustgroup *tg_strtotg(char *);
 void th_adjusthosts(trusthost *th, trusthost *, trusthost *);
 void th_getsuperandsubsets(uint32_t, uint32_t, trusthost **, trusthost **);
-trusthost *th_getsubsetbyhost(uint32_t, uint32_t);
+trusthost *th_getsubsetbyhost(uint32_t ip, uint32_t mask);
+trusthost *th_getnextsubsetbyhost(trusthost *th, uint32_t ip, uint32_t mask);
+void th_linktree(void);
 
 /* migration.c */
 typedef void (*TrustMigrationGroup)(void *, unsigned int, char *, unsigned int, unsigned int, unsigned int, unsigned int, time_t, time_t, time_t, char *, char *, char *);
index d403f94cfaaba46ac4058c0a5ac6875fa58f4991..7085df4e4b777406273b0674b0e7b4da65f6950a 100644 (file)
@@ -1,6 +1,8 @@
 #include <stdio.h>
+#include <string.h>
 #include "../control/control.h"
 #include "../lib/irc_string.h"
+#include "../lib/strlfunc.h"
 #include "trusts.h"
 
 int trusts_migration_start(TrustDBMigrationCallback, void *);
@@ -49,6 +51,81 @@ static int trusts_cmdmigrate(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
+void calculatespaces(int spaces, char *str, char **_prebuf, char **_postbuf) {
+  static char prebuf[512], postbuf[512];
+  int spacelen;
+
+  if(spaces + 5 >= sizeof(prebuf)) {
+    prebuf[0] = prebuf[1] = '\0';
+  } else {
+    memset(prebuf, ' ', spaces);
+    prebuf[spaces] = '\0';
+  }
+
+  spacelen = 21 - (strlen(str) + spaces);
+  if(spacelen <= 0 || spacelen + 5 >= sizeof(postbuf)) {
+    postbuf[0] = postbuf[1] = '\0';
+  } else {
+    memset(postbuf, ' ', spacelen);
+    postbuf[spacelen] = '\0';
+  }
+
+  *_prebuf = prebuf;
+  *_postbuf = postbuf;
+}
+
+#define MODE_PARENT   0
+#define MODE_CURRENT  1
+#define MODE_CHILDREN 2
+
+static int __replytrusthosts(nick *sender, trusthost *th, int mode, int childdepth) {
+  char parentbuf[512], *postspacebuf, *prespacebuf, *cidrstr;
+  int depth;
+
+  if(mode != MODE_CHILDREN) {
+    /* find all parents of this node */
+    if(th->parent) {
+      depth = __replytrusthosts(sender, th->parent, MODE_PARENT, 0) + 1;
+    } else {
+      depth = 1;
+    }
+  } else {
+    depth = childdepth;
+  }
+
+  cidrstr = trusts_cidr2str(th->ip, th->mask);
+  calculatespaces(depth, cidrstr, &prespacebuf, &postspacebuf);
+
+  if(mode == MODE_CURRENT) {
+    /* prefix the hosts in the current group with > */
+
+    if(!prespacebuf[0])
+      prespacebuf[1] = '\0';
+    prespacebuf[0] = '>';
+
+    parentbuf[0] = '\0';
+  } else {
+    /* show the ids of other groups */
+
+    snprintf(parentbuf, sizeof(parentbuf), "%-10d %s", th->id, th->group->name->content);
+  }
+
+  controlreply(sender, "%s%s%s %-10d %-10d %-20s%s", prespacebuf, cidrstr, postspacebuf, th->count, th->maxusage, (th->count>0)?"(now)":((th->lastseen>0)?trusts_timetostr(th->lastseen):"(never)"), parentbuf);
+
+  /* find all children of this node */
+  if(mode != MODE_PARENT) {
+    trusthost *cth;
+    for(cth=th->children;cth;cth=cth->nextbychild)
+      __replytrusthosts(sender, cth, MODE_CHILDREN, depth + 1);
+  }
+
+  return depth;
+}
+
+static void replytrusthosts(nick *sender, trusthost *th) {
+  __replytrusthosts(sender, th, MODE_CURRENT, 0);
+}
+
 static int trusts_cmdtrustlist(void *source, int cargc, char **cargv) {
   nick *sender = source;
   trustgroup *tg;
@@ -80,10 +157,10 @@ static int trusts_cmdtrustlist(void *source, int cargc, char **cargv) {
   controlreply(sender, "Max usage        : %d", tg->maxusage);
   controlreply(sender, "Last max reset   : %s", tg->lastmaxuserreset?trusts_timetostr(tg->lastmaxuserreset):"(never)");
 
-  controlreply(sender, "Host                 Current    Max        Last seen");
+  controlreply(sender, "Host                 Current    Max        Last seen           Group ID   Group name");
 
   for(th=tg->hosts;th;th=th->next)
-    controlreply(sender, " %-20s %-10d %-10d %s", trusts_cidr2str(th->ip, th->mask), th->count, th->maxusage, (th->count>0)?"(now)":((th->lastseen>0)?trusts_timetostr(th->lastseen):"(never)"));
+    replytrusthosts(sender, th);
 
   controlreply(sender, "End of list.");