]> jfr.im git - irc/quakenet/newserv.git/commitdiff
add my version of trusts, trusts_newsearch, trusts_search modules
authorPaul <redacted>
Sat, 4 Oct 2008 20:56:14 +0000 (21:56 +0100)
committerPaul <redacted>
Sat, 4 Oct 2008 20:56:14 +0000 (21:56 +0100)
40 files changed:
trusts2/Makefile.in [new file with mode: 0644]
trusts2/trusts.c [new file with mode: 0644]
trusts2/trusts.h [new file with mode: 0644]
trusts2/trusts_alloc.c [new file with mode: 0644]
trusts2/trusts_db.c [new file with mode: 0644]
trusts2/trusts_groups.c [new file with mode: 0644]
trusts2/trusts_handlers.c [new file with mode: 0644]
trusts2/trusts_hash.c [new file with mode: 0644]
trusts2/trusts_hosts.c [new file with mode: 0644]
trusts2/trusts_ident.c [new file with mode: 0644]
trusts2/trustscmd.c [new file with mode: 0644]
trusts_newsearch/Makefile.in [new file with mode: 0644]
trusts_newsearch/formats.c [new file with mode: 0644]
trusts_newsearch/trusts_newsearch.c [new file with mode: 0644]
trusts_newsearch/trusts_newsearch.h [new file with mode: 0644]
trusts_newsearch/tsns-currenton.c [new file with mode: 0644]
trusts_newsearch/tsns-enforceident.c [new file with mode: 0644]
trusts_newsearch/tsns-maxclones.c [new file with mode: 0644]
trusts_newsearch/tsns-ownerid.c [new file with mode: 0644]
trusts_newsearch/tsns-tgcreated.c [new file with mode: 0644]
trusts_newsearch/tsns-tgexpire.c [new file with mode: 0644]
trusts_newsearch/tsns-tgid.c [new file with mode: 0644]
trusts_newsearch/tsns-tglastused.c [new file with mode: 0644]
trusts_newsearch/tsns-tgmaxperident.c [new file with mode: 0644]
trusts_newsearch/tsns-tgmaxperip.c [new file with mode: 0644]
trusts_newsearch/tsns-tgmaxusage.c [new file with mode: 0644]
trusts_newsearch/tsns-tgmodified.c [new file with mode: 0644]
trusts_newsearch/tsns-tgstartdate.c [new file with mode: 0644]
trusts_newsearch/tsns-thcreated.c [new file with mode: 0644]
trusts_newsearch/tsns-thexpire.c [new file with mode: 0644]
trusts_newsearch/tsns-thid.c [new file with mode: 0644]
trusts_newsearch/tsns-thlastused.c [new file with mode: 0644]
trusts_newsearch/tsns-thmaxusage.c [new file with mode: 0644]
trusts_newsearch/tsns-thmodified.c [new file with mode: 0644]
trusts_newsearch/tsns-thstartdate.c [new file with mode: 0644]
trusts_newsearch/tsns-trusted.c [new file with mode: 0644]
trusts_search/Makefile.in [new file with mode: 0644]
trusts_search/formats.c [new file with mode: 0644]
trusts_search/trusts_search.c [new file with mode: 0644]
trusts_search/trusts_search.h [new file with mode: 0644]

diff --git a/trusts2/Makefile.in b/trusts2/Makefile.in
new file mode 100644 (file)
index 0000000..65a1cb7
--- /dev/null
@@ -0,0 +1,10 @@
+@include@ @includel@../build.mk@includel@
+
+CFLAGS+=$(INCDBAPI)
+LDFLAGS+=$(LIBDBAPI)
+
+.PHONY: all
+
+all: trusts.so
+
+trusts.so: trusts_ident.o trusts_hosts.o trusts_groups.o trusts_alloc.o trusts.o trusts_handlers.o trusts_hash.o trusts_db.o trustscmd.o
diff --git a/trusts2/trusts.c b/trusts2/trusts.c
new file mode 100644 (file)
index 0000000..417e9d3
--- /dev/null
@@ -0,0 +1,141 @@
+#include "trusts.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../core/nsmalloc.h"
+
+int tgh_ext;
+static int trusts_loaded;
+
+static void trusts_status(int hooknum, void *arg);
+
+void _init(void) {
+  trusts_hash_init();
+
+  tgh_ext = registernodeext("trusthost");
+  if ( !tgh_ext ) {
+    Error("trusts", ERR_FATAL, "Could not register a required node extension");
+    return;
+  }
+
+  if ( !trusts_load_db()) {
+    return;
+  }
+  trusts_loaded = 1;
+  trusts_cmdinit();
+
+  registerhook(HOOK_NICK_NEWNICK, &trusts_hook_newuser);
+  registerhook(HOOK_NICK_LOSTNICK, &trusts_hook_lostuser);
+
+  registerhook(HOOK_CORE_STATSREQUEST, trusts_status);
+}
+
+void _fini(void) {
+  trusthost_t *thptr;
+  trustgroupidentcount_t *t;
+  int i;
+  for ( i = 0; i < TRUSTS_HASH_HOSTSIZE ; i++ ) {
+    for ( thptr = trusthostidtable[i]; thptr; thptr = thptr-> nextbyid ) {
+      derefnode(iptree,thptr->node);
+    }
+  }
+  releasenodeext(tgh_ext); 
+
+  if ( trusts_loaded ) {
+    trusts_cmdfini();
+
+    deregisterhook(HOOK_NICK_NEWNICK, &trusts_hook_newuser);
+    deregisterhook(HOOK_NICK_LOSTNICK, &trusts_hook_lostuser);
+
+    deregisterhook(HOOK_CORE_STATSREQUEST, trusts_status);
+  }
+
+  for ( i = 0; i < TRUSTS_HASH_IDENTSIZE ; i++ ) {
+    for ( t = trustgroupidentcounttable[i]; t; t = t-> next ) {
+      if (t->ident) {
+        freesstring(t->ident);
+      }
+    }
+  }
+
+  /* @@@ CLOSE DB */
+
+  trusts_hash_fini();
+
+  nsfreeall(POOL_TRUSTS);
+}
+
+void increment_trust_ipnode(patricia_node_t *node) {
+  patricia_node_t *parent;
+  trusthost_t *tgh = NULL;
+  time_t curtime = getnettime();
+  parent = node;
+  while (parent) {
+    if(parent->exts && parent->exts[tgh_ext]) {
+      /* update the trusted hosts themselves */
+      tgh = (trusthost_t *)parent->exts[tgh_ext];
+      tgh->lastused = curtime;
+      if (tgh->node->usercount > tgh->maxused) { tgh->maxused = tgh->node->usercount; }
+
+      /* update the trustgroup itself */
+      tgh->trustgroup->currenton++;
+      tgh->trustgroup->lastused = curtime;
+      if (tgh->trustgroup->currenton > tgh->trustgroup->maxusage) { tgh->trustgroup->maxusage = tgh->trustgroup->currenton; }
+    }
+    parent = parent->parent;
+  }
+}
+
+void decrement_trust_ipnode(patricia_node_t *node) {
+  patricia_node_t *parent;
+  trusthost_t *tgh = NULL;
+  time_t curtime = getnettime();
+
+  parent = node;
+  while (parent) {
+    if(parent->exts && parent->exts[tgh_ext]) {
+      tgh = (trusthost_t *)parent->exts[tgh_ext];
+      tgh->trustgroup->currenton--;
+      tgh->lastused = curtime;
+
+      tgh->trustgroup->lastused = curtime;
+    }
+    parent = parent->parent;
+  }
+}
+
+void trust_debug(char *format, ...) {
+  char buf[512];
+  va_list va;
+  channel *debugcp = findchannel("#qnet.trusts");
+  if(debugcp) {
+     va_start(va, format);
+     vsnprintf(buf, sizeof(buf), format, va);
+     va_end(va);
+    controlchanmsg(debugcp,buf);
+  }
+}
+
+static void trusts_status(int hooknum, void *arg) {
+  if((long)arg > 10) {
+    char message[100];
+    int tgcount = 0, thcount = 0; 
+    trustgroup_t *tg; trusthost_t* thptr; int i;
+
+    for ( i = 0; i < TRUSTS_HASH_GROUPSIZE ; i++ ) {
+      for ( tg = trustgroupidtable[i]; tg; tg = tg -> nextbyid ) {
+        tgcount++;
+      }
+    }
+
+    for ( i = 0; i < TRUSTS_HASH_HOSTSIZE ; i++ ) {
+      for ( thptr = trusthostidtable[i]; thptr; thptr = thptr-> nextbyid ) {
+        thcount++;
+      }
+    }
+    snprintf(message, sizeof(message), "Trusts  :%7d groups, %7d hosts", tgcount, thcount);
+    triggerhook(HOOK_CORE_STATSREPLY, message);
+  }
+
+}
diff --git a/trusts2/trusts.h b/trusts2/trusts.h
new file mode 100644 (file)
index 0000000..4b96f09
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+
+ * trust.h:
+ *  Top level data structures and function prototypes for the
+ *  trusts service module
+ */
+
+#ifndef __TRUST_H
+#define __TRUST_H
+
+#include <string.h>
+
+#include "../lib/irc_ipv6.h"
+#include "../core/schedule.h"
+#include "../lib/irc_string.h"
+#include "../localuser/localuserchannel.h"
+#include "../control/control.h"
+#include "../patricia/patricia.h"
+#include "../dbapi/dbapi.h"
+#include "../patricianick/patricianick.h"
+#include "../nick/nick.h"
+
+#define TRUSTS_HASH_GROUPSIZE 500
+#define TRUSTS_HASH_HOSTSIZE 1000
+#define TRUSTS_HASH_IDENTSIZE 50
+
+#define TRUSTS_MAXGROUPNAMELEN 20
+
+extern int tgh_ext;
+
+typedef struct trusthost_s {
+        /* Details */
+        unsigned long id;
+        patricia_node_t* node;
+        time_t startdate;
+        time_t lastused;
+        time_t expire;
+        unsigned long maxused;
+
+        /* Trust group */
+        struct trustgroup_s* trustgroup;
+
+        time_t created;
+        time_t modified;
+
+        /* Hash table */
+        struct trusthost_s* nextbyid;
+        struct trusthost_s* nextbygroupid;
+} trusthost_t;
+
+typedef struct trustgroup_s {
+        /* Details */
+        unsigned long id;
+        unsigned long maxusage, currenton;
+        unsigned long maxclones, maxperident;
+        unsigned short maxperip;
+        int enforceident;
+        time_t startdate,lastused, expire;
+        unsigned long ownerid;
+        int type;
+
+        time_t created;
+        time_t modified;
+
+        /* Hash table */
+        struct trustgroup_s* nextbyid;
+} trustgroup_t;
+
+typedef struct trustgroupidentcount_s {
+        /* Ident */
+        sstring *ident;
+
+        /* Trust group */
+        struct trustgroup_s* trustgroup;
+
+        /* Counter */
+        unsigned long currenton;
+
+        /* Hash table */
+        struct trustgroupidentcount_s* next;
+} trustgroupidentcount_t;
+
+typedef struct trustblock_s {
+  unsigned long id;
+  patricia_node_t* node;
+  unsigned long ownerid;
+  time_t expire;
+  time_t startdate;
+  sstring* reason_private;
+  sstring* reason_public;
+  struct trustblock_s* next;
+} trustblock_t;
+
+/* trusts hash tables */
+extern trustgroup_t *trustgroupidtable[TRUSTS_HASH_GROUPSIZE];
+extern trustgroup_t *trustgroupnametable[TRUSTS_HASH_GROUPSIZE];
+extern trusthost_t *trusthostidtable[TRUSTS_HASH_HOSTSIZE];
+extern trusthost_t *trusthostgroupidtable[TRUSTS_HASH_HOSTSIZE];
+extern trustgroupidentcount_t *trustgroupidentcounttable[TRUSTS_HASH_IDENTSIZE];
+
+#define trusts_gettrustgroupidhash(x) ((x)%TRUSTS_HASH_GROUPSIZE)
+#define trusts_gettrustgroupnamehash(x) ((crc32i(x))%TRUSTS_HASH_GROUPSIZE)
+#define trusts_gettrusthostidhash(x) ((x)%TRUSTS_HASH_HOSTSIZE)
+#define trusts_gettrusthostgroupidhash(x) ((x)%TRUSTS_HASH_HOSTSIZE)
+#define trusts_gettrustgroupidenthash(x) ((crc32i(x))%TRUSTS_HASH_IDENTSIZE)
+
+/* trusts_hash.c */
+void trusts_hash_init();
+void trusts_hash_fini();
+
+void trusts_addtrusthosttohash(trusthost_t *newhost);
+void trusts_removetrusthostfromhash(trusthost_t *t);
+
+void trusts_addtrustgrouptohash(trustgroup_t *newgroup);
+void trusts_removetrustgroupfromhash(trustgroup_t *t);
+
+void trusts_addtrustgroupidenttohash(trustgroupidentcount_t *newident);
+void trusts_removetrustgroupidentfromhash(trustgroupidentcount_t *t);
+
+trustgroup_t* findtrustgroupbyid(int id);
+trustgroup_t* findtrustgroupbyownerid(int ownerid);
+
+trustgroupidentcount_t* findtrustgroupcountbyident(char *ident, trustgroup_t *t);
+
+trustgroupidentcount_t *getnewtrustgroupidentcount(trustgroup_t *tg, char *ident);
+
+unsigned long trusts_lasttrustgroupid, trusts_lasttrusthostid, trusts_lasttrustblockid;
+
+void trust_debug(char *format, ...);
+
+/* trusts alloc */
+trustgroup_t *newtrustgroup();
+void freetrustgroup (trustgroup_t *trustgroup);
+trusthost_t *newtrusthost();
+void freetrusthost (trusthost_t *trusthost);
+trustgroupidentcount_t *newtrustgroupidentcount();
+void freetrustgroupidentcount (trustgroupidentcount_t *trustgroupidentcount);
+trustblock_t *newtrustblock();
+void freetrustblock (trustblock_t *trustblock);
+
+/* trusts db */
+int trusts_load_db(void);
+void trusts_create_tables(void);
+void trusts_cleanup_db(void);
+void trusts_loadtrustgroups(DBConn *dbconn, void *arg);
+void trusts_loadtrusthosts(DBConn *dbconn, void *arg);
+void trusts_loadtrustblocks(DBConn *dbconn, void *arg);
+void trustsdb_addtrustgroup(trustgroup_t *t);
+void trustsdb_updatetrustgroup(trustgroup_t *t);
+void trustsdb_deletetrustgroup(trustgroup_t *t);
+void trustsdb_addtrusthost(trusthost_t *th);
+void trustsdb_updatetrusthost(trusthost_t *th);
+void trustsdb_deletetrusthost(trusthost_t *th);
+void trustsdb_addtrustblock(trustblock_t *tb);
+void trustsdb_updatetrustblock(trustblock_t *tb);
+void trustsdb_deletetrustblock(trustblock_t *tb);
+void trustsdb_logmessage(trustgroup_t *tg, unsigned long userid, int type, char *message);
+
+/* trusts handlers */
+void trusts_hook_newuser(int hook, void *arg);
+void trusts_hook_lostuser(int hook, void *arg);
+
+/* trusts groups */
+
+trustgroup_t *createtrustgroupfromdb(unsigned long id, unsigned long maxusage, unsigned long maxclones, unsigned long maxperident, unsigned short maxperip, int enforceident, time_t startdate, time_t lastused, time_t expire, unsigned long ownerid, int type, time_t created, time_t modified);
+trustgroup_t *createtrustgroup(unsigned long id, unsigned long maxclones, unsigned long maxperident, unsigned short maxperip, int enforceident, time_t expire, unsigned long ownerid, int type);
+void trustgroup_expire (trustgroup_t *tg);
+void trustgroup_free(trustgroup_t* t);
+
+/* trusts hosts */
+trusthost_t *createtrusthostfromdb(unsigned long id, patricia_node_t* node, time_t startdate, time_t lastused, time_t expire, unsigned long maxused, trustgroup_t* trustgroup, time_t created, time_t modified);
+trusthost_t *createtrusthost(unsigned long id, patricia_node_t* node, time_t expire, trustgroup_t *trustgroup);
+void trusthost_free(trusthost_t* t);
+void trusthost_addcounters(trusthost_t* tgh);
+trusthost_t* trusthostadd(patricia_node_t *node, trustgroup_t* tg, time_t expire);
+void trusthost_expire ( trusthost_t *th);
+
+/* trusts idents */
+void increment_ident_count(nick *np, trustgroup_t *tg);
+void decrement_ident_count(nick *np, trustgroup_t *tg);
+
+/* trusts */
+void decrement_trust_ipnode(patricia_node_t *node);
+void increment_trust_ipnode(patricia_node_t *node);
+
+/* trusts cmds */
+void trusts_cmdinit();
+void trusts_cmdfini();
+
+int trust_groupadd(void *source, int cargc, char **cargv) ;
+int trust_groupmodify(void *source, int cargc, char **cargv) ;
+int trust_groupdel(void *source, int cargc, char **cargv) ;
+int trust_denyadd(void *source, int cargc, char **cargv) ;
+int trust_denydel(void *source, int cargc, char **cargv) ;
+int trust_denylist(void *source, int cargc, char **cargv) ;
+int trust_del(void *source, int cargc, char **cargv) ;
+int trust_add(void *source, int cargc, char **cargv) ;
+int trust_comment(void *source, int cargc, char **cargv) ;
+
+int trust_stats(void *source, int cargc, char **cargv);
+int trust_dump(void *source, int cargc, char **cargv) ;
+#endif
+
diff --git a/trusts2/trusts_alloc.c b/trusts2/trusts_alloc.c
new file mode 100644 (file)
index 0000000..4f1fb7c
--- /dev/null
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <assert.h>
+#include "../core/nsmalloc.h"
+#include "trusts.h"
+
+#define ALLOCUNIT  100
+
+trustgroup_t *trustgroup_freelist;
+trustgroupidentcount_t *trustgroupidentcount_freelist;
+trusthost_t *trusthost_freelist;
+trustblock_t *trustblock_freelist;
+
+trustgroup_t *newtrustgroup() {
+  trustgroup_t *trustgroup;
+  int i;
+
+  if( trustgroup_freelist ==NULL ) {
+    trustgroup_freelist=(trustgroup_t *)nsmalloc(POOL_TRUSTS,ALLOCUNIT*sizeof(trustgroup_t));
+
+    for (i=0;i<(ALLOCUNIT-1);i++) {
+      trustgroup_freelist[i].nextbyid=(trustgroup_t *)&(trustgroup_freelist[i+1]);
+    }
+    trustgroup_freelist[ALLOCUNIT-1].nextbyid=NULL;
+  }
+
+  trustgroup=trustgroup_freelist;
+  trustgroup_freelist=(trustgroup_t *)trustgroup->nextbyid;
+
+  return trustgroup;
+}
+
+void freetrustgroup (trustgroup_t *trustgroup) {
+  trustgroup->nextbyid=(trustgroup_t *)trustgroup_freelist;
+  trustgroup_freelist=trustgroup;
+}
+
+trusthost_t *newtrusthost() {
+  trusthost_t *trusthost;
+  int i;
+
+  if( trusthost_freelist ==NULL ) {
+    trusthost_freelist=(trusthost_t *)nsmalloc(POOL_TRUSTS,ALLOCUNIT*sizeof(trusthost_t));
+
+    for (i=0;i<(ALLOCUNIT-1);i++) {
+      trusthost_freelist[i].nextbyid=(trusthost_t *)&(trusthost_freelist[i+1]);
+    }
+    trusthost_freelist[ALLOCUNIT-1].nextbyid=NULL;
+  }
+
+  trusthost=trusthost_freelist;
+  trusthost_freelist=(trusthost_t *)trusthost->nextbyid;
+
+  return trusthost;
+}
+
+void freetrusthost (trusthost_t *trusthost) {
+  trusthost->nextbyid=(trusthost_t *)trusthost_freelist;
+  trusthost_freelist=trusthost;
+}
+
+
+trustgroupidentcount_t *newtrustgroupidentcount() {
+  trustgroupidentcount_t *trustgroupidentcount;
+  int i;
+
+  if( trustgroupidentcount_freelist ==NULL ) {
+    trustgroupidentcount_freelist=(trustgroupidentcount_t *)nsmalloc(POOL_TRUSTS,ALLOCUNIT*sizeof(trustgroupidentcount_t));
+
+    for (i=0;i<(ALLOCUNIT-1);i++) {
+      trustgroupidentcount_freelist[i].next=(trustgroupidentcount_t *)&(trustgroupidentcount_freelist[i+1]);
+    }
+    trustgroupidentcount_freelist[ALLOCUNIT-1].next=NULL;
+  }
+
+  trustgroupidentcount=trustgroupidentcount_freelist;
+  trustgroupidentcount_freelist=(trustgroupidentcount_t *)trustgroupidentcount->next;
+
+  return trustgroupidentcount;
+}
+
+void freetrustgroupidentcount (trustgroupidentcount_t *trustgroupidentcount) {
+  trustgroupidentcount->next=(trustgroupidentcount_t *)trustgroupidentcount_freelist;
+  trustgroupidentcount_freelist=trustgroupidentcount;
+}
+
+trustblock_t *newtrustblock() {
+  trustblock_t *trustblock;
+  int i;
+
+  if( trustblock_freelist ==NULL ) {
+    trustblock_freelist=(trustblock_t *)nsmalloc(POOL_TRUSTS,ALLOCUNIT*sizeof(trustblock_t));
+
+    for (i=0;i<(ALLOCUNIT-1);i++) {
+      trustblock_freelist[i].next=(trustblock_t *)&(trustblock_freelist[i+1]);
+    }
+    trustblock_freelist[ALLOCUNIT-1].next=NULL;
+  }
+
+  trustblock=trustblock_freelist;
+  trustblock_freelist=(trustblock_t *)trustblock->next;
+
+  return trustblock;
+}
+
+void freetrustblock (trustblock_t *trustblock) {
+  trustblock->next=(trustblock_t *)trustblock_freelist;
+  trustblock_freelist=trustblock;
+}
+
diff --git a/trusts2/trusts_db.c b/trusts2/trusts_db.c
new file mode 100644 (file)
index 0000000..4d5a07b
--- /dev/null
@@ -0,0 +1,281 @@
+#include "../nick/nick.h"
+#include "../core/error.h"
+#include "../lib/irc_string.h"
+#include "../core/schedule.h"
+#include <stdlib.h>
+
+#include "trusts.h"
+
+int trustdb_loaded = 0;
+
+int trusts_load_db(void) {
+  if(!dbconnected()) {
+    Error("trusts", ERR_STOP, "Could not connect to database.");
+    return 0;
+  }
+
+  if(trustdb_loaded)
+    trusts_cleanup_db();
+
+  trustdb_loaded = 1;
+
+  trusts_create_tables();
+
+  dbasyncquery(trusts_loadtrustgroups, NULL,
+    "SELECT trustid,maxusage,maxclones,maxperident,maxperip,enforceident,startdate,lastused,expires,owneruserid,type,created,modified FROM trusts.groups WHERE enddate = 0");
+  dbasyncquery(trusts_loadtrusthosts, NULL,
+    "SELECT * FROM trusts.hosts WHERE enddate = 0");
+  dbasyncquery(trusts_loadtrustblocks, NULL,
+    "SELECT * FROM trusts.blocks");
+
+  return 1;
+}
+
+void trusts_create_tables(void) {
+  dbattach("trusts");
+  dbcreatequery(
+    "CREATE TABLE trusts.groups ("
+    "trustid      INT4 NOT NULL PRIMARY KEY,"
+    "startdate    INT4 NOT NULL,"
+    "enddate      INT4 NOT NULL,"
+    "owneruserid  INT4,"
+    "maxusage     INT4 NOT NULL,"
+    "enforceident INT2 NOT NULL,"
+    "type         INT2,"
+    "maxclones    INT4 NOT NULL,"
+    "maxperident  INT4,"
+    "maxperip     INT4,"
+    "expires      INT4,"
+    "lastused     INT4,"
+    "modified     INT4,"
+    "created      INT4"
+    ") WITHOUT OIDS;"
+    );
+
+  dbcreatequery(
+    "CREATE TABLE trusts.hosts ("
+    "hostid     INT4 NOT NULL PRIMARY KEY,"
+    "trustid    INT4 NOT NULL,"
+    "startdate  INT4 NOT NULL,"
+    "enddate    INT4,"
+    "host       INET NOT NULL,"
+    "maxusage   INT4 NOT NULL,"
+    "lastused   INT4,"
+    "expires    INT4 NOT NULL,"
+    "modified   INT4,"
+    "created    INT4"
+    ") WITHOUT OIDS;"
+    );
+
+  dbcreatequery(
+    "CREATE TABLE trusts.blocks ("
+    "blockid        INT4 NOT NULL PRIMARY KEY,"
+    "block          INET NOT NULL,"
+    "owner          INT4,"
+    "expires        INT4,"
+    "startdate      INT4,"
+    "reason_private VARCHAR,"
+    "reason_public  VARCHAR"
+    ") WITHOUT OIDS;"
+    );
+
+  dbcreatequery(
+    "CREATE TABLE trusts.log ("
+    "logid          SERIAL NOT NULL PRIMARY KEY,"
+    "trustid        INT4 NOT NULL,"
+    "timestamp      INT4 NOT NULL,"
+    "userid         INT4 NOT NULL,"
+    "type           INT2,"
+    "message        VARCHAR"
+    ") WITHOUT OIDS;"
+  );
+}
+
+void trusts_cleanup_db(void) {
+  dbdetach("trusts");
+}
+
+void trusts_loadtrustgroups(DBConn *dbconn, void *arg) {
+  DBResult *pgres = dbgetresult(dbconn);
+  int rows=0;
+  trustgroup_t *t;
+
+  if(!dbquerysuccessful(pgres)) {
+    Error("trusts", ERR_ERROR, "Error loading trustgroup list.");
+    dbclear(pgres);
+    return;
+  }
+
+  trusts_lasttrustgroupid = 1; 
+
+  while(dbfetchrow(pgres)) {
+
+    t = createtrustgroupfromdb( 
+                     /*id*/          strtoul(dbgetvalue(pgres,0),NULL,10),
+                     /*maxusage*/    strtoul(dbgetvalue(pgres,1),NULL,10),
+                     /*maxclones*/   strtoul(dbgetvalue(pgres,2),NULL,10),
+                     /*maxperident*/ strtoul(dbgetvalue(pgres,3),NULL,10),
+                     /*maxperip*/    strtoul(dbgetvalue(pgres,4),NULL,10),
+        /*TODOTYPE*/ /*enforceident*/strtoul(dbgetvalue(pgres,5),NULL,10),
+                     /*startdate*/   strtoul(dbgetvalue(pgres,6),NULL,10),
+                     /*lastused*/    strtoul(dbgetvalue(pgres,7),NULL,10),
+                     /*expire*/      strtoul(dbgetvalue(pgres,8),NULL,10),
+                     /*ownerid*/     strtoul(dbgetvalue(pgres,9),NULL,10),
+                     /*type*/        strtoul(dbgetvalue(pgres,10),NULL,10),
+                     /*created*/     strtoul(dbgetvalue(pgres,11),NULL,10),
+                     /*modified*/    strtoul(dbgetvalue(pgres,12),NULL,10)
+                     );
+    if(t->id > trusts_lasttrustgroupid)
+      trusts_lasttrustgroupid = t->id;
+
+    rows++;
+  }
+
+  Error("trusts",ERR_INFO,"Loaded %d trusts (highest ID was %lu)",rows,trusts_lasttrustgroupid);
+
+  dbclear(pgres);
+}
+
+void trusts_loadtrusthosts(DBConn *dbconn, void *arg) {
+  DBResult *pgres = dbgetresult(dbconn);
+  int rows=0;
+  trusthost_t *t;
+  trustgroup_t *tg;
+  patricia_node_t *node;
+  struct irc_in_addr sin;
+  unsigned char bits;
+
+  if(!dbquerysuccessful(pgres)) {
+    Error("trusts", ERR_ERROR, "Error loading trusthost list.");
+    dbclear(pgres);
+    return;
+  }
+
+  trusts_lasttrusthostid = 1;
+
+  while(dbfetchrow(pgres)) {
+    /*node*/
+    ipmask_parse(dbgetvalue(pgres,4), &sin, &bits);
+    node  = refnode(iptree, &sin, bits);
+
+    /*tg*/
+    int tgid = strtoul(dbgetvalue(pgres,1),NULL,10);
+    tg=findtrustgroupbyid(tgid);
+    if (!tg) { 
+      Error("trusts", ERR_ERROR, "Error loading trusthosts - invalid group: %d.", tgid);
+      continue;
+    }
+
+    t = createtrusthostfromdb( 
+                    /*id*/        strtoul(dbgetvalue(pgres,0),NULL,10),
+                    /*node*/      node,
+                    /*startdate*/ strtoul(dbgetvalue(pgres,2),NULL,10),
+                    /*lastused*/  strtoul(dbgetvalue(pgres,6),NULL,10),
+                    /*expire*/    strtoul(dbgetvalue(pgres,7),NULL,10),
+                    /*maxusage*/  strtoul(dbgetvalue(pgres,5),NULL,10),
+                    /*trustgroup*/ tg,
+                    /*created*/   strtoul(dbgetvalue(pgres,9),NULL,10),
+                    /*modified*/ strtoul(dbgetvalue(pgres,8),NULL,10)
+                  );
+    node = 0;
+    if(t->id > trusts_lasttrusthostid)
+      trusts_lasttrusthostid = t->id;
+
+    trusthost_addcounters(t);
+    rows++;
+  }
+
+  Error("trusts",ERR_INFO,"Loaded %d trusthosts (highest ID was %lu)",rows,trusts_lasttrusthostid);
+
+  dbclear(pgres);
+}
+
+void trusts_loadtrustblocks(DBConn *dbconn, void *arg) {
+  DBResult *pgres = dbgetresult(dbconn);
+  int rows=0;
+  trustblock_t *t;
+
+  if(!dbquerysuccessful(pgres)) {
+    Error("trusts", ERR_ERROR, "Error loading trustblock list.");
+    dbclear(pgres);
+    return;
+  }
+
+  trusts_lasttrustblockid = 1;
+
+  while(dbfetchrow(pgres)) {
+//    t = gettrustblock();
+    if(!t)
+      Error("trusts", ERR_ERROR, "Unable to load trust block");
+
+    t->id = strtoul(dbgetvalue(pgres,0),NULL,10);
+    /* host */
+    t->ownerid = strtoul(dbgetvalue(pgres,3),NULL,10);
+    t->expire = strtoul(dbgetvalue(pgres,11),NULL,10);
+    t->startdate = strtoul(dbgetvalue(pgres,2),NULL,10);
+    /* reason_private */
+    /* reason_public */
+
+    if(t->id > trusts_lasttrustblockid)
+      trusts_lasttrustblockid = t->id;
+
+    //trusts_addtrustgrouptohash(t);
+    rows++;
+  }
+
+  Error("trusts",ERR_INFO,"Loaded %d trustblocks (highest ID was %lu)",rows,trusts_lasttrustblockid);
+
+  dbclear(pgres);
+}
+
+
+/* trust group */
+void trustsdb_addtrustgroup(trustgroup_t *t) {
+  dbquery("INSERT INTO trusts.groups (trustid,startdate,enddate,owneruserid,maxusage,enforceident,type,maxclones,maxperident,maxperip,expires,lastused,modified,created ) VALUES (%lu,%lu,0,%lu,%lu,%d,%d,%lu,%lu,%d,%lu,%lu,%lu,%lu )", t->id,t->startdate,t->ownerid,t->maxusage,t->enforceident,t->type,t->maxclones,t->maxperident,t->maxperip, t->expire, t->lastused, t->modified, t->created ); 
+}
+
+void trustsdb_updatetrustgroup(trustgroup_t *t) {
+  dbquery("UPDATE trusts.groups SET startdate=%lu,owneruserid=%lu,maxusage=%lu,enforceident=%d,type=%d,maxclones=%lu, maxperident=%lu,maxperip=%d,expires=%lu,lastused=%lu,modified=%lu,created=%lu WHERE trustid = %lu", t->startdate, t->ownerid,t->maxusage,t->enforceident,t->type,t->maxclones,t->maxperident,t->maxperip, t->expire, t->lastused, t->modified, t->created, t->id);
+}
+
+void trustsdb_deletetrustgroup(trustgroup_t *t) {
+  dbquery("UPDATE trusts.groups SET enddate = %jd WHERE trustid = %lu", (intmax_t)getnettime(), t->id);
+}
+
+/* trust host */
+void trustsdb_addtrusthost(trusthost_t *th) {
+  dbquery("INSERT INTO trusts.hosts (hostid,trustid,startdate,enddate,host,maxusage,lastused,expires,modified,created) VALUES (%lu,%lu,%lu,0,'%s/%d',%lu,%lu,%lu,%lu,%lu)", th->id, th->trustgroup->id, th->startdate, IPtostr(th->node->prefix->sin),irc_bitlen(&(th->node->prefix->sin),th->node->prefix->bitlen), th->maxused, th->lastused, th->expire, th->modified, th->created);
+}
+
+void trustsdb_updatetrusthost(trusthost_t *th) {
+  dbquery("UPDATE trusts.hosts SET hostid=%lu,trustid=%lu,startdate=%lu,host='%s/%d',maxusage=%lu,lastused=%lu,expires=%lu,modified=%lu,created=%lu", th->id, th->trustgroup->id, th->startdate, IPtostr(th->node->prefix->sin), irc_bitlen(&(th->node->prefix->sin),th->node->prefix->bitlen), th->maxused, th->lastused, th->expire, th->modified, th->created);
+}
+
+void trustsdb_deletetrusthost(trusthost_t *th) {
+  dbquery("UPDATE trusts.hosts SET enddate = %jd WHERE hostid = %lu", (intmax_t)getnettime(), th->id);
+}
+
+/* trust block */
+void trustsdb_addtrustblock(trustblock_t *tb) {
+  dbquery("INSERT INTO trusts.blocks ( blockid,block,owner,expires,startdate,reason_private,reason_public) VALUES (%lu,'%s/%d',%lu,%lu,%lu,'%s','%s')",tb->id, IPtostr(tb->node->prefix->sin), irc_bitlen(&(tb->node->prefix->sin),tb->node->prefix->bitlen), tb->ownerid, tb->expire, tb->startdate, tb->reason_private->content, tb->reason_public->content);
+}
+
+void trustsdb_updatetrustblock(trustblock_t *tb) {
+  dbquery("UPDATE trusts.blocks SET blockid=%lu,block='%s/%d',owner=%lu,expires=%lu,startdate=%lu,reason_private='%s',reason_public='%s'", tb->id, IPtostr(tb->node->prefix->sin), irc_bitlen(&(tb->node->prefix->sin),tb->node->prefix->bitlen), tb->ownerid, tb->expire, tb->startdate, tb->reason_private->content, tb->reason_public->content);
+}
+
+void trustsdb_deletetrustblock(trustblock_t *tb) {
+  dbquery("DELETE from trusts.blocks WHERE blockid = %lu", tb->id);
+}
+
+/* trust log */
+/* logid, trustid, timestamp, userid, type, message */
+/* @@@ TODO */
+
+void trustsdb_logmessage(trustgroup_t *tg, unsigned long userid, int type, char *message) {
+  /* maximum length of a trustlog message is ircd max length */
+  char escmessage[2*512+1];
+  
+  dbescapestring(escmessage,message, strlen(message)); 
+  dbquery("INSERT INTO trusts.log (trustid, timestamp, userid, type, message) VALUES ( %lu, %lu, %lu, %d, '%s')", tg->id, getnettime(), userid, type, escmessage);
+}
diff --git a/trusts2/trusts_groups.c b/trusts2/trusts_groups.c
new file mode 100644 (file)
index 0000000..2d1af41
--- /dev/null
@@ -0,0 +1,63 @@
+#include "trusts.h"
+
+trustgroup_t *createtrustgroupfromdb(unsigned long id,
+ unsigned long maxusage, unsigned long maxclones, unsigned long maxperident, unsigned short maxperip, int enforceident, time_t startdate, time_t lastused, time_t expire, unsigned long ownerid, int type, time_t created, time_t modified){
+  trustgroup_t *tg = createtrustgroup(id, maxclones, maxperident, maxperip, enforceident, expire, ownerid,type);
+  tg->maxusage = maxusage;
+  // currenton
+  tg->startdate = startdate;
+  tg->lastused = lastused;
+  tg->created = created;
+  tg->modified = modified;
+  return tg;
+}
+trustgroup_t *createtrustgroup(unsigned long id, unsigned long maxclones, unsigned long maxperident, unsigned short maxperip, int enforceident, time_t expire, unsigned long ownerid, int type) {
+  trustgroup_t *tg = newtrustgroup();
+
+  time_t timenow = getnettime();
+
+  tg->id = id;
+  tg->maxusage = 0;
+  tg->currenton = 0;
+  tg->maxclones = maxclones;
+  tg->maxperident = maxperident;
+  tg->maxperip = maxperip;
+  tg->enforceident = enforceident;
+  tg->startdate = timenow;
+  tg->lastused = 0;
+  tg->expire = expire;
+  tg->ownerid = ownerid;
+  tg->type = type;
+  tg->created = timenow;
+  tg->modified = timenow;
+  trusts_addtrustgrouptohash(tg);
+  return tg;
+}
+
+void trustgroup_free(trustgroup_t* t)
+{
+  trusts_removetrustgroupfromhash(t);
+  freetrustgroup(t);
+}
+
+void trustgroup_expire (trustgroup_t *tg) {
+  trusthost_t *thptr, *nthptr;
+  /* set expire to 0 so we can call trusthost_expire without it bouncing back */
+  tg->expire = 0;
+
+  /* first expiry any trust hosts */
+  int hash = trusts_gettrusthostgroupidhash(tg->id);
+  thptr = trusthostgroupidtable[hash];
+  while (thptr) {
+    nthptr = thptr;
+    thptr=thptr->nextbygroupid;
+    if(nthptr->trustgroup == tg) {
+      trusthost_expire(nthptr);
+    }
+  }
+
+  /* secondly expire trust group */
+  controlwall(NO_OPER, NL_TRUSTS, "expired trustgroup #%lu",tg->id); 
+  trustsdb_deletetrustgroup(tg);
+  trustgroup_free(tg);
+}
diff --git a/trusts2/trusts_handlers.c b/trusts2/trusts_handlers.c
new file mode 100644 (file)
index 0000000..f7003ce
--- /dev/null
@@ -0,0 +1,127 @@
+#include "trusts.h"
+
+void trusts_hook_newuser(int hook, void *arg) {
+  /*TODO: add subnet clone warnings somewhere */
+  nick *np = (nick *)arg;
+  trusthost_t *tgh = NULL;
+  trustgroup_t *tg = NULL;
+  patricia_node_t *parent;
+
+  if(np->ipnode->exts[tgh_ext]) {
+    /* we have a new user on a trust group host */
+    tgh = (trusthost_t *)np->ipnode->exts[tgh_ext];
+    /* check if it has expired */ 
+    if(tgh->expire && (tgh->expire <= getnettime())) {
+      trusthost_expire(tgh);
+      tgh = NULL;
+    } else {
+      tg = tgh->trustgroup;
+      if(tg->expire && (tg->expire <= getnettime())) {
+        /* expire trust group */
+        trustgroup_expire(tg);
+        tgh = NULL;
+      }
+    } 
+  }
+
+  if (!tgh) {
+    /* recurse to see if a parent node is trusted */
+    parent = np->ipnode->parent;
+    while (parent) {
+      if(parent->exts)
+        if( parent->exts[tgh_ext]) {
+          /* falls under parent trust */
+          tgh = (trusthost_t *)parent->exts[tgh_ext];
+          if(tgh->expire && (tgh->expire <= getnettime())) {
+            trusthost_expire(tgh);
+            tgh = NULL;
+          } else {
+            tg = tgh->trustgroup;
+            if(tg->expire && (tg->expire <= getnettime())) {
+              /* expire trust group */
+              trustgroup_expire(tg);
+              tgh = NULL;
+            } else {
+              break; 
+            }
+          }
+        }
+      parent = parent->parent;
+    }
+  }
+
+  if(tgh) {
+    /* we have a trusthost - check it */
+    tg = tgh->trustgroup;
+    if(((((int)(np->ipnode->usercount))) > tg->maxperip) && tg->maxperip ) {
+      /* user exceed ip trust limit - disconnect */
+      controlwall(NO_OPER, NL_TRUSTS, "KILL TG %lu: Exceeding IP limit (%d / %d) for %s!%s@%s", tg->id, (((int)(np->ipnode->usercount))), tg->maxperip, np->nick, np->ident, np->host->name->content);
+      //killuser(NULL, np, "USER: Exceeding IP Limit.");
+    }
+    if( tg->maxclones >0 ) {
+      if( (tg->currenton + 1) > tg->maxclones) {
+        /* user exceeds trust group limit - disconnect */
+        //killuser(NULL, np, "USER: Exceeding Trustgroup Limit.");
+        controlwall(NO_OPER, NL_TRUSTS, "KILL TG %lu: Excedding trustgroup limit (%d / %d) for %s!%s@%s",tg->id, (tg->currenton + 1), tg->maxclones, np->nick, np->ident, np->host->name->content);
+      }
+    }
+    if ( np->ident[0] == '~')  {
+      /* non-ident user */
+      if (tg->enforceident ) {
+        controlwall(NO_OPER, NL_TRUSTS, "KILL TG %lu: Ident Required for %s!%s@%s", tg->id, np->nick, np->ident, np->host->name->content);
+        //killuser(NULL, np, "USER: Ident Required From Your Host.");
+        /*TODO: add short gline here - ~*@%s - "IDENTD required from your host", "MissingIDENT" */
+      }
+    } else {
+      /* ident user */
+      /*TODO: need to tidy out ident currenton */
+      increment_ident_count(np, tg);
+    }
+    /* Trust Checks Passed: OK - increment counters */
+    increment_trust_ipnode(np->ipnode);
+    return;
+  }
+  /* non trusted user - OK */
+}
+
+
+void trusts_hook_lostuser(int hook, void *arg) {
+  nick *np = (nick *)arg;
+  trusthost_t *tgh = NULL;
+  trustgroup_t *tg = NULL;
+  patricia_node_t *parent;
+
+  if(!np) {
+    Error("nodecount", ERR_ERROR, "np was NULL");
+  }
+  if(!np->ipnode) {
+    Error("nodecount", ERR_ERROR, "np->ipnode was NULL");
+  }
+  if(!np->ipnode->exts) {
+    Error("nodecount", ERR_ERROR, "np->ipnode->exts was NULL");
+  }
+
+  decrement_trust_ipnode(np->ipnode);
+
+  if(np->ipnode->exts[tgh_ext]) {
+    tgh = (trusthost_t *)np->ipnode->exts[tgh_ext];
+  } else {
+    parent = np->ipnode->parent;
+    while (parent) {
+      if(parent->exts)
+        if( parent->exts[tgh_ext]) {
+          /* falls under parent trust */
+          tgh = (trusthost_t *)parent->exts[tgh_ext];
+          break;
+        }
+      parent = parent->parent;
+    }
+  }
+  if(tgh) {
+    tg = tgh->trustgroup;
+    if ( np->ident[0] != '~')  {
+      decrement_ident_count(np, tg);
+    }
+  }
+}
+
diff --git a/trusts2/trusts_hash.c b/trusts2/trusts_hash.c
new file mode 100644 (file)
index 0000000..38c4210
--- /dev/null
@@ -0,0 +1,137 @@
+#include "trusts.h"
+
+trustgroup_t *trustgroupidtable[TRUSTS_HASH_GROUPSIZE];
+trustgroup_t *trustgroupnametable[TRUSTS_HASH_GROUPSIZE];
+trusthost_t *trusthostidtable[TRUSTS_HASH_HOSTSIZE];
+trusthost_t *trusthostgroupidtable[TRUSTS_HASH_HOSTSIZE];
+trustgroupidentcount_t *trustgroupidentcounttable[TRUSTS_HASH_IDENTSIZE];
+
+void trusts_hash_init() {
+  memset(trustgroupidtable,0,sizeof(trustgroupidtable));
+  memset(trustgroupnametable,0,sizeof(trustgroupnametable));
+  memset(trusthostidtable,0,sizeof(trusthostidtable));
+  memset(trusthostgroupidtable,0,sizeof(trusthostgroupidtable));
+}
+
+void trusts_hash_fini() {
+}
+
+void trusts_addtrusthosttohash(trusthost_t *newhost)
+{
+  unsigned int hash;
+  hash = trusts_gettrusthostidhash(newhost->id);
+  newhost->nextbyid = trusthostidtable[hash];
+  trusthostidtable[hash] = newhost;
+
+  hash = trusts_gettrusthostgroupidhash(newhost->trustgroup->id);
+  newhost->nextbygroupid = trusthostgroupidtable[hash];
+  trusthostgroupidtable[hash] = newhost;
+}
+
+void trusts_removetrusthostfromhash(trusthost_t *t)
+{
+  trusthost_t **tgh;
+  int found = 0;
+  for(tgh=&(trusthostidtable[trusts_gettrusthostidhash(t->id)]);*tgh;tgh=(trusthost_t **)&((*tgh)->nextbyid)) {
+    if((*tgh)==t) {
+      (*tgh)=(trusthost_t *)t->nextbyid;
+      found = 1;
+      break;
+    }
+  }
+  if(!found)
+    Error("trusts",ERR_ERROR,"Unable to remove trusthost id %lu from hashtable", t->id);
+  found = 0;
+  for(tgh=&(trusthostgroupidtable[trusts_gettrusthostgroupidhash(t->trustgroup->id)]);*tgh;tgh=(trusthost_t **)&((*tgh)->nextbygroupid)) {
+    if((*tgh)==t) {
+      (*tgh)=(trusthost_t *)t->nextbygroupid;
+      found = 1;
+      break;
+    }
+  }
+  if(!found)
+    Error("trusts",ERR_ERROR,"Unable to remove trusthost groupid %lu from hashtable", t->trustgroup->id);
+}
+
+void trusts_addtrustgrouptohash(trustgroup_t *newgroup)
+{
+  unsigned int hash;
+  hash = trusts_gettrustgroupidhash(newgroup->id);
+  newgroup->nextbyid = trustgroupidtable[hash];
+  trustgroupidtable[hash] = newgroup;
+}
+
+trustgroup_t* findtrustgroupbyid(int id) {
+  trustgroup_t* tl;
+  for(tl=trustgroupidtable[trusts_gettrustgroupidhash(id)]; tl; tl = (trustgroup_t *)tl->nextbyid) { 
+    if(tl->id == id) {
+      return tl;
+    }
+  }
+  return NULL;
+}
+
+trustgroup_t* findtrustgroupbyownerid(int ownerid) {
+  trustgroup_t* tg;
+  int i;
+
+  for ( i = 0; i < TRUSTS_HASH_GROUPSIZE ; i++ ) {
+    for ( tg = trustgroupidtable[i]; tg; tg = tg -> nextbyid ) {
+      if(tg->ownerid == ownerid) {
+        return tg;
+      }
+    }
+  }
+  return NULL;
+}
+
+
+void trusts_removetrustgroupfromhash(trustgroup_t *t)
+{
+  trustgroup_t **tg;
+  int found = 0;
+  for(tg=&(trustgroupidtable[trusts_gettrustgroupidhash(t->id)]);*tg;tg=(trustgroup_t **)&((*tg)->nextbyid)) {
+    if((*tg)==t) {
+      (*tg)=(trustgroup_t *)t->nextbyid;
+      found = 1;
+      break;
+    }
+  }
+  if (!found)
+    Error("trusts",ERR_ERROR,"Unable to remove trustgroup ID %lu from hashtable",t->id);
+}
+
+void trusts_addtrustgroupidenttohash(trustgroupidentcount_t *newident)
+{
+  unsigned int hash;
+  hash = trusts_gettrustgroupidenthash(newident->ident->content);
+  newident->next = trustgroupidentcounttable[hash];
+  trustgroupidentcounttable[hash] = newident;
+}
+
+void trusts_removetrustgroupidentfromhash(trustgroupidentcount_t *t)
+{
+  trustgroupidentcount_t **thi;
+  for(thi=&(trustgroupidentcounttable[trusts_gettrustgroupidenthash(t->ident->content)]);*thi;thi=(trustgroupidentcount_t **)&((*thi)->next)) {
+    if((*thi)==t) {
+      (*thi)=(trustgroupidentcount_t *)t->next;
+      return; 
+    }
+  }
+  Error("trusts",ERR_ERROR,"Unable to remove trustgroup ident %s from group %lu from hashtable",t->ident->content, t->trustgroup->id);
+}
+
+trustgroupidentcount_t* findtrustgroupcountbyident(char *ident, trustgroup_t *t) {
+  trustgroupidentcount_t* tgi;
+
+  for(tgi=trustgroupidentcounttable[trusts_gettrustgroupidenthash(ident)]; tgi; tgi = (trustgroupidentcount_t *)tgi->next) {
+    if(tgi->trustgroup == t) {
+      if(ircd_strcmp(tgi->ident->content,ident)==0) {
+        return tgi;
+      }
+    }
+  }
+  return NULL;
+}
+
diff --git a/trusts2/trusts_hosts.c b/trusts2/trusts_hosts.c
new file mode 100644 (file)
index 0000000..dc7059a
--- /dev/null
@@ -0,0 +1,116 @@
+#include "trusts.h"
+
+trusthost_t *createtrusthostfromdb(unsigned long id, patricia_node_t* node, time_t startdate, time_t lastused, time_t expire, unsigned long maxused, trustgroup_t* trustgroup, time_t created, time_t modified){
+  trusthost_t *th = createtrusthost(id,node,expire,trustgroup);
+
+  th->startdate=startdate;
+  th->lastused = lastused;
+  th->maxused = maxused;
+  th->created = created;
+  th->modified = modified;
+  return th;
+}
+
+trusthost_t *createtrusthost(unsigned long id, patricia_node_t* node, time_t expire, trustgroup_t *trustgroup) {
+  trusthost_t *th = newtrusthost();
+  memset(th, 0, sizeof(trusthost_t));
+
+  time_t timenow = getnettime();
+
+  th->id = id;
+  th->node = node;
+  th->expire = expire;
+  th->trustgroup = trustgroup;
+  th->created = timenow;
+  th->modified = timenow;
+  th->lastused = 0;
+  trusts_addtrusthosttohash(th);
+  return th;
+}
+
+void trusthost_free(trusthost_t* t)
+{
+  trusts_removetrusthostfromhash(t);
+  derefnode(iptree,t->node);
+  freetrusthost(t);
+}
+
+trusthost_t* trusthostadd(patricia_node_t *node, trustgroup_t* tg, time_t expire) {
+  trusthost_t* tgh = createtrusthost(++trusts_lasttrusthostid, node, expire, tg);
+  patricia_node_t *inode;
+  nick *np;
+  patricianick_t *pnp;
+  int i;
+  time_t timenow;
+
+  if(!tgh) {
+    return NULL;
+  }
+
+  timenow = getnettime();
+  if(node->usercount >0){
+    tgh->lastused = timenow;
+    tg->currenton += node->usercount;
+    tg->lastused = timenow;
+  }
+  tgh->expire = expire;
+
+  PATRICIA_WALK(node, inode)
+  {
+    pnp = inode->exts[pnode_ext];
+    if (pnp ) {
+      for (i = 0; i < PATRICIANICK_HASHSIZE; i++) {
+        for (np = pnp->identhash[i]; np; np=np->exts[pnick_ext]) {
+          increment_ident_count(np, tg);
+        }
+      }
+    }
+  }
+  PATRICIA_WALK_END;
+
+  node->exts[tgh_ext] = tgh;
+
+  return tgh;
+}
+
+void trusthost_addcounters(trusthost_t* tgh) {
+  patricia_node_t *inode;
+  nick *np;
+  patricianick_t *pnp;
+  int i;
+
+  trustgroup_t* tg = tgh->trustgroup;
+  if(tgh->node->usercount >0){
+    tg->currenton += tgh->node->usercount;
+  }
+
+  PATRICIA_WALK(tgh->node, inode)
+  {
+    pnp = inode->exts[pnode_ext];
+    if (pnp ) {
+      for (i = 0; i < PATRICIANICK_HASHSIZE; i++) {
+        for (np = pnp->identhash[i]; np; np=np->exts[pnick_ext]) {
+          increment_ident_count(np, tg);
+        }
+      }
+    }
+  }
+  PATRICIA_WALK_END;
+
+  tgh->node->exts[tgh_ext] = tgh;
+}
+
+
+void trusthost_expire( trusthost_t *th) {
+  trustgroup_t *tg = th->trustgroup;
+
+  if(tg->expire && (tg->expire <= getnettime())) {
+    /* check if trustgroup also expires */
+    trustgroup_expire(tg);
+  } else {
+    controlwall(NO_OPER, NL_TRUSTS, "%s/%d expired from trustgroup #%lu",IPtostr(th->node->prefix->sin),irc_bitlen(&(th->node->prefix->sin),th->node->prefix->bitlen),tg->id);
+    trustsdb_deletetrusthost(th->node->exts[tgh_ext]);
+    trusthost_free(th->node->exts[tgh_ext]);
+    th->node->exts[tgh_ext] = NULL;
+  }
+}
diff --git a/trusts2/trusts_ident.c b/trusts2/trusts_ident.c
new file mode 100644 (file)
index 0000000..448cd55
--- /dev/null
@@ -0,0 +1,43 @@
+#include "trusts.h"
+
+trustgroupidentcount_t *getnewtrustgroupidentcount(trustgroup_t *tg, char *ident) {
+  trustgroupidentcount_t *tgic = newtrustgroupidentcount();
+  tgic->ident = getsstring(ident,USERLEN);
+  tgic->currenton = 1;
+  tgic->trustgroup = tg;
+
+  trusts_addtrustgroupidenttohash(tgic);
+  return tgic;
+}
+
+void increment_ident_count(nick *np, trustgroup_t *tg) {
+  trustgroupidentcount_t* identcnt;
+  identcnt = findtrustgroupcountbyident(np->ident,tg);
+  if(identcnt) {
+    /* ident exists */
+    if( tg->maxperident && (identcnt->currenton+1) > tg->maxperident) {
+      trust_debug("NEWNICK TRUSTED BAD USER: Exceeding User (%s) Ident Limit (%d/%d)",np->ident, identcnt->currenton+1, tg->maxperident);
+      //killuser(NULL, np, "USER: Exceeding User Ident Limit.");
+    }
+    identcnt->currenton++;
+  } else {
+    /* we have a new user to add */
+    getnewtrustgroupidentcount( tg, np->ident );
+  }
+}
+
+void decrement_ident_count(nick *np, trustgroup_t *tg) {
+  trustgroupidentcount_t* identcnt;
+  identcnt = findtrustgroupcountbyident(np->ident,tg);
+  if(identcnt) {
+    identcnt->currenton--;
+    if(identcnt->currenton == 0) {
+      trusts_removetrustgroupidentfromhash(identcnt);
+      if (identcnt->ident) {
+        freesstring(identcnt->ident);
+      }
+      freetrustgroupidentcount(identcnt);
+    }
+  }
+}
+
diff --git a/trusts2/trustscmd.c b/trusts2/trustscmd.c
new file mode 100644 (file)
index 0000000..c271617
--- /dev/null
@@ -0,0 +1,718 @@
+#include "../core/schedule.h"
+#include "../lib/irc_string.h"
+#include "../localuser/localuserchannel.h"
+#include "../control/control.h"
+#include "trusts.h"
+#include <string.h>
+
+void trusts_cmdinit() {
+  registercontrolcmd("trustgroupadd",10,7,trust_groupadd);
+  registercontrolcmd("trustgroupmodify",10,4,trust_groupmodify);
+  registercontrolcmd("trustgroupdel",10,2,trust_groupdel);
+
+  registercontrolcmd("trustcomment",10,2,trust_comment);
+
+  registercontrolcmd("trustadd",10,3,trust_add);
+  registercontrolcmd("trustdel",10,2,trust_del);
+
+  registercontrolcmd("trustdenyadd",10,2,trust_denyadd);
+  registercontrolcmd("trustdenylist",10,2,trust_denylist);
+  registercontrolcmd("trustdenydel",10,2,trust_denydel);
+
+  registercontrolcmd("truststats",10,2,trust_stats);
+  registercontrolcmd("trustdump",10,2,trust_dump);
+}
+
+void trusts_cmdfini() {
+  deregistercontrolcmd("trustgroupadd",trust_groupadd);
+  deregistercontrolcmd("trustgroupmodify",trust_groupmodify);
+  deregistercontrolcmd("trustgroupdel",trust_groupdel);
+
+  deregistercontrolcmd("trustcomment",trust_comment);
+
+  deregistercontrolcmd("trustadd",trust_add);
+  deregistercontrolcmd("trustdel",trust_del);
+
+  deregistercontrolcmd("trustdenyadd",trust_denyadd);
+  deregistercontrolcmd("trustdenylist",trust_denylist);
+  deregistercontrolcmd("trustdenydel",trust_denydel);
+
+  deregistercontrolcmd("truststats",trust_stats);
+  deregistercontrolcmd("trustdump",trust_dump);
+}
+
+/*TODO*/
+/* tgh - should this have a 'maxclones limit'? */
+
+int trust_groupadd(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  int expiry;
+  unsigned long maxclones;
+  unsigned short maxperip;
+  unsigned long  maxperident;
+  int enforceident;
+  int type;
+  unsigned long ownerid;
+  trustgroup_t *t;
+
+  if (cargc < 7) {
+    controlreply(sender,"Usage: trustgroupadd howmany howlong maxperident maxperip enforceident type ownerid");
+    return CMD_ERROR;
+  }
+
+  maxclones = strtoul(cargv[0],NULL,10);
+  if ( maxclones > 10000 ) { 
+    /* we allow 0 for unlimited trusts, and only warn on this */
+    controlreply(sender, "WARNING: large maximum number of clients - %lu", maxclones);
+  }
+  expiry = durationtolong(cargv[1]);
+  if (expiry > (365 * 86400) ) {
+    controlreply(sender,"ERROR: Invalid duration given - temporary trusts can not be longer then 1 year");
+    return CMD_ERROR;
+  }
+  ownerid  = strtoul(cargv[6],NULL,10);
+  maxperip = strtoul(cargv[3],NULL,10);
+  if (maxperip > 500) {
+    controlreply(sender, "ERROR: MaxPerIP value should be less then 500 (if set)");
+    return CMD_ERROR;
+  }
+  maxperident = strtoul(cargv[2],NULL,10);
+  if (maxperident > 50) {
+    controlreply(sender, "ERROR: MaxPerIdent value should be less then 50 (if set)");
+    return CMD_ERROR;
+  }
+  if (((cargv[4][0]!='0') && (cargv[4][0]!='1')) || (cargv[4][1]!='\0')) {
+    controlreply(sender,"ERROR: enforceident is a boolean setting, that means it can only be 0 or 1");
+    return CMD_ERROR;
+  }
+  enforceident = cargv[4][0] == '1';
+
+  if ( findtrustgroupbyownerid(ownerid) ) {
+    controlreply(sender, "ERROR: Q User ID %d already has a trustgroup", ownerid);
+    return CMD_ERROR;
+  }
+  if (ownerid > 2147483646 ) {
+    controlreply(sender, "ERROR: Invalid Q User ID: %d", ownerid);
+    return CMD_ERROR;
+  }
+
+  type = strtoul(cargv[5],NULL,10);
+
+  /* check rules */
+  switch (type ) {
+    case 0:
+      break;
+    default:
+      controlreply(sender, "Invalid Type (%d)", type);
+      return CMD_ERROR;
+  }
+
+  t = createtrustgroup( ++trusts_lasttrustgroupid, maxclones, maxperident, maxperip,  enforceident, getnettime() + expiry, ownerid, type);
+
+  if(!t) {
+    controlreply(sender,"ERROR: An error occured adding trustgroup");
+    return CMD_ERROR;
+  }
+
+  trustsdb_addtrustgroup(t);
+
+  controlreply(sender,"Adding trustgroup with ID %lu", t->id);
+  controlreply(sender,"Connections: %d, Enforceident %d, Per ident: %d, Per IP %d",maxclones,enforceident,maxperident,maxperip);
+  controlreply(sender,"Expires: %d, User ID: %d", expiry, ownerid);
+  controlwall(NO_OPER, NL_TRUSTS, "NewTrust: ID: %lu, Connections: %d, Enforceident %d, Per ident: %d, Per IP %d, Owner %d", t->id,maxclones,enforceident,maxperident,maxperip, ownerid);
+  return CMD_OK;
+}
+
+int trust_del(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  struct irc_in_addr sin;
+  unsigned char bits;
+  patricia_node_t *node;
+  trustgroup_t *tg;
+
+  if (cargc<1) {
+    controlreply(sender,"Syntax: trustdel IP[/mask]");
+    return CMD_OK;
+  }
+
+  if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
+    controlreply(sender, "ERROR: Invalid mask.");
+    return CMD_ERROR;
+  }
+
+  node = refnode(iptree, &sin, bits);
+  if(!node->exts[tgh_ext]) {
+    controlreply(sender,"ERROR: That CIDR was not trusted.");
+    return CMD_ERROR;
+  } else {
+    /*TODO: only allow a host to be removed if <X users? subnets? bah */
+    tg = ((trusthost_t *)node->exts[tgh_ext])->trustgroup;
+    controlreply(sender,"%s removed from trustgroup #%lu",cargv[0],tg->id);
+    controlwall(NO_OPER, NL_TRUSTS, "%s removed from trustgroup #%lu",cargv[0],tg->id);
+    trustsdb_deletetrusthost(node->exts[tgh_ext]);
+    trusthost_free(node->exts[tgh_ext]);
+    node->exts[tgh_ext] = NULL;
+  }
+  return CMD_OK;
+}
+
+int trust_add(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  trustgroup_t *tg;
+  struct irc_in_addr sin;
+  unsigned char bits;
+  patricia_node_t *node, *inode, *parent;
+  int expiry = 0;
+  trusthost_t *th;
+
+  if (cargc<2) {
+    controlreply(sender,"Syntax: trustadd <#groupid> IP[/mask] <duration>");
+    return CMD_OK;
+  }
+
+  if(cargv[0][0]== '#'){
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
+  } else {
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
+  }
+
+  if(tg == NULL) {
+    controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
+    return CMD_ERROR;
+  }
+
+  if (tg->id==0) {
+    controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
+    return CMD_ERROR;
+  }
+
+  if (ipmask_parse(cargv[1], &sin, &bits) == 0) {
+    controlreply(sender, "ERROR: Invalid mask.");
+    return CMD_ERROR;
+  }
+
+  if ( irc_in_addr_is_ipv4(&sin) ) {
+    if (bits>128 || bits<112) {
+      controlreply(sender,"ERROR: Not a valid netmask (needs to be between 8 and 32)");
+      return CMD_ERROR;
+    }
+  } else {
+    if ( bits<64) {
+      controlreply(sender,"ERROR: Not a valid ipv6 netmask ");
+      return CMD_ERROR;
+    }
+  }
+
+  if (cargc == 3) {
+    expiry = getnettime() + durationtolong(cargv[2]);
+    if (expiry<1) {
+      controlreply(sender,"ERROR: Invalid duration given");
+      return CMD_ERROR;
+    }
+  }
+
+  node  = refnode(iptree, &sin, bits);
+  if(node->exts[tgh_ext]) {
+    /* this mask is already trusted */
+    controlreply(sender,"ERROR: This mask is already trusted by trustgroup %lu.", ((trusthost_t *)node->exts[tgh_ext])->trustgroup->id);
+    return CMD_ERROR;
+  }
+
+  /* check child status */
+  PATRICIA_WALK(node, inode)
+  {
+    th = inode->exts[tgh_ext];
+    if (th) {
+      /* we have a child trustgroup */
+      /* Criteria 1: we can't add two hosts into the same group */
+      if (th->trustgroup == tg) {
+        controlreply(sender,"ERROR: A child subnet is already in this trustgroup, remove that subnet first (%s/%d)", IPtostr(inode->prefix->sin),irc_bitlen(&(inode->prefix->sin),inode->prefix->bitlen));
+        return CMD_ERROR;
+      } 
+    }
+  }
+  PATRICIA_WALK_END;
+
+  /* check parents too */
+  parent = node->parent;
+  while (parent) {
+    if( parent->exts[tgh_ext]) {
+      th = parent->exts[tgh_ext];
+      /* we have a parent trustgroup */
+      /* Criteria 1: we can't add two hosts into the same group */
+      if (th->trustgroup == tg) {
+        controlreply(sender,"ERROR: A parent subnet is already in this trustgroup (%s/%d)", IPtostr(parent->prefix->sin),irc_bitlen(&(parent->prefix->sin),parent->prefix->bitlen));
+        return CMD_ERROR;
+      }
+      /* even if we find 1 parent, we continue to the top */
+    }
+    parent = parent->parent;
+  }
+
+  th = trusthostadd(node, tg, expiry );
+  if ( !th ) {
+    controlreply(sender,"ERROR: Unable to add trusted host");
+  }
+  trustsdb_addtrusthost(th);
+  controlreply(sender,"Added %s to trustgroup #%lu",cargv[1],tg->id);
+  controlwall(NO_OPER, NL_TRUSTS, "Added %s to trustgroup #%lu",cargv[1],tg->id);
+  return CMD_OK;
+}
+
+int trust_denyadd(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+
+  controlreply(sender,"Not Implemented");
+  return CMD_OK;
+}
+
+int trust_dump(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+
+  char tmps3[512];
+  trustgroup_t *g;
+  unsigned long startid=0;
+  long num=0, count=0, lines=0;
+
+  if (cargc<2) {
+    controlreply(sender, "Syntax: trustdump <start #id> <number>");
+    controlreply(sender, "Dumps <number> trustgroups starting from <start #id>.");
+    controlreply(sender, "This allows to dump very large numbers of groups,");
+    controlreply(sender, "so use with care.");
+    return CMD_ERROR;
+  }
+  strncpy(tmps3,cargv[0],20);
+  tmps3[20]='\0';
+  num = atoi(cargv[1]);
+
+  if (tmps3[0] != '#') {
+    controlreply(sender, "First parameter has to be a trust ID (prefixed with #).");
+    return CMD_ERROR;
+  }
+
+  startid=strtoul(&tmps3[1], NULL, 10);
+  if (num < 1) {
+    controlreply(sender, "Cannot return fewer than 1 group.");
+    return CMD_ERROR;
+  }
+  if (num >= 500) {
+    controlreply(sender, "Will not list more than 500 groups in one go.");
+    return CMD_ERROR;
+  }
+
+  if (startid > trusts_lasttrustgroupid) {
+    controlreply(sender, "Start ID cannot exceed maximum group ID (#%ld).", trusts_lasttrustgroupid);
+    return CMD_ERROR;
+  }
+
+  do {
+    g=findtrustgroupbyid(startid);
+    startid++;
+  } while ((g == NULL) && (startid <= (trusts_lasttrustgroupid+1)));
+  if (g == NULL) {
+    controlreply(sender, "Failed to find nearest start group.");
+    return CMD_ERROR;
+  }
+
+  while (startid <= (trusts_lasttrustgroupid+1)) {
+    if (g == NULL) {
+      g=findtrustgroupbyid(startid);
+      startid++;
+      continue;
+    }
+    controlreply(sender, "G,#%lu,%lu,%lu,%d,%lu,%lu,%lu,%lu",
+      g->id, g->currenton, g->maxclones, g->enforceident, g->maxperident,
+      g->maxusage, g->expire, g->lastused);
+    lines++;
+
+    trusthost_t* thptr;
+
+    int hash = trusts_gettrusthostgroupidhash(g->id);
+    for (thptr = trusthostgroupidtable[hash]; thptr; thptr = thptr->nextbygroupid ) {
+      if ( thptr->trustgroup->id == g->id ) {
+        /* TODO: expire here - trusthost_free(thptr);*/
+        controlreply(sender, "H,#%lu,%s/%d,%lu,%lu,%lu", g->id,
+                              IPtostr(((patricia_node_t *)thptr->node)->prefix->sin),
+                              irc_bitlen(&(((patricia_node_t *)thptr->node)->prefix->sin),((patricia_node_t *)thptr->node)->prefix->bitlen),
+                              0 /*a->currentlyon*/,
+                              0 /*a->maxused*/,
+                              0 /* a->lastused*/);
+        lines++;
+      }
+    }
+
+    count++;
+    if (count >= num) {
+      break;
+    }
+    g=findtrustgroupbyid(startid);
+    startid++;
+  }
+  controlreply(sender, "End of list, %ld groups and %ld lines returned.", count, lines);
+  return CMD_OK;
+}
+
+int trust_denydel(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+
+  controlreply(sender,"Not Implemented");
+  return CMD_OK;
+}
+
+int trust_denylist(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+
+  controlreply(sender,"Not Implemented");
+  return CMD_OK;
+}
+
+int trust_groupmodify(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  unsigned long oldvalue, newvalue;
+  char *mod;
+  int expiry;
+  trustgroup_t *tg;
+
+  if (cargc<3 || cargc==4) {
+    controlreply(sender,"Syntax: trustgroupmodify <#groupid> <what> [+|-|=]number");
+    controlreply(sender,"        +20 means add 20, =20 replaces current value, -20 means subtract");
+    controlreply(sender,"        what: maxclones, maxperident, maxperip, expire, enforceident, ownerid");
+    return CMD_OK;
+  }
+
+  if(cargv[0][0]== '#'){
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
+  } else {
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
+  }
+
+  if(tg == NULL) {
+    controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
+    return CMD_ERROR;
+  }
+
+  if (tg->id==0) {
+    controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
+    return CMD_ERROR;
+  }
+
+  switch ( cargv[2][0] ) {
+    case '+':
+    case '-':
+    case '=':
+      mod = cargv[2];
+      break;
+    default:
+      controlreply(sender,"ERROR: invalid modifier specified (values values are +,-,=)");
+      return CMD_ERROR;
+  }
+  newvalue = strtoul(&cargv[2][1],NULL,10);
+  
+  if (ircd_strcmp(cargv[1], "maxclones")==0) {
+    oldvalue = tg->maxclones;
+    switch (*mod) {
+      case '+':
+        newvalue = oldvalue + newvalue; 
+        break;
+      case '-':
+        if (newvalue > oldvalue) {
+          controlreply(sender, "ERROR: maxclones cannot be less than 0");
+          return CMD_ERROR; 
+        }
+        newvalue = oldvalue - newvalue;
+        if (newvalue == 0) {
+          controlreply(sender, "ERROR: maxclones limit would be 0 - unlimited maxclones can only be set with '='");
+          return CMD_ERROR;
+        }
+        break;
+    }
+
+    if (newvalue > 1000000) {
+      controlreply(sender, "ERROR: large maximum number of clients - %lu", newvalue);
+      return CMD_ERROR;
+    }
+    if (newvalue > 10000) {
+      controlreply(sender, "WARNING: large maximum number of clients - %lu", newvalue);
+    }
+
+    tg->maxclones = newvalue;
+  } else if (ircd_strcmp(cargv[1], "maxperident")==0) {
+    oldvalue = tg->maxperident;
+    switch (*mod) {
+      case '+':
+        newvalue = oldvalue + newvalue;
+        break;
+      case '-':
+        if (newvalue > oldvalue) {
+          controlreply(sender, "ERROR: maxperident cannot be less than 0");
+          return CMD_ERROR;
+        }
+        newvalue = oldvalue - newvalue;
+        if (newvalue == 0) {
+          controlreply(sender, "ERROR: maxperident limit would be 0 - unlimited maxclones can only be set with '='");
+          return CMD_ERROR;
+        }
+        break;
+    }
+
+    if (newvalue > 50) {
+      controlreply(sender, "ERROR: MaxPerIdent value should be less then 50 (if set)");
+      return CMD_ERROR;
+    }
+    tg->maxperident=newvalue;  
+  } else if (ircd_strcmp(cargv[1], "maxperip")==0) {
+    oldvalue = tg->maxperip;
+    switch (*mod) {
+      case '+':
+        newvalue = oldvalue + newvalue;
+        break;
+      case '-':
+        if (newvalue > oldvalue) {
+          controlreply(sender, "ERROR: maxperip cannot be less than 0");
+          return CMD_ERROR;
+        }
+        newvalue = oldvalue - newvalue;
+        if (newvalue == 0) {
+          controlreply(sender, "ERROR: maxperip limit would be 0 - unlimited maxclones can only be set with '='");
+          return CMD_ERROR;
+        }
+        break;
+    }
+
+    if (newvalue > 500) {
+      controlreply(sender, "ERROR: MaxPerIP value should be less then 500 (if set)");
+      return CMD_ERROR;
+    }
+    tg->maxperip = newvalue;
+  } else if (ircd_strcmp(cargv[1], "expire")==0) {
+    oldvalue = tg->expire;
+    expiry = durationtolong(&cargv[2][1]);
+
+    if (expiry > (365 * 86400) ) {
+      controlreply(sender,"ERROR: Invalid duration given - temporary trusts can not be longer then 1 year");
+      return CMD_ERROR;
+    }
+
+    switch (*mod) {
+      case '+':
+        newvalue = oldvalue + expiry;
+        break;
+      case '-':
+        newvalue = oldvalue - expiry;
+        if (newvalue < getnettime() ) {
+          controlreply(sender, "ERROR: Can't set expiry before current nettime - use trustgroupdel to delete trust groups");
+          return CMD_ERROR;
+        }
+        break;
+      case '=':
+        if ( expiry > 0) { 
+          newvalue = getnettime() + expiry;
+        }
+        break; 
+    }
+    tg->expire = newvalue;
+  } else if (ircd_strcmp(cargv[1], "enforceident")==0) {
+    oldvalue = tg->enforceident;
+    if ( (newvalue != 0 && newvalue != 1) || *mod != '=' ) {
+      controlreply(sender,"ERROR: enforceident is a boolean setting, that means it can only be 0 or 1, and can only be set by '='");
+      return CMD_ERROR; 
+    }
+    tg->enforceident = newvalue;
+  } else if (ircd_strcmp(cargv[1], "ownerid")==0) {
+    oldvalue = tg->ownerid; 
+    if ( *mod != '=' ) {
+      controlreply(sender,"ERROR: Q user ID can only be set by '='");
+      return CMD_ERROR;
+    }
+    if ( findtrustgroupbyownerid(newvalue) ) {
+      controlreply(sender, "ERROR: Q User ID %d already has a trustgroup", newvalue);
+      return CMD_ERROR;
+    }
+
+    if (newvalue > 2147483646 ) {
+      controlreply(sender, "ERROR: Invalid Q User ID: %d", newvalue);
+      return CMD_ERROR;
+    }
+
+    tg->ownerid = newvalue;
+  }
+  controlreply(sender, "Modification: %s changed to %lu from %lu for trustgroup %lu", cargv[1], newvalue, oldvalue, tg->id);
+  controlwall(NO_OPER, NL_TRUSTS, "Modification: %s changed to %lu from %lu for trustgroup %lu", cargv[1], newvalue, oldvalue, tg->id);
+
+  trustsdb_updatetrustgroup(tg);
+  return CMD_OK;
+}
+
+int trust_groupdel(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  trusthost_t *thptr, *nthptr;
+  trustgroup_t *tg;
+  patricia_node_t *node;
+
+  if (cargc<1) {
+    controlreply(sender,"Syntax: trustgroupdel <#id|id>");
+    return CMD_OK;
+  }
+
+  if(cargv[0][0]== '#'){
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
+  } else {
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
+  }
+
+  if(tg == NULL) {
+    controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
+    return CMD_ERROR;
+  }
+
+  if (tg->id==0) {
+    controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
+    return CMD_ERROR;
+  }
+
+  /* we have a trustgroup to remove */
+  int hash = trusts_gettrusthostgroupidhash(tg->id);
+  for (thptr = trusthostgroupidtable[hash]; thptr; thptr = nthptr ) {
+    nthptr = thptr->nextbygroupid;  
+    if(thptr->trustgroup == tg) {
+      node = thptr->node;
+      controlwall(NO_OPER, NL_TRUSTS, "%s/%d removed from trustgroup #%lu",IPtostr(thptr->node->prefix->sin),irc_bitlen(&(thptr->node->prefix->sin),thptr->node->prefix->bitlen),tg->id);
+      controlreply(sender,"%s/%d removed from trustgroup #%lu",IPtostr(thptr->node->prefix->sin),irc_bitlen(&(thptr->node->prefix->sin),thptr->node->prefix->bitlen),tg->id);
+      trustsdb_deletetrusthost(thptr);
+      trusthost_free(thptr);
+      node->exts[tgh_ext] = NULL;
+    }
+  }
+  controlwall(NO_OPER, NL_TRUSTS, "removed trustgroup #%lu",tg->id);
+  controlreply(sender,"removed trustgroup #%lu",tg->id);
+  trustsdb_deletetrustgroup(tg);
+  trustgroup_free(tg);
+  return CMD_OK;
+
+}
+
+int trust_stats(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  trustgroup_t *tg; trusthost_t* thptr; int i;
+  unsigned long thcount=0, ucount=0, mcount=0, tgcount=0;
+  unsigned long hentries=0;
+  unsigned long netcount4[33];
+  unsigned long netucount4[33];
+  unsigned long netmcount4[33];
+  unsigned long netcount6[129];
+  unsigned long netucount6[129];
+  unsigned long netmcount6[129];
+
+  int maxthmask4 = 32;
+  int maxthmask6 = 128;
+
+  for (i=0; i<33; i++) {
+    netcount4[i]=0;
+    netucount4[i]=0;
+    netmcount4[i]=0;
+  }
+
+  for (i=0; i<129; i++) {
+    netcount6[i]=0;
+    netucount6[i]=0;
+    netmcount6[i]=0;
+  }
+
+  for ( i = 0; i < TRUSTS_HASH_GROUPSIZE ; i++ ) {
+    for ( tg = trustgroupidtable[i]; tg; tg = tg -> nextbyid ) {
+      /*check active*/
+      tgcount++;
+    }
+  }
+
+  for ( i = 0; i < TRUSTS_HASH_HOSTSIZE ; i++ ) {
+    for ( thptr = trusthostidtable[i]; thptr; thptr = thptr-> nextbyid ) {
+      /*check active*/
+      hentries++;
+      thcount++;
+      ucount+=thptr->node->usercount;
+      mcount+=thptr->maxused;
+      if(irc_in_addr_is_ipv4(&((patricia_node_t *)thptr->node)->prefix->sin)) {
+        netcount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]++;
+        netucount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]+=thptr->node->usercount;
+        netmcount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]+=thptr->maxused;
+        if( (((patricia_node_t *)thptr->node)->prefix->bitlen-96) < maxthmask4 ) {
+          maxthmask4 = (((patricia_node_t *)thptr->node)->prefix->bitlen-96);
+        }
+      } else {
+        netcount6[((patricia_node_t *)thptr->node)->prefix->bitlen]++;
+        netucount6[((patricia_node_t *)thptr->node)->prefix->bitlen]+=thptr->node->usercount;
+        netmcount6[((patricia_node_t *)thptr->node)->prefix->bitlen]+=thptr->maxused;
+        if( ((patricia_node_t *)thptr->node)->prefix->bitlen < maxthmask6 ) {
+          maxthmask6 = ((patricia_node_t *)thptr->node)->prefix->bitlen;
+        }
+      }
+    }
+  }
+  controlreply(sender, "Online trust users:   %lu", ucount);
+  controlreply(sender, "Maximum online users: %lu", mcount);
+  controlreply(sender, "Trust groups:         %lu", tgcount);
+  controlreply(sender, "Maximum group ID:     #%lu", trusts_lasttrustgroupid);
+  controlreply(sender, "Trusted hosts/nets:   %lu", thcount);
+  controlreply(sender, "Largest subnet (v4):  /%d", maxthmask4);
+  controlreply(sender, "Largest subnet (v6):  /%d", maxthmask6);
+  controlreply(sender, "IPv4 Subnets:");
+  for (i=0; i<32; i++) {
+    if (netcount4[i]==0) continue;
+    controlreply(sender, "|-*/%d (Netcount: %lu Cur: %lu Max: %lu)", i, netcount4[i], netucount4[i], netmcount4[i]);
+  }
+  controlreply(sender, "`-*/32 (Netcount: %lu Cur: %lu Max: %lu)", netcount4[32], netucount4[32], netmcount4[32]);
+  controlreply(sender, "IPv6 Subnets:");
+  for (i=0; i<128; i++) {
+    if (netcount6[i]==0) continue;
+    controlreply(sender, "|-*/%d (Netcount: %lu Cur: %lu Max: %lu)", i, netcount6[i], netucount6[i], netmcount6[i]);
+  }
+  controlreply(sender, "`-*/128 (Netcount: %lu Cur: %lu Max: %lu)", netcount6[128], netucount6[128], netmcount6[128]);
+
+  return CMD_OK;
+}
+
+
+int trust_comment(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+  trustgroup_t *tg;
+
+  if (cargc<2) {
+    controlreply(sender,"Syntax: trustcomment <#groupid> <comment>");
+    return CMD_OK;
+  }
+
+  if(cargv[0][0]== '#'){
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
+  } else {
+    /* find group by id */
+    tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
+  }
+
+  if(tg == NULL) {
+    controlreply(sender,"A trustgroup with that ID does not exist.");
+    return CMD_ERROR;
+  }
+
+  if (tg->id==0) {
+    controlreply(sender,"Internal error: Trustgroup has ID 0");
+    return CMD_ERROR;
+  }
+
+  trustsdb_logmessage(tg, 0, 1, cargv[1]);
+
+  controlreply(sender, "Comment: %s for trustgroup %lu", cargv[1], tg->id);
+  controlwall(NO_OPER, NL_TRUSTS, "Comment: %s for trustgroup %lu", cargv[1], tg->id);
+
+  return CMD_OK;
+
+}
+
diff --git a/trusts_newsearch/Makefile.in b/trusts_newsearch/Makefile.in
new file mode 100644 (file)
index 0000000..e40294e
--- /dev/null
@@ -0,0 +1,12 @@
+@include@ @includel@../build.mk@includel@
+
+CFLAGS+=$(INCDBAPI)
+LDFLAGS+=$(LIBDBAPI)
+
+
+.PHONY: all
+
+all: trusts_newsearch.so
+
+trusts_newsearch.so: formats.o tsns-ownerid.o tsns-tgmaxperident.o tsns-thcreated.o tsns-thmodified.o trusts_newsearch.o tsns-tgcreated.o tsns-tgmaxperip.o tsns-thexpire.o tsns-thstartdate.o tsns-currenton.o tsns-tgexpire.o tsns-tgmaxusage.o tsns-thid.o tsns-trusted.o tsns-enforceident.o tsns-tgid.o tsns-tgmodified.o tsns-thlastused.o tsns-maxclones.o tsns-tglastused.o tsns-tgstartdate.o tsns-thmaxusage.o
+
diff --git a/trusts_newsearch/formats.c b/trusts_newsearch/formats.c
new file mode 100644 (file)
index 0000000..0133736
--- /dev/null
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+#include "../newsearch/newsearch.h"
+#include "../control/control.h"
+#include "../lib/stringbuf.h"
+#include "../trusts/trusts.h"
+
+void printtrust_group(searchCtx *ctx, nick *sender, patricia_node_t *node) {
+  trusthost_t *tgh = node->exts[tgh_ext];
+  trustgroup_t *tg;
+
+  if (tgh) {
+    tg = tgh->trustgroup;
+    ctx->reply(sender,"%s | [%lu] | %lu/%lu", IPtostr(node->prefix->sin), tg->id, tg->currenton, tg->maxusage); 
+  } else { 
+    ctx->reply(sender,"%s | <none>", IPtostr(node->prefix->sin));
+  }
+}
+
diff --git a/trusts_newsearch/trusts_newsearch.c b/trusts_newsearch/trusts_newsearch.c
new file mode 100644 (file)
index 0000000..1499718
--- /dev/null
@@ -0,0 +1,107 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "trusts_newsearch.h"
+#include "../trusts/trusts.h"
+
+
+void _init(void) {
+  regdisp(reg_nodesearch, "tg", printtrust_group, 0, "");
+
+  /* TRUSTGROUP */
+  registersearchterm(reg_tgsearch, "tgid", tsns_tgid_parse, 0, "Trustgroup ID");
+  registersearchterm(reg_tgsearch, "tgstartdate", tsns_tgstartdate_parse, 0, "Trustgroup start date timestamp - represents date trust is due to go active or date trust was added");
+  registersearchterm(reg_tgsearch, "tglastused", tsns_tglastused_parse, 0, "trust group last used timestamp");
+  registersearchterm(reg_tgsearch, "tgexpire", tsns_tgexpire_parse, 0, "trust group expiry timestamp");
+  registersearchterm(reg_tgsearch, "tgownerid", tsns_tgownerid_parse, 0, "Q auth id of trust group owner");
+  registersearchterm(reg_tgsearch, "tgmaxperip", tsns_tgmaxperip_parse, 0, "trust group max per IP value");
+  registersearchterm(reg_tgsearch, "tgmaxusage", tsns_tgmaxusage_parse, 0, "trust group max usage ever");
+  registersearchterm(reg_tgsearch, "tgcurrenton", tsns_tgcurrenton_parse, 0, "trust group current usage");
+  registersearchterm(reg_tgsearch, "tgmaxclones", tsns_tgmaxclones_parse, 0, "trust group maximum user limit");
+  registersearchterm(reg_tgsearch, "tgmaxperident", tsns_tgmaxperident_parse, 0, "trust group max per ident value");
+  registersearchterm(reg_tgsearch, "tgenforceident", tsns_tgenforceident_parse, 0, "trust group enforce ident (0/1)");
+  registersearchterm(reg_tgsearch, "tgcreated", tsns_tgcreated_parse, 0, "trust group creation timestamp (note: we also store a startdate timestamp)");
+  registersearchterm(reg_tgsearch, "tgmodified", tsns_tgmodified_parse, 0, "trust group last modified timestamp");
+
+  registersearchterm(reg_thsearch, "thid", tsns_thid_parse, 0, "trust host ID");
+  registersearchterm(reg_thsearch, "thstartdate", tsns_thstartdate_parse, 0, "trust host start date timestamp - represents date host is due to go active or date host was added");
+  registersearchterm(reg_thsearch, "thlastused", tsns_thlastused_parse, 0, "trust host last used timestamp");
+  registersearchterm(reg_thsearch, "thexpire", tsns_thexpire_parse, 0, "trust host expiry timestamp");
+  registersearchterm(reg_thsearch, "thmaxusage", tsns_thmaxusage_parse, 0, "trust host max usage ever");
+  registersearchterm(reg_thsearch, "thcreated", tsns_thcreated_parse, 0, "trust host creation timestamp (note: we also store a startdate timestamp)");
+  registersearchterm(reg_thsearch, "thmodified", tsns_thmodified_parse, 0, "trust host last modified timestamp");
+
+  registersearchterm(reg_nodesearch, "trusted", tsns_trusted_parse, 0, "IP node is trusted");
+  registersearchterm(reg_nodesearch, "tgid", tsns_tgid_parse, 0, "Trust group ID");
+  registersearchterm(reg_nodesearch, "tgexpire", tsns_tgexpire_parse, 0, "trust group expiry timestamp");
+  registersearchterm(reg_nodesearch, "tgstartdate", tsns_tgstartdate_parse, 0, "Trustgroup start date timestamp - represents date trust is due to go active or date trust was added");
+  registersearchterm(reg_nodesearch, "tglastused", tsns_tglastused_parse, 0, "trust group last used timestamp");
+  registersearchterm(reg_nodesearch, "tgownerid", tsns_tgownerid_parse, 0, "Q auth id of trust group owner");
+  registersearchterm(reg_nodesearch, "tgmaxperip", tsns_tgmaxperip_parse, 0, "trust group max per IP value");
+  registersearchterm(reg_nodesearch, "tgmaxusage", tsns_tgmaxusage_parse, 0, "trust group max usage ever");
+  registersearchterm(reg_nodesearch, "tgmaxclones", tsns_tgmaxclones_parse, 0, "trust group maximum user limit");
+  registersearchterm(reg_nodesearch, "tgmaxperident", tsns_tgmaxperident_parse, 0, "trust group max per ident value");
+  registersearchterm(reg_nodesearch, "tgenforceident", tsns_tgenforceident_parse, 0, "trust group enforce ident (0/1)");
+  registersearchterm(reg_nodesearch, "tgcreated", tsns_tgcreated_parse, 0, "trust group creation timestamp (note: we also store a startdate timestamp)");
+  registersearchterm(reg_nodesearch, "tgmodified", tsns_tgmodified_parse, 0, "trust group last modified timestamp");
+
+  registersearchterm(reg_nodesearch, "thid", tsns_thid_parse, 0, "Trust Host ID");
+  registersearchterm(reg_nodesearch, "thstartdate", tsns_thstartdate_parse, 0, "trust host start date timestamp - represents date host is due to go active or date host was added");
+  registersearchterm(reg_nodesearch, "thlastused", tsns_thlastused_parse, 0, "trust host last used timestamp");
+  registersearchterm(reg_nodesearch, "thexpire", tsns_thexpire_parse, 0, "trust host expiry timestamp");
+  registersearchterm(reg_nodesearch, "thmaxusage", tsns_thmaxusage_parse, 0, "trust host max usage ever");
+  registersearchterm(reg_nodesearch, "thcreated", tsns_thcreated_parse, 0, "trust host creation timestamp (note: we also store a startdate timestamp)");
+  registersearchterm(reg_nodesearch, "thmodified", tsns_thmodified_parse, 0, "trust host last modified timestamp");
+
+}
+
+void _fini(void) {
+  unregdisp(reg_nodesearch, "tg", printtrust_group);
+
+  deregistersearchterm(reg_tgsearch, "tgid", tsns_tgid_parse);
+  deregistersearchterm(reg_tgsearch, "tgstartdate", tsns_tgstartdate_parse);
+  deregistersearchterm(reg_tgsearch, "tglastused", tsns_tglastused_parse);
+  deregistersearchterm(reg_tgsearch, "tgexpire", tsns_tgexpire_parse);
+  deregistersearchterm(reg_tgsearch, "tgownerid", tsns_tgownerid_parse);
+  deregistersearchterm(reg_tgsearch, "tgmaxperip", tsns_tgmaxperip_parse);
+  deregistersearchterm(reg_tgsearch, "tgmaxusage", tsns_tgmaxusage_parse);
+  deregistersearchterm(reg_tgsearch, "tgcurrenton", tsns_tgcurrenton_parse);
+  deregistersearchterm(reg_tgsearch, "tgmaxclones", tsns_tgmaxclones_parse);
+  deregistersearchterm(reg_tgsearch, "tgmaxperident", tsns_tgmaxperident_parse);
+  deregistersearchterm(reg_tgsearch, "tgenforceident", tsns_tgenforceident_parse);
+  deregistersearchterm(reg_tgsearch, "tgcreated", tsns_tgcreated_parse);
+  deregistersearchterm(reg_tgsearch, "tgmodified", tsns_tgmodified_parse);
+
+  deregistersearchterm(reg_thsearch, "thid", tsns_thid_parse);
+  deregistersearchterm(reg_thsearch, "thstartdate", tsns_thstartdate_parse);
+  deregistersearchterm(reg_thsearch, "thlastused", tsns_thlastused_parse);
+  deregistersearchterm(reg_thsearch, "thexpire", tsns_thexpire_parse);
+  deregistersearchterm(reg_thsearch, "thmaxusage", tsns_thmaxusage_parse);
+  deregistersearchterm(reg_thsearch, "thcreated", tsns_thcreated_parse);
+  deregistersearchterm(reg_thsearch, "thmodified", tsns_thmodified_parse);
+
+  deregistersearchterm(reg_nodesearch, "trusted", tsns_trusted_parse);
+  deregistersearchterm(reg_nodesearch, "tgid", tsns_tgid_parse);
+  deregistersearchterm(reg_nodesearch, "tgexpire", tsns_tgexpire_parse);
+  deregistersearchterm(reg_nodesearch, "tgstartdate", tsns_tgstartdate_parse);
+  deregistersearchterm(reg_nodesearch, "tglastused", tsns_tglastused_parse);
+  deregistersearchterm(reg_nodesearch, "tgownerid", tsns_tgownerid_parse);
+  deregistersearchterm(reg_nodesearch, "tgmaxperip", tsns_tgmaxperip_parse);
+  deregistersearchterm(reg_nodesearch, "tgmaxusage", tsns_tgmaxusage_parse);
+  deregistersearchterm(reg_nodesearch, "tgmaxclones", tsns_tgmaxclones_parse);
+  deregistersearchterm(reg_nodesearch, "tgmaxperident", tsns_tgmaxperident_parse);
+  deregistersearchterm(reg_nodesearch, "tgenforceident", tsns_tgenforceident_parse);
+  deregistersearchterm(reg_nodesearch, "tgcreated", tsns_tgcreated_parse);
+  deregistersearchterm(reg_nodesearch, "tgmodified", tsns_tgmodified_parse);
+
+  deregistersearchterm(reg_nodesearch, "thid", tsns_thid_parse);
+  deregistersearchterm(reg_nodesearch, "thstartdate", tsns_thstartdate_parse);
+  deregistersearchterm(reg_nodesearch, "thlastused", tsns_thlastused_parse);
+  deregistersearchterm(reg_nodesearch, "thexpire", tsns_thexpire_parse);
+  deregistersearchterm(reg_nodesearch, "thmaxusage", tsns_thmaxusage_parse);
+  deregistersearchterm(reg_nodesearch, "thcreated", tsns_thcreated_parse);
+  deregistersearchterm(reg_nodesearch, "thmodified", tsns_thmodified_parse);
+
+}
+
diff --git a/trusts_newsearch/trusts_newsearch.h b/trusts_newsearch/trusts_newsearch.h
new file mode 100644 (file)
index 0000000..4d937de
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __TRUSTS_NEWSEARCH_H_
+#define __TRUSTS_NEWSEARCH_H
+
+#include "../patriciasearch/patriciasearch.h"
+#include "../trusts/trusts.h"
+#include "../trusts_search/trusts_search.h"
+
+void printtrust_group(searchCtx *ctx, nick *sender, patricia_node_t *node);
+
+struct searchNode *tsns_trusted_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgid_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgexpire_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgmaxperip_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgownerid_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgstartdate_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tglastused_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgmaxusage_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgcurrenton_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgmaxclones_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgmaxperident_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgenforceident_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgcreated_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_tgmodified_parse(searchCtx *ctx, int argc, char **argv);
+
+struct searchNode *tsns_thcreated_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thexpire_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thid_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thlastused_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thmaxusage_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thmodified_parse(searchCtx *ctx, int argc, char **argv);
+struct searchNode *tsns_thstartdate_parse(searchCtx *ctx, int argc, char **argv);
+
+#endif
diff --git a/trusts_newsearch/tsns-currenton.c b/trusts_newsearch/tsns-currenton.c
new file mode 100644 (file)
index 0000000..e75d397
--- /dev/null
@@ -0,0 +1,34 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgcurrenton_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgcurrenton_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgcurrenton_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgcurrenton_exe;
+  thenode->free = tsns_tgcurrenton_free;
+
+  return thenode;
+}
+
+void *tsns_tgcurrenton_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+
+  tg = (trustgroup_t *)theinput;
+  return (void *)(tg->currenton);
+}
+
+void tsns_tgcurrenton_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-enforceident.c b/trusts_newsearch/tsns-enforceident.c
new file mode 100644 (file)
index 0000000..a382f7f
--- /dev/null
@@ -0,0 +1,46 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgenforceident_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgenforceident_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgenforceident_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_BOOL;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgenforceident_exe;
+  thenode->free = tsns_tgenforceident_free;
+
+  return thenode;
+}
+
+void *tsns_tgenforceident_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      if (((trusthost_t *)node->exts[tgh_ext])->trustgroup->enforceident)
+        return (void *)1;
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    if (tg->enforceident)
+      return (void *)1;
+  } else {
+    return NULL;
+  }
+
+  return (void *)0;
+}
+
+void tsns_tgenforceident_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-maxclones.c b/trusts_newsearch/tsns-maxclones.c
new file mode 100644 (file)
index 0000000..66dc9d4
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgmaxclones_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgmaxclones_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgmaxclones_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgmaxclones_exe;
+  thenode->free = tsns_tgmaxclones_free;
+
+  return thenode;
+}
+
+void *tsns_tgmaxclones_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+  
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->maxclones);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->maxclones);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgmaxclones_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-ownerid.c b/trusts_newsearch/tsns-ownerid.c
new file mode 100644 (file)
index 0000000..af3c7fd
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgownerid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgownerid_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgownerid_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgownerid_exe;
+  thenode->free = tsns_tgownerid_free;
+
+  return thenode;
+}
+
+void *tsns_tgownerid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->ownerid);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->ownerid);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgownerid_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgcreated.c b/trusts_newsearch/tsns-tgcreated.c
new file mode 100644 (file)
index 0000000..1cd3af5
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgcreated_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgcreated_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgcreated_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgcreated_exe;
+  thenode->free = tsns_tgcreated_free;
+
+  return thenode;
+}
+
+void *tsns_tgcreated_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->created);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->created);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgcreated_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgexpire.c b/trusts_newsearch/tsns-tgexpire.c
new file mode 100644 (file)
index 0000000..ecbb7d0
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgexpire_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgexpire_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgexpire_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgexpire_exe;
+  thenode->free = tsns_tgexpire_free;
+
+  return thenode;
+}
+
+void *tsns_tgexpire_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->expire);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->expire);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgexpire_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgid.c b/trusts_newsearch/tsns-tgid.c
new file mode 100644 (file)
index 0000000..ad11ccb
--- /dev/null
@@ -0,0 +1,46 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgid_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgid_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgid_exe;
+  thenode->free = tsns_tgid_free;
+
+  return thenode;
+}
+
+void *tsns_tgid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  patricia_node_t *node;
+  trustgroup_t *tg;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+      node = (patricia_node_t *)theinput;
+      if (node->exts[tgh_ext] != NULL)
+        return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->id);
+      else
+        return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+      tg = (trustgroup_t *)theinput;
+      return (void *)(tg->id); 
+  } else {
+      return NULL;
+  } 
+
+}
+
+void tsns_tgid_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tglastused.c b/trusts_newsearch/tsns-tglastused.c
new file mode 100644 (file)
index 0000000..a31586e
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tglastused_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tglastused_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tglastused_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tglastused_exe;
+  thenode->free = tsns_tglastused_free;
+
+  return thenode;
+}
+
+void *tsns_tglastused_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->lastused);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->lastused);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tglastused_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgmaxperident.c b/trusts_newsearch/tsns-tgmaxperident.c
new file mode 100644 (file)
index 0000000..3682024
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgmaxperident_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgmaxperident_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgmaxperident_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgmaxperident_exe;
+  thenode->free = tsns_tgmaxperident_free;
+
+  return thenode;
+}
+
+void *tsns_tgmaxperident_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+  
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->maxperident);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->maxperident);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgmaxperident_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgmaxperip.c b/trusts_newsearch/tsns-tgmaxperip.c
new file mode 100644 (file)
index 0000000..5418f3c
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgmaxperip_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgmaxperip_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgmaxperip_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgmaxperip_exe;
+  thenode->free = tsns_tgmaxperip_free;
+
+  return thenode;
+}
+
+void *tsns_tgmaxperip_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+  
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->maxperip);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->maxperip);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgmaxperip_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgmaxusage.c b/trusts_newsearch/tsns-tgmaxusage.c
new file mode 100644 (file)
index 0000000..f3f5319
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgmaxusage_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgmaxusage_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgmaxusage_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgmaxusage_exe;
+  thenode->free = tsns_tgmaxusage_free;
+
+  return thenode;
+}
+
+void *tsns_tgmaxusage_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->maxusage);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->maxusage);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgmaxusage_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgmodified.c b/trusts_newsearch/tsns-tgmodified.c
new file mode 100644 (file)
index 0000000..8a0bc69
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgmodified_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgmodified_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgmodified_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgmodified_exe;
+  thenode->free = tsns_tgmodified_free;
+
+  return thenode;
+}
+
+void *tsns_tgmodified_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->modified);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->modified);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgmodified_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-tgstartdate.c b/trusts_newsearch/tsns-tgstartdate.c
new file mode 100644 (file)
index 0000000..97a43d3
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_tgstartdate_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_tgstartdate_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_tgstartdate_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_tgstartdate_exe;
+  thenode->free = tsns_tgstartdate_free;
+
+  return thenode;
+}
+
+void *tsns_tgstartdate_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trustgroup_t *tg;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->trustgroup->startdate);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_tgsearch) {
+    tg = (trustgroup_t *)theinput;
+    return (void *)(tg->startdate);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_tgstartdate_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thcreated.c b/trusts_newsearch/tsns-thcreated.c
new file mode 100644 (file)
index 0000000..38fc626
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thcreated_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thcreated_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thcreated_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thcreated_exe;
+  thenode->free = tsns_thcreated_free;
+
+  return thenode;
+}
+
+void *tsns_thcreated_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->created);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->created);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thcreated_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thexpire.c b/trusts_newsearch/tsns-thexpire.c
new file mode 100644 (file)
index 0000000..b6234d3
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thexpire_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thexpire_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thexpire_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thexpire_exe;
+  thenode->free = tsns_thexpire_free;
+
+  return thenode;
+}
+
+void *tsns_thexpire_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->expire);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->expire);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thexpire_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thid.c b/trusts_newsearch/tsns-thid.c
new file mode 100644 (file)
index 0000000..80e1713
--- /dev/null
@@ -0,0 +1,46 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thid_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thid_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thid_exe;
+  thenode->free = tsns_thid_free;
+
+  return thenode;
+}
+
+void *tsns_thid_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  patricia_node_t *node;
+  trusthost_t *th;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+      node = (patricia_node_t *)theinput;
+      if (node->exts[tgh_ext] != NULL)
+        return (void *)(((trusthost_t *)node->exts[tgh_ext])->id);
+      else
+        return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+      th = (trusthost_t *)theinput;
+      return (void *)(th->id); 
+  } else {
+      return NULL;
+  } 
+
+}
+
+void tsns_thid_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thlastused.c b/trusts_newsearch/tsns-thlastused.c
new file mode 100644 (file)
index 0000000..8b6cb6e
--- /dev/null
@@ -0,0 +1,45 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thlastused_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thlastused_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thlastused_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thlastused_exe;
+  thenode->free = tsns_thlastused_free;
+
+  return thenode;
+}
+
+void *tsns_thlastused_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node; 
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    node = (patricia_node_t *)theinput;
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->lastused);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->lastused);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thlastused_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thmaxusage.c b/trusts_newsearch/tsns-thmaxusage.c
new file mode 100644 (file)
index 0000000..cc53a6f
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thmaxusage_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thmaxusage_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thmaxusage_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thmaxusage_exe;
+  thenode->free = tsns_thmaxusage_free;
+
+  return thenode;
+}
+
+void *tsns_thmaxusage_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->maxused);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->maxused);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thmaxusage_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thmodified.c b/trusts_newsearch/tsns-thmodified.c
new file mode 100644 (file)
index 0000000..8d8ce63
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thmodified_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thmodified_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thmodified_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thmodified_exe;
+  thenode->free = tsns_thmodified_free;
+
+  return thenode;
+}
+
+void *tsns_thmodified_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->modified);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->modified);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thmodified_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-thstartdate.c b/trusts_newsearch/tsns-thstartdate.c
new file mode 100644 (file)
index 0000000..ad36fad
--- /dev/null
@@ -0,0 +1,44 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_thstartdate_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_thstartdate_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_thstartdate_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_INT;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_thstartdate_exe;
+  thenode->free = tsns_thstartdate_free;
+
+  return thenode;
+}
+
+void *tsns_thstartdate_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  trusthost_t *th;
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (ctx->searchcmd == reg_nodesearch) {
+    if (node->exts[tgh_ext] != NULL) 
+      return (void *)(((trusthost_t *)node->exts[tgh_ext])->startdate);
+    else
+      return (void *)0; /* will cast to a FALSE */
+  } else if (ctx->searchcmd == reg_thsearch) {
+    th = (trusthost_t *)theinput;
+    return (void *)(th->startdate);
+  } else {
+    return NULL;
+  }
+}
+
+void tsns_thstartdate_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
diff --git a/trusts_newsearch/tsns-trusted.c b/trusts_newsearch/tsns-trusted.c
new file mode 100644 (file)
index 0000000..7975938
--- /dev/null
@@ -0,0 +1,37 @@
+#include "trusts_newsearch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void *tsns_trusted_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
+void tsns_trusted_free(searchCtx *ctx, struct searchNode *thenode);
+
+struct searchNode *tsns_trusted_parse(searchCtx *ctx, int argc, char **argv) {
+  struct searchNode *thenode;
+
+  if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
+    parseError = "malloc: could not allocate memory for this search.";
+    return NULL;
+  }
+
+  thenode->returntype = RETURNTYPE_BOOL;
+  thenode->localdata = NULL;
+  thenode->exe = tsns_trusted_exe;
+  thenode->free = tsns_trusted_free;
+
+  return thenode;
+}
+
+void *tsns_trusted_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
+  patricia_node_t *node = (patricia_node_t *)theinput;
+
+  if (node->exts[tgh_ext] == NULL)
+    return (void *)0;
+
+  return (void *)1;
+}
+
+void tsns_trusted_free(searchCtx *ctx, struct searchNode *thenode) {
+  free(thenode);
+}
+
diff --git a/trusts_search/Makefile.in b/trusts_search/Makefile.in
new file mode 100644 (file)
index 0000000..f8589e1
--- /dev/null
@@ -0,0 +1,10 @@
+@include@ @includel@../build.mk@includel@
+
+CFLAGS+=$(INCPGSQL) $(INCPCRE)
+LDFLAGS+=$(LIBPGSQL) $(LIBPCRE)
+
+.PHONY: all
+all: trusts_search.so
+
+trusts_search.so: formats.o trusts_search.o
+
diff --git a/trusts_search/formats.c b/trusts_search/formats.c
new file mode 100644 (file)
index 0000000..bc0009a
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdio.h>
+
+#include "../newsearch/newsearch.h"
+#include "../control/control.h"
+#include "../lib/stringbuf.h"
+#include "../trusts2/trusts.h"
+
+char *trusts_timetostr(time_t t) {
+  static char buf[100];
+  if ( t == 0 ) {
+    return "<none>";
+  }
+
+  strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&t));
+
+  return buf;
+}
+
+void printtg(searchCtx *ctx, nick *sender, trustgroup_t *tg) {
+  ctx->reply(sender,"%lu", tg->id);
+}
+
+void printth(searchCtx *ctx, nick *sender, trusthost_t *th) {
+  ctx->reply(sender,"%lu: %s", th->id, IPtostr(((patricia_node_t *)th->node)->prefix->sin));
+}
+
+void printtgfull(searchCtx *ctx, nick *sender, trustgroup_t *g) {
+  trusthost_t* thptr;
+  trusthost_t *tgh = NULL;
+  patricia_node_t *parent;
+
+  ctx->reply(sender,"Trustgroup ID   : %lu", g->id);
+  ctx->reply(sender,"Max Connections : %lu, Max Per Ident: %lu, Max Per IP: %lu", g->maxclones, g->maxperident, g->maxperip);
+  ctx->reply(sender,"Curent Usage    : %lu/%lu", g->currenton,g->maxusage);
+  ctx->reply(sender,"Enforce Ident   : %d", g->enforceident);
+  ctx->reply(sender,"Start Date      : %s", trusts_timetostr(g->startdate));
+  ctx->reply(sender,"Last Used       : %s", trusts_timetostr(g->lastused));
+  ctx->reply(sender,"Expiry          : %s", trusts_timetostr(g->expire));
+
+  ctx->reply(sender,"Owner           : %lu", g->ownerid);
+  ctx->reply(sender,"Type            : %d", g->type);
+
+  ctx->reply(sender,"Trust Hosts:");
+  ctx->reply(sender,"ID      Host             Current    Max   Last seen           Expiry");
+  int hash = trusts_gettrusthostgroupidhash(g->id);
+  for (thptr = trusthostgroupidtable[hash]; thptr; thptr = thptr->nextbygroupid ) {
+    if(thptr->trustgroup == g)
+      ctx->reply(sender, "%-5lu %15s/%d   %-10lu %-5lu %s %s",
+                         thptr->id,
+                         IPtostr(((patricia_node_t *)thptr->node)->prefix->sin),
+                         irc_bitlen(&(((patricia_node_t *)thptr->node)->prefix->sin),((patricia_node_t *)thptr->node)->prefix->bitlen),
+                         thptr->node->usercount,
+                         thptr->maxused,
+                         trusts_timetostr(thptr->lastused),
+                         trusts_timetostr(thptr->expire));
+
+    parent = ((patricia_node_t *)thptr->node)->parent;
+    while (parent) {
+      if(parent->exts)
+        if( parent->exts[tgh_ext]) {
+          tgh = (trusthost_t *)parent->exts[tgh_ext];
+          ctx->reply(sender, "- Parent Trust Group: %lu", tgh->trustgroup->id);
+        }
+      parent = parent->parent;
+    }
+  }
+}
diff --git a/trusts_search/trusts_search.c b/trusts_search/trusts_search.c
new file mode 100644 (file)
index 0000000..e2d4f16
--- /dev/null
@@ -0,0 +1,201 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "../control/control.h"
+#include "../irc/irc_config.h"
+#include "../lib/irc_string.h"
+#include "../parser/parser.h"
+#include "../lib/splitline.h"
+#include "../lib/version.h"
+#include "../lib/stringbuf.h"
+#include "../lib/strlfunc.h"
+#include "../trusts2/trusts.h"
+#include "trusts_search.h"
+
+typedef void (*TGDisplayFunc)(struct searchCtx *, nick *, trustgroup_t *);
+typedef void (*THDisplayFunc)(struct searchCtx *, nick *, trusthost_t *);
+
+int do_tgsearch(void *source, int cargc, char **cargv);
+int do_tgsearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv);
+void tgsearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, TGDisplayFunc display, int limit, patricia_node_t *subset);
+int do_thsearch(void *source, int cargc, char **cargv);
+int do_thsearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv);
+void thsearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, THDisplayFunc display, int limit, patricia_node_t *subset);
+
+searchCmd *reg_tgsearch;
+searchCmd *reg_thsearch;
+
+TGDisplayFunc defaulttgfn = printtg;
+THDisplayFunc defaultthfn = printth;
+
+void _init() {
+  reg_tgsearch = (searchCmd *)registersearchcommand("tgsearch",NO_OPER,do_tgsearch, printtg);
+  reg_thsearch = (searchCmd *)registersearchcommand("thsearch",NO_OPER,do_thsearch, printth);
+
+  regdisp(reg_tgsearch, "all", printtgfull, 0, "show trustgroup details, including hosts, excludes trust comments");
+  regdisp(reg_tgsearch, "default", printtg, 0, "displays trust group id");
+  regdisp(reg_thsearch, "default", printth, 0, "displays trust host id");
+}
+
+void _fini() {
+  unregdisp( reg_tgsearch, "all", printtgfull);
+  unregdisp(reg_tgsearch, "default", printtg);
+  unregdisp(reg_thsearch, "default", printth);
+
+  deregistersearchcommand( reg_tgsearch );
+  deregistersearchcommand( reg_thsearch );
+}
+
+static void controlwallwrapper(int level, char *format, ...) {
+  char buf[1024];
+  va_list ap;
+
+  va_start(ap, format);
+  vsnprintf(buf, sizeof(buf), format, ap);
+  controlwall(NO_OPER, level, "%s", buf);
+  va_end(ap);
+}
+
+int do_tgsearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
+  nick *sender = senderNSExtern = source;
+  struct searchNode *search;
+  int limit=500;
+  int arg=0;
+  TGDisplayFunc display=defaulttgfn;
+  searchCtx ctx;
+  int ret;
+  patricia_node_t *subset = iptree->head;
+
+  if (cargc<1)
+    return CMD_USAGE;
+
+  ret = parseopts(cargc, cargv, &arg, &limit, (void *)&subset, (void **)&display, reg_tgsearch->outputtree, reply, sender);
+  if(ret != CMD_OK)
+    return ret;
+
+  if (arg>=cargc) {
+    reply(sender,"No search terms - aborting.");
+    return CMD_ERROR;
+  }
+
+  if (arg<(cargc-1)) {
+    rejoinline(cargv[arg],cargc-arg);
+  }
+
+  newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_tgsearch, sender, display, limit);
+
+  if (!(search = ctx.parser(&ctx, cargv[arg]))) {
+    reply(sender,"Parse error: %s",parseError);
+    return CMD_ERROR;
+  }
+
+  tgsearch_exe(search, &ctx, sender, display, limit, subset);
+
+  (search->free)(&ctx, search);
+
+  return CMD_OK;
+}
+
+int do_tgsearch(void *source, int cargc, char **cargv) {
+  return do_tgsearch_real(controlreply, controlwallwrapper, source, cargc, cargv);
+}
+
+void tgsearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, TGDisplayFunc display, int limit, patricia_node_t *subset) {
+  int matches = 0;
+  trustgroup_t *tg;
+  int i;
+
+  /* Get a marker value to mark "seen" channels for unique count */
+  //nmarker=nextnodemarker();
+
+  /* The top-level node needs to return a BOOL */
+  search=coerceNode(ctx, search, RETURNTYPE_BOOL);
+
+  for ( i = 0; i < TRUSTS_HASH_GROUPSIZE ; i++ ) {
+    for ( tg = trustgroupidtable[i]; tg; tg = tg -> nextbyid ) {
+      if ((search->exe)(ctx, search, tg)) {
+      if (matches<limit)
+        display(ctx, sender, tg);
+
+      if (matches==limit)
+        ctx->reply(sender, "--- More than %d matches, skipping the rest",limit);
+      matches++;
+    }
+  }
+  }
+  ctx->reply(sender,"--- End of list: %d matches",
+                matches);
+}
+
+int do_thsearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
+  nick *sender = senderNSExtern = source;
+  struct searchNode *search;
+  int limit=500;
+  int arg=0;
+  THDisplayFunc display=defaultthfn;
+  searchCtx ctx;
+  int ret;
+  patricia_node_t *subset = iptree->head;
+
+  if (cargc<1)
+    return CMD_USAGE;
+
+  ret = parseopts(cargc, cargv, &arg, &limit, (void *)&subset, (void **)&display, reg_tgsearch->outputtree, reply, sender);
+  if(ret != CMD_OK)
+    return ret;
+
+  if (arg>=cargc) {
+    reply(sender,"No search terms - aborting.");
+    return CMD_ERROR;
+  }
+
+  if (arg<(cargc-1)) {
+    rejoinline(cargv[arg],cargc-arg);
+  }
+
+  newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_thsearch, sender, display, limit);
+
+  if (!(search = ctx.parser(&ctx, cargv[arg]))) {
+    reply(sender,"Parse error: %s",parseError);
+    return CMD_ERROR;
+  }
+
+  thsearch_exe(search, &ctx, sender, display, limit, subset);
+
+  (search->free)(&ctx, search);
+
+  return CMD_OK;
+}
+
+int do_thsearch(void *source, int cargc, char **cargv) {
+  return do_thsearch_real(controlreply, controlwallwrapper, source, cargc, cargv);
+}
+
+void thsearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, THDisplayFunc display, int limit, patricia_node_t *subset) {
+  int matches = 0;
+  trusthost_t *tgh;
+  int i;
+
+  /* Get a marker value to mark "seen" channels for unique count */
+  //nmarker=nextnodemarker();
+
+  /* The top-level node needs to return a BOOL */
+  search=coerceNode(ctx, search, RETURNTYPE_BOOL);
+
+  for ( i = 0; i < TRUSTS_HASH_HOSTSIZE ; i++ ) {
+    for ( tgh = trusthostidtable[i]; tgh; tgh = tgh -> nextbyid ) {
+      if ((search->exe)(ctx, search, tgh)) {
+      if (matches<limit)
+        display(ctx, sender, tgh);
+
+      if (matches==limit)
+        ctx->reply(sender, "--- More than %d matches, skipping the rest",limit);
+      matches++;
+    }
+  }
+  }
+  ctx->reply(sender,"--- End of list: %d matches",
+                matches);
+}
+
diff --git a/trusts_search/trusts_search.h b/trusts_search/trusts_search.h
new file mode 100644 (file)
index 0000000..b50fee3
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "../newsearch/newsearch.h"
+#include "../control/control.h"
+#include "../irc/irc_config.h"
+#include "../lib/irc_string.h"
+#include "../parser/parser.h"
+#include "../lib/splitline.h"
+#include "../lib/version.h"
+#include "../lib/stringbuf.h"
+#include "../lib/strlfunc.h"
+#include "../trusts2/trusts.h"
+
+extern searchCmd *reg_tgsearch;
+extern searchCmd *reg_thsearch;
+
+void printtg(searchCtx *ctx, nick *sender, trustgroup_t *tg);
+void printth(searchCtx *ctx, nick *sender, trusthost_t *tgh);
+void printtgfull(searchCtx *ctx, nick *sender, trustgroup_t *g);