+#include <stdio.h>
+#include <stdarg.h>
#include "../dbapi2/dbapi2.h"
#include "../core/error.h"
#include "../core/hooks.h"
#include "../core/schedule.h"
+#include "../control/control.h"
#include "trusts.h"
DBAPIConn *trustsdb;
/* I'd like multiple keys here but that's not gonna happen on a cross-database platform :( */
trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, lastseen INT)", "Td", hosts, TRUSTHOSTLEN);
+
+ trustsdb->createtable(trustsdb, NULL, NULL,
+ "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, ts INT, username VARCHAR(?), message VARCHAR(?))",
+ "Tdd", "log", CREATEDBYLEN, TRUSTLOGLEN
+ );
}
static void flushdatabase(void *arg) {
th_linktree();
}
+void trustlog(unsigned int groupid, const char *user, const char *format, ...) {
+ char buf[TRUSTLOGLEN+1];
+ va_list va;
+ unsigned int now;
+
+ va_start(va, format);
+ vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+
+ now = time(NULL);
+
+ trustsdb->squery(trustsdb,
+ "INSERT INTO ? (ts, groupid, username, message) VALUES (?, ?, ?, ?)",
+ "Tuuss", "log", now, groupid, user, buf);
+}
+
+static void trustlogquery_callback(const struct DBAPIResult *result, void *arg) {
+ nick *np = (nick *)arg;
+ int rows = 0;
+
+ if(!result || !result->success) {
+ controlreply(np, "Error querying the log.");
+
+ if(result)
+ result->clear(result);
+
+ return;
+ }
+
+ while(result->next(result)) {
+ unsigned int ts, groupid;
+ char *user, *message;
+
+ ts = strtoul(result->get(result, 0), NULL, 10);
+ groupid = strtoul(result->get(result, 1), NULL, 10);
+ user = result->get(result, 2);
+ message = result->get(result, 3);
+
+ controlreply(np, "[%s] #%d (%s) %s", trusts_timetostr(ts), groupid, user, message);
+ rows++;
+ }
+
+ controlreply(np, "--- Done. Found %d rows.", rows);
+}
+
+void trustlogspew(nick *np, unsigned int groupid, unsigned int limit) {
+ trustsdb->query(trustsdb, trustlogquery_callback, (void *)np,
+ "SELECT ts, groupid, username, message FROM ? WHERE groupid = ? ORDER BY ts DESC LIMIT ?",
+ "Tuu", "log", groupid, limit);
+}
+
+void trustloggrep(nick *np, const char *pattern, unsigned int limit) {
+ char buf[512];
+ snprintf(buf, sizeof(buf), "%%%s%%", pattern);
+
+ trustsdb->query(trustsdb, trustlogquery_callback, (void *)np,
+ "SELECT ts, groupid, username, message FROM ? WHERE message LIKE ? ORDER BY ts DESC LIMIT ?",
+ "Tsu", "log", buf, limit);
+}
+
void _init(void) {
trusts_connectdb();
}
triggerhook(HOOK_TRUSTS_ADDHOST, th);
controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTADD'ed host %s to group '%s'", controlid(sender), host, th->group->name->content);
+ trustlog(tg->id, controlid(sender), "Added host '%s'.", host);
return CMD_OK;
}
triggerhook(HOOK_TRUSTS_ADDGROUP, tg);
controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTGROUPADD'ed '%s'", controlid(sender), tg->name->content);
+ trustlog(tg->id, controlid(sender), "Created trust group '%s' (ID #%d): howmany=%d, enforceident=%d, maxperident=%d, "
+ "expires=%d, createdby=%s, contact=%s, comment=%s",
+ tg->name->content, howmany, tg->id, enforceident, maxperident, howlong + time(NULL), createdby, contact, comment);
return CMD_OK;
}
}
controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTGROUPDEL'ed '%s'.", controlid(sender), tg->name->content);
+ trustlog(tg->id, controlid(sender), "Deleted group '%s'.", tg->name->content);
triggerhook(HOOK_TRUSTS_DELGROUP, tg);
tg_delete(tg);
controlreply(sender, "Host deleted.");
controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTDEL'ed %s from group '%s'.", controlid(sender), host, tg->name->content);
+ trustlog(tg->id, controlid(sender), "Removed host '%s'.", host);
return CMD_OK;
}
controlreply(sender, "Group modified.");
controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTMODIFIED'ed group '%s' (field: %s, value: %s)", controlid(sender), tg->name->content, what, to);
+ trustlog(tg->id, controlid(sender), "Modified %s: %s", what, to);
return CMD_OK;
}
+static int trusts_cmdtrustlogspew(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ trustgroup *tg = NULL;
+ char *name;
+ int groupid;
+ int limit = 0;
+
+ if(cargc < 1)
+ return CMD_USAGE;
+
+ name = cargv[0];
+
+ tg = tg_strtotg(name);
+
+ if(tg)
+ groupid = tg->id;
+ else if (name[0] == '#')
+ groupid = strtoul(name + 1, NULL, 10);
+ else {
+ controlreply(sender, "Invalid trust group name or ID.");
+ return CMD_OK;
+ }
+
+ if(cargc>1)
+ limit = strtoul(cargv[1], NULL, 10);
+
+ if(limit==0)
+ limit = 100;
+
+ trustlogspew(sender, groupid, limit);
+
+ return CMD_OK;
+}
+
+static int trusts_cmdtrustloggrep(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ char *pattern;
+ int limit = 0;
+
+ if(cargc < 1)
+ return CMD_USAGE;
+
+ pattern = cargv[0];
+
+ if(cargc>1)
+ limit = strtoul(cargv[1], NULL, 10);
+
+ if(limit==0)
+ limit = 100;
+
+ trustloggrep(sender, pattern, limit);
+
+ return CMD_OK;
+}
+
+static int trusts_cmdtrustcomment(void *source, int cargc, char **cargv) {
+ nick *sender = source;
+ trustgroup *tg = NULL;
+ char *name, *comment;
+
+ if(cargc < 2)
+ return CMD_USAGE;
+
+ name = cargv[0];
+ comment = cargv[1];
+
+ tg = tg_strtotg(name);
+
+ if(!tg) {
+ controlreply(sender, "Invalid trust group name or ID.");
+ return CMD_OK;
+ }
+
+ trustlog(tg->id, controlid(sender), "Comment: %s", comment);
+
+ return CMD_OK;
+}
+
+
static int commandsregistered;
static void registercommands(int hooknum, void *arg) {
registercontrolhelpcmd("trustgroupdel", NO_OPER, 1, trusts_cmdtrustgroupdel, "Usage: trustgroupdel <#id|name|id>");
registercontrolhelpcmd("trustdel", NO_OPER, 2, trusts_cmdtrustdel, "Usage: trustdel <#id|name|id> <ip/mask>");
registercontrolhelpcmd("trustgroupmodify", NO_OPER, 3, trusts_cmdtrustgroupmodify, "Usage: trustgroupmodify <#id|name|id> <field> <new value>");
+ registercontrolhelpcmd("trustlogspew", NO_OPER, 2, trusts_cmdtrustlogspew, "Usage: trustlogspew <#id|name> [limit]\nShows log for the specified trust group.");
+ registercontrolhelpcmd("trustloggrep", NO_OPER, 2, trusts_cmdtrustloggrep, "Usage trustloggrep <pattern> [limit]\nShows maching log entries.");
+ registercontrolhelpcmd("trustcomment", NO_OPER, 2, trusts_cmdtrustcomment, "Usage: trustcomment <#id|name> <comment>\nLogs a comment for a trust.");
}
static void deregistercommands(int hooknum, void *arg) {
deregistercontrolcmd("trustgroupdel", trusts_cmdtrustgroupdel);
deregistercontrolcmd("trustdel", trusts_cmdtrustdel);
deregistercontrolcmd("trustgroupmodify", trusts_cmdtrustgroupmodify);
+ deregistercontrolcmd("trustlogspew", trusts_cmdtrustlogspew);
+ deregistercontrolcmd("trustloggrep", trusts_cmdtrustloggrep);
+ deregistercontrolcmd("trustcomment", trusts_cmdtrustcomment);
}
static int loaded;