configure.ac.local
config.h
settings.mk
+graphing/dump
FILE *logfile;
+static corehandler *coreh, *coret;
+
char *sevtostring(int severity) {
switch(severity) {
case ERR_DEBUG:
exit(0);
}
}
+
+void handlecore(void) {
+ corehandler *n;
+
+ /* no attempt is made to clean these up */
+ for(n=coreh;coreh;n=coreh->next)
+ (n->fn)(n->arg);
+}
+
+corehandler *registercorehandler(CoreHandlerFn fn, void *arg) {
+ corehandler *c = (corehandler *)malloc(sizeof(corehandler));
+ /* core if we can't allocate!! */
+
+ c->fn = fn;
+ c->arg = arg;
+ c->next = NULL;
+ c->prev = coret;
+ coret = c->prev;
+
+ if(!coreh)
+ coreh = c;
+
+ return c;
+}
+
+void deregistercorehandler(corehandler *c) {
+ if(!c->prev) {
+ coreh = c->next;
+ } else {
+ c->prev->next = c->next;
+ }
+
+ if(!c->next) {
+ coret = c->prev;
+ } else {
+ c->next->prev = c->prev;
+ }
+
+ free(c);
+}
+
char *source;
};
+typedef void (*CoreHandlerFn)(void *arg);
+
+typedef struct corehandler {
+ void *arg;
+ CoreHandlerFn fn;
+ struct corehandler *prev, *next;
+} corehandler;
+
void Error(char *source, int severity, char *reason, ... );
+corehandler *registercorehandler(CoreHandlerFn fn, void *arg);
+void deregistercorehandler(corehandler *c);
+
#endif
void init_logfile();
void siginthandler(int sig);
void sigusr1handler(int sig);
+void sigsegvhandler(int sig);
+void handlecore(void);
+
+static void (*oldsegv)(int);
int main(int argc, char **argv) {
initseed();
initmodules();
signal(SIGINT, siginthandler);
signal(SIGUSR1, sigusr1handler);
+ oldsegv = signal(SIGSEGV, sigsegvhandler);
/* Main loop */
for(;;) {
void sigusr1handler(int sig) {
newserv_sigusr1_pending = 1;
}
+
+void sigsegvhandler(int sig) {
+ handlecore();
+
+ oldsegv(sig);
+}
+
--- /dev/null
+@include@ @includel@../build.mk@includel@
+
+.PHONY: all
+all: graphing.so nterfacer_graphing.so dump
+
+graphing.so: graphing.o fsample.o
+
+nterfacer_graphing.so: nterfacer_graphing.o
+
+dump: dump.o fsample.o
+ $(CC) $(CFLAGS) -o $@ @srcs@
--- /dev/null
+#include "graphing.h"
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int dump(fsample_m *f, fsample_t start, fsample_t stop) {
+ int i, j;
+
+ for(i=start;i<stop;i++) {
+ printf("%2d ", i);
+ for(j=0;j<f->pos;j++) {
+ fsample_t t;
+ int moo = fsget_m(f, j, i, &t);
+
+ if(!moo) {
+ int moo2 = fsget_mr(f, j, i, &t);
+ printf("X%2d(%2d) ", t, moo2);
+ } else {
+ printf(" %2d(%2d) ", t, moo);
+ }
+ }
+ printf("\n");
+ }
+
+ return 0;
+}
+
+
+int main(int cargc, char **cargv) {
+ fsample_m *f;
+ int stop = time(NULL) / GRAPHING_RESOLUTION;
+ struct stat sb;
+
+ if(cargc < 2) {
+ puts("insufficient args");
+ return 1;
+ }
+
+ if(stat(cargv[1], &sb) == -1) {
+ puts("file doesn't exist");
+ return 2;
+ }
+
+ f = fsopen_m(0, cargv[1], SAMPLES, NULL, NULL);
+ if(!f)
+ return 3;
+
+ dump(f, stop - 100, stop);
+
+ fsclose_m(f);
+
+ return 0;
+}
+
--- /dev/null
+#include "fsample.h"
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct fsample_p {
+ fsample_t v;
+ unsigned char iteration;
+};
+
+struct fsample_header {
+ char magic[4];
+ fsample_t version;
+ unsigned char iteration;
+ fsample_t lastpos;
+};
+
+struct fsample {
+ struct fsample_p *m;
+ int fd;
+ size_t samples, len;
+ struct fsample_header *header;
+ void *corehandler;
+ CoreHandlerDelFn corehandlerdel;
+};
+
+static fsample_t version = 1;
+
+static void fscorefree(void *arg) {
+ fsample *f = (fsample *)arg;
+ munmap(f->header, f->len);
+}
+
+fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
+ int flags = 0;
+ int new = 0;
+ fsample *f = (fsample *)malloc(sizeof(fsample));
+ if(!f)
+ return NULL;
+
+ f->len = samples * sizeof(struct fsample_p) + sizeof(struct fsample_header);
+ f->fd = open(filename, O_RDWR|O_CREAT, 0600);
+
+ if(!lseek(f->fd, 0, SEEK_END))
+ new = 1;
+
+ if((f->fd == -1) || (lseek(f->fd, f->len - 1, SEEK_SET) == -1)) {
+ free(f);
+ return NULL;
+ }
+ write(f->fd, "", 1);
+
+ flags = MAP_SHARED;
+#ifdef MAP_NOCORE
+ flags|=MAP_NOCORE;
+#endif
+
+ f->header = mmap(NULL, f->len, PROT_READ|PROT_WRITE, flags, f->fd, 0);
+ if(f->header == MAP_FAILED) {
+ close(f->fd);
+ free(f);
+ return NULL;
+ }
+
+ if(!new && (memcmp(f->header->magic, "FSAMP", sizeof(f->header->magic)) || (version != f->header->version))) {
+ munmap(f->header, f->len);
+ close(f->fd);
+ free(f);
+ return NULL;
+ }
+
+ if(chafn && chdfn) {
+ f->corehandler = chafn(fscorefree, f);
+ f->corehandlerdel = chdfn;
+ } else {
+ f->corehandler = NULL;
+ f->corehandlerdel = NULL;
+ }
+
+ memcpy(f->header->magic, "FSAMP", sizeof(f->header->magic));
+ f->header->version = version;
+
+ f->m = (struct fsample_p *)(f->header + 1);
+ f->samples = samples;
+
+ if(f->header->iteration == 0)
+ f->header->iteration = 1;
+
+ return f;
+}
+
+void fsclose(fsample *f) {
+ munmap(f->header, f->len);
+ close(f->fd);
+
+ if(f->corehandlerdel && f->corehandler)
+ (f->corehandlerdel)(f->corehandler);
+
+ free(f);
+}
+
+static inline unsigned char previteration(fsample *f) {
+ unsigned char p = f->header->iteration - 1;
+ if(p == 0)
+ p = 255;
+ return p;
+}
+
+
+/* doesn't support writing to negative numbers... */
+inline void fsset(fsample *f, fsample_t pos, fsample_t value) {
+ fsample_t actualpos = pos % f->samples;
+ struct fsample_p *p = &f->m[actualpos];
+
+ if(f->header->lastpos > actualpos) {
+ f->header->iteration++;
+ if(f->header->iteration == 0)
+ f->header->iteration = 1;
+ }
+
+ f->header->lastpos = actualpos;
+
+ p->iteration = f->header->iteration;
+ p->v = value;
+}
+
+static inline fsample_t mmod(int x, int y) {
+#if -5 % 3 == -2
+ int v = x % y;
+ if(v < 0)
+ v = v + y;
+ return v;
+#else
+#error Unknown modulo operator function.
+#endif
+}
+
+/* API functions only have access to positive indicies */
+inline fsample_t __fsget(fsample *f, int pos, fsample_t *t) {
+ struct fsample_p *p = &f->m[mmod(pos, f->samples)];
+
+ if(p->iteration != f->header->iteration) {
+ unsigned char prev = previteration(f);
+
+ if(prev != p->iteration || (pos <= f->header->lastpos)) {
+ /*printf("bad: prev: %d p->iteration: %d, pos: %d lastpos: %d\n", prev, p->iteration, pos, f->header->lastpos);*/
+ return 0;
+ }
+ }
+
+ *t = p->v;
+ return p->iteration;
+}
+
+inline fsample_t fsget_r(fsample *f, fsample_t pos, fsample_t *t) {
+ struct fsample_p *p = &f->m[mmod(pos, f->samples)];
+
+ *t = p->v;
+ return p->iteration;
+}
+
+inline fsample_t fsget(fsample *f, fsample_t pos, fsample_t *t) {
+ return __fsget(f, pos, t);
+}
+
+int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag) {
+ fsample_m_entry *p = &f->entry[f->pos];
+
+ p->f = fsopen(filename, f->samples / freq, f->chafn, f->chdfn);
+ if(!p->f)
+ return 0;
+
+ p->freq = freq;
+ p->derive = derive;
+ p->tag = tag;
+ f->pos++;
+ return 1;
+}
+
+fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn) {
+ fsample_m *n = (fsample_m *)malloc(sizeof(fsample_m) + (count + 1) * sizeof(fsample_m_entry));
+ if(!n)
+ return NULL;
+
+ n->samples = samples;
+ n->pos = 0;
+ n->chafn = chafn;
+ n->chdfn = chdfn;
+
+ if(!fsadd_m(n, filename, 1, NULL, 0)) {
+ free(n);
+ return NULL;
+ }
+
+ return n;
+}
+
+void fsset_m(fsample_m *f, fsample_t pos, fsample_t value) {
+ int i;
+
+ for(i=0;i<f->pos;i++) {
+ fsample_t v;
+
+ if((pos + 1) % f->entry[i].freq != 0)
+ continue;
+
+ if(f->entry[i].derive) {
+ v = (f->entry[i].derive)(f, i, pos, f->entry[i].tag);
+ } else {
+ v = value;
+ }
+
+ fsset(f->entry[i].f, pos / f->entry[i].freq, v);
+ }
+}
+
+void fsclose_m(fsample_m *f) {
+ int i;
+
+ for(i=0;i<f->pos;i++)
+ fsclose(f->entry[i].f);
+ free(f);
+}
+
+inline fsample_t __fsget_m(fsample_m *f, int entry, int pos, fsample_t *t) {
+ return __fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
+}
+
+inline fsample_t fsget_m(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
+ return fsget(f->entry[entry].f, pos / f->entry[entry].freq, t);
+}
+
+inline fsample_t fsget_mr(fsample_m *f, int entry, fsample_t pos, fsample_t *t) {
+ return fsget_r(f->entry[entry].f, pos / f->entry[entry].freq, t);
+}
+
+fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag) {
+ fsample_t c = 0;
+ long samples = (long)tag;
+ int count = 0;
+ int rpos = pos / f->entry[0].freq;
+ int i;
+ fsample_t t;
+
+ for(i=0;i<samples;i++) {
+ if(__fsget_m(f, 0, rpos - i, &t)) {
+ c+=t;
+ count++;
+ } else {
+/* printf("bad :(\n");*/
+ }
+ }
+
+ if(count == 0)
+ return 0;
+
+ return c / count;
+}
+
+fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag) {
+ fsample_t c = 0;
+ long samples = (long)tag;
+ int count = 0;
+ int rpos = pos / f->entry[entry - 1].freq;
+ int i;
+ fsample_t t;
+
+ for(i=0;i<=samples;i++) {
+ if(__fsget(f->entry[entry - 1].f, rpos - i, &t)) {
+ c+=t;
+ count++;
+ } else {
+ /*printf("bad :(\n");*/
+ }
+ }
+
+ if(count == 0)
+ return 0;
+
+ return c / count;
+}
--- /dev/null
+#ifndef __FSAMPLE_H
+#define __FSAMPLE_H
+
+#include <sys/types.h>
+
+typedef u_int32_t fsample_t;
+
+typedef struct fsample fsample;
+
+/* nice loss of type safety here... */
+typedef void *(*CoreHandlerAddFn)(void *handler, void *arg);
+typedef void (*CoreHandlerDelFn)(void *);
+
+/* single sample functions */
+fsample *fsopen(char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
+void fsclose(fsample *f);
+inline void fsset(fsample *f, fsample_t pos, fsample_t value);
+inline fsample_t fsget(fsample *f, fsample_t pos, fsample_t *t);
+inline fsample_t fsget_r(fsample *f, fsample_t pos, fsample_t *t);
+
+struct fsample_m;
+typedef fsample_t (*DeriveValueFn)(struct fsample_m *v, int entry, fsample_t pos, void *tag);
+
+typedef struct fsample_m_entry {
+ size_t freq;
+ fsample *f;
+ void *tag;
+ DeriveValueFn derive;
+} fsample_m_entry;
+
+typedef struct fsample_m {
+ size_t pos, samples;
+ CoreHandlerAddFn chafn;
+ CoreHandlerDelFn chdfn;
+ struct fsample_m_entry entry[];
+} fsample_m;
+
+/* multiple sample functions */
+fsample_m *fsopen_m(size_t count, char *filename, size_t samples, CoreHandlerAddFn chafn, CoreHandlerDelFn chdfn);
+void fsclose_m(fsample_m *f);
+int fsadd_m(fsample_m *f, char *filename, size_t freq, DeriveValueFn derive, void *tag);
+void fsset_m(fsample_m *f, fsample_t pos, fsample_t value);
+inline fsample_t fsget_m(fsample_m *f, int entry, fsample_t pos, fsample_t *t);
+inline fsample_t fsget_mr(fsample_m *f, int entry, fsample_t pos, fsample_t *t);
+
+/* aggregates */
+fsample_t fsamean(fsample_m *f, int entry, fsample_t pos, void *tag);
+fsample_t fsapmean(fsample_m *f, int entry, fsample_t pos, void *tag);
+
+#endif
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+
+#include "../core/hooks.h"
+#include "../core/config.h"
+#include "../usercount/usercount.h"
+#include "../lib/sstring.h"
+#include "../core/schedule.h"
+#include "../core/error.h"
+#include "../lib/sha1.h"
+#include "../lib/hmac.h"
+
+#include "graphing.h"
+
+static void gr_newserver(int hook, void *arg);
+static void gr_lostserver(int hook, void *arg);
+static void tick(void *arg);
+static void openserver(int servernum);
+static void closeserver(int servernum);
+
+fsample_m *servergraphs[MAXSERVERS];
+static void *sched;
+
+static sstring *path;
+
+void _init(void) {
+ int i;
+
+ memset(servergraphs, 0, sizeof(servergraphs));
+
+ path = getcopyconfigitem("graphing", "path", "", 100);
+ if(!path || !path->content || !path->content[0]) {
+ Error("graphing", ERR_WARNING, "Path not set, not loaded.");
+ return;
+ }
+
+ for(i=0;i<MAXSERVERS;i++)
+ openserver(i);
+
+ registerhook(HOOK_SERVER_NEWSERVER, gr_newserver);
+ registerhook(HOOK_SERVER_LOSTSERVER, gr_lostserver);
+
+ sched = schedulerecurring(time(NULL), 0, 1, tick, NULL);
+}
+
+void _fini(void) {
+ int i;
+ if(sched)
+ deleteschedule(sched, tick, NULL);
+
+ for(i=0;i<MAXSERVERS;i++)
+ if(servermonitored(i))
+ closeserver(i);
+
+ freesstring(path);
+
+ deregisterhook(HOOK_SERVER_NEWSERVER, gr_newserver);
+ deregisterhook(HOOK_SERVER_LOSTSERVER, gr_lostserver);
+}
+
+int servermonitored(int servernum) {
+ return servergraphs[servernum] != NULL;
+}
+
+static char *appendsuffix(char *prefix, char *suffix) {
+ static char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%s%s", prefix, suffix);
+
+ return buf;
+}
+
+static void openserver(int servernum) {
+ unsigned char digest[SHA1_DIGESTSIZE];
+ char filename[512], hexdigest[sizeof(digest)*2 + 1];
+ FILE *f;
+ SHA1_CTX sha;
+ fsample_m *m;
+
+ if(servermonitored(servernum))
+ return;
+
+ if(serverlist[servernum].linkstate == LS_INVALID)
+ return;
+
+ SHA1Init(&sha);
+ SHA1Update(&sha, (unsigned char *)serverlist[servernum].name->content, serverlist[servernum].name->length);
+ SHA1Final(digest, &sha);
+
+ snprintf(filename, sizeof(filename), "%s/%s", path->content, hmac_printhex(digest, hexdigest, sizeof(digest)));
+
+ f = fopen(appendsuffix(filename, ".name"), "w");
+ if(!f) {
+ Error("graphing", ERR_WARNING, "Unable to create name file for %s (%s.name)", serverlist[servernum].name->content, filename);
+ return;
+ }
+
+ fprintf(f, "%s\n", serverlist[servernum].name->content);
+ fclose(f);
+
+ /* 0: seconds
+ 1: minutes
+ 2: hours
+ 3: days
+ 4: weeks
+ 5: months
+ */
+
+ m = fsopen_m(GRAPHING_DATASETS, appendsuffix(filename, ".0"), SAMPLES, (CoreHandlerAddFn)registercorehandler, (CoreHandlerDelFn)deregistercorehandler);
+ if(!m) {
+ Error("graphing", ERR_WARNING, "Unable to create main backing store for %s (%s.0)", serverlist[servernum].name->content, filename);
+ return;
+ }
+/*
+ if(!fsadd_m(m, appendsuffix(filename, ".1"), PERMINUTE, fsapmean, (void *)PERMINUTE) ||
+ !fsadd_m(m, appendsuffix(filename, ".2"), PERMINUTE * 24, fsapmean, (void *)(PERMINUTE * 24)) ||
+ !fsadd_m(m, appendsuffix(filename, ".3"), PERMINUTE * 24 * 7, fsapmean, (void *)(PERMINUTE * 24 * 7)) ||
+ !fsadd_m(m, appendsuffix(filename, ".4"), PERMINUTE * 24 * 7 * 4, fsapmean, (void *)(PERMINUTE * 24 * 7 * 4)) ||
+ !fsadd_m(m, appendsuffix(filename, ".5"), PERMINUTE * 24 * 7 * 4 * 12, fsapmean, (void *)(PERMINUTE * 24 * 7 * 4 * 12)))
+ {
+ Error("graphing", ERR_WARNING, "Unable to create main side store for %s (%s.X)", serverlist[servernum].name->content, filename);
+ fsclose_m(m);
+ return;
+ }
+*/
+ servergraphs[servernum] = m;
+}
+
+static void closeserver(int servernum) {
+ if(!servermonitored(servernum))
+ return;
+
+ fsclose_m(servergraphs[servernum]);
+ servergraphs[servernum] = NULL;
+}
+
+static void gr_newserver(int hook, void *arg) {
+ long num = (long)arg;
+
+ openserver(num);
+}
+
+static void gr_lostserver(int hook, void *arg) {
+ long num = (long)arg;
+
+ closeserver(num);
+}
+
+static void tick(void *arg) {
+ time_t t = time(NULL);
+ int i;
+
+ if(t % GRAPHING_RESOLUTION != 0)
+ return;
+
+ for(i=0;i<MAXSERVERS;i++)
+ if(servermonitored(i))
+ fsset_m(servergraphs[i], t / GRAPHING_RESOLUTION, servercount[i]);
+}
+
+
--- /dev/null
+#ifndef __GRAPHING_H
+#define __GRAPHING_H
+
+#include "../server/server.h"
+#include "../graphing/fsample.h"
+
+extern fsample_m *servergraphs[MAXSERVERS];
+int servermonitored(int servernum);
+
+#define GRAPHING_DATASETS 5
+#define GRAPHING_RESOLUTION 5
+
+#define PERMINUTE (60 / GRAPHING_RESOLUTION)
+#define SAMPLES PERMINUTE * 60 * 24 * 7 * 4 * 12
+
+#endif
--- /dev/null
+#include "../nterfacer/library.h"
+#include "../nterfacer/nterfacer.h"
+
+#include "graphing.h"
+
+#include <time.h>
+
+#define ERR_SERVER_NOT_MONITORED 0x01
+#define ERR_BAD_PARAMETERS 0x02
+#define ERR_BAD_ENTRY 0x03
+
+int handle_servernames(struct rline *li, int argc, char **argv);
+int handle_serverdata(struct rline *li, int argc, char **argv);
+
+static struct service_node *g_node;
+
+void _init(void) {
+ g_node = register_service("graphing");
+ if(!g_node)
+ return;
+
+ register_handler(g_node, "servernames", 0, handle_servernames);
+ register_handler(g_node, "serverdata", 3, handle_serverdata);
+}
+
+void _fini(void) {
+ if(g_node)
+ deregister_service(g_node);
+}
+
+int handle_servernames(struct rline *li, int argc, char **argv) {
+ int i;
+
+ for(i=0;i<MAXSERVERS;i++) {
+ if((serverlist[i].linkstate != LS_INVALID) && servermonitored(i)) {
+ if(ri_append(li, "%d:%s", i, serverlist[i].name->content) == BF_OVER)
+ return ri_error(li, BF_OVER, "Buffer overflow");
+ }
+ }
+
+ return ri_final(li);
+}
+
+int handle_serverdata(struct rline *li, int argc, char **argv) {
+ int servernum = atoi(argv[0]);
+ unsigned int entry = atoi(argv[1]);
+ fsample_t count = atoi(argv[2]);
+ time_t t = time(NULL) / GRAPHING_RESOLUTION;
+ int i, ret;
+ fsample_m *m;
+
+ if(!servermonitored(servernum))
+ return ri_error(li, ERR_SERVER_NOT_MONITORED, "Server not monitored");
+
+ m = servergraphs[servernum];
+
+ if(entry > m->pos) /* not inclusive as 0 is used for for the base index */
+ return ri_error(li, ERR_BAD_PARAMETERS, "Bad parameters");
+
+ for(i=0;i<count;i++) {
+ fsample_t v;
+ if(fsget_m(m, entry, t - m->entry[entry].freq * i, &v)) {
+ ret = ri_append(li, "%d", v);
+ } else {
+ ret = ri_append(li, "-1", v);
+ }
+ if(ret == BF_OVER)
+ return ri_error(li, BF_OVER, "Buffer overflow");
+ }
+
+ return ri_final(li);
+}
+
#include <sys/types.h>
#include <netinet/in.h>
+#include "../lib/sstring.h"
+
#include "esockets.h"
#include "library.h"
}
}
- irc_send("%s GL * +%s %d :AUTO: %s (ID: %08lx)\r\n", mynumeric->content, hostname, rg_expiry_time, delay->reason->reason->content, delay->reason->glineid);
+ irc_send("%s GL * +%s %d %d :AUTO: %s (ID: %08lx)\r\n", mynumeric->content, hostname, rg_expiry_time, time(NULL), delay->reason->reason->content, delay->reason->glineid);
rg_deletedelay(delay);
}
rg_sqlescape_string(eereason, cargv[3], strlen(cargv[3]));
rg_sqlquery("INSERT INTO regexglines (gline, setby, reason, expires, type) VALUES ('%s', '%s', '%s', %d, %s)", eemask, eesetby, eereason, realexpiry, cargv[2]);
- if (!rg_sqlquery("SELECT id FROM regexglines WHERE gline = '%s' AND setby = '%s' AND reason = '%s' AND expires = %d AND type = %s ORDER BY ID DESC LIMIT 1", eemask, eesetby, eereason, realexpiry, cargv[2])) {
+ if (!rg_sqlquery("SELECT LAST_INSERT_ID()")) {
rg_sqlresult res;
if((res = rg_sqlstoreresult())) {
rg_sqlrow row;
row = rg_sqlgetrow(res);
if (row) {
- rp = rg_newsstruct(row[0], cargv[0], np->nick, cargv[3], "", cargv[2], realexpiry, 0);
+ int id = atoi(row[0]);
+ if(id == 0) {
+ rp = NULL;
+ } else {
+ rp = rg_newsstruct(row[0], cargv[0], np->nick, cargv[3], "", cargv[2], realexpiry, 0);
+ }
rg_sqlfree(res);
if(!rp) {
rg_sqlquery("DELETE FROM regexglines WHERE gline = '%s' AND setby = '%s' AND reason = '%s' AND expires = %d AND type = %s ORDER BY ID DESC LIMIT 1", eemask, eesetby, eereason, realexpiry, cargv[2]);
if(length >= RG_QUERY_BUF_SIZE)
length = RG_QUERY_BUF_SIZE - 1;
- mysql_escape_string(dest, source, length);
+ mysql_real_escape_string(&rg_sql, dest, source, length);
}
int rg_sqlquery(char *format, ...) {
}
}
- irc_send("%s GL * +%s %d :AUTO: %s (ID: %08lx)\r\n", mynumeric->content, hostname, rg_expiry_time, rp->reason->content, rp->glineid);
+ irc_send("%s GL * +%s %d %d :AUTO: %s (ID: %08lx)\r\n", mynumeric->content, hostname, rg_expiry_time, time(NULL), rp->reason->content, rp->glineid);
return usercount;
}
-int floodprotection = 0;
+static int floodprotection = 0;
+static int lastfloodspam = 0;
void rg_dogline(struct rg_glinelist *gll, nick *np, struct rg_struct *rp, char *matched) {
int t = time(NULL);
if(t > floodprotection) {
floodprotection = t;
} else if((floodprotection - t) / 8 > RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC) {
- channel *cp = findchannel("#twilightzone");
- if(cp)
- controlchanmsg(cp, "WARNING! REGEXGLINE DISABLED FOR AN HOUR DUE TO NETWORK WIDE LOOKING GLINE!");
- controlwall(NO_OPER, NL_MANAGEMENT, "WARNING! REGEXGLINE DISABLED FOR AN HOUR DUE TO NETWORK WIDE LOOKING GLINE!");
- floodprotection = t + RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC * 3600 * 8;
+ if(t > lastfloodspam + 3600) {
+ channel *cp = findchannel("#twilightzone");
+ if(cp)
+ controlchanmsg(cp, "WARNING! REGEXGLINE DISABLED FOR AN HOUR DUE TO NETWORK WIDE LOOKING GLINE!: %d exceeded %d", (floodprotection - t) / 8, RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC);
+ controlwall(NO_OPER, NL_MANAGEMENT, "WARNING! REGEXGLINE DISABLED FOR AN HOUR DUE TO NETWORK WIDE LOOKING GLINE!");
+ lastfloodspam = t;
+ floodprotection = t + RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC * 3600 * 8;
+ }
+ return;
}
floodprotection+=__rg_dogline(gll, np, rp, matched);
#define RG_MINIMUM_DELAY_TIME 5
#define RG_MAXIMUM_RAND_TIME 15
#define RG_EXPIRY_TIME_DEFAULT 1800
-#define RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC 625 /* 5000 / 8 */
+#define RG_NETWORK_WIDE_MAX_GLINES_PER_8_SEC 625*8 /* 5000 / 8 */
#define RGStringise(x) #x
#define RGBuildHostname(buf, np) snprintf(buf, sizeof(buf), "%s!%s@%s\r%s", np->nick, np->ident, np->host->name->content, np->realname->name->content);