#include <string.h>
#include <ctype.h>
#include <sys/types.h>
-#include <regex.h>
+#include <pcre.h>
-regex_t remail, raccount;
-static int regexinit;
+static pcre *remail, *raccount;
-int csa_initregex(void) {
- if (regexinit)
- return 1;
+void csa_initregex(void) {
+ const char *errptr;
+ int erroffset;
- if (regcomp(&remail, VALID_EMAIL, REG_EXTENDED | REG_NOSUB | REG_ICASE))
- return 0;
+ if (!(remail=pcre_compile(VALID_EMAIL, PCRE_CASELESS, &errptr, &erroffset, NULL)))
+ Error("chanserv", ERR_STOP, "Unable to compile email regex (error: %s, position: %d).", errptr, erroffset);
- if (regcomp(&raccount, VALID_ACCOUNT_NAME, REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
- regfree(&remail);
- return 0;
- }
-
- regexinit = 1;
- return 1;
+ if (!(raccount=pcre_compile(VALID_ACCOUNT_NAME, PCRE_CASELESS, &errptr, &erroffset, NULL)))
+ Error("chanserv", ERR_STOP, "Unable to compile account name regex (error: %s, position: %d).", errptr, erroffset);
}
void csa_freeregex(void) {
- if(!regexinit)
- return;
-
- regfree(&remail);
- regfree(&raccount);
- regexinit = 0;
+ pcre_free(remail);
+ pcre_free(raccount);
}
/*
*/
int csa_checkeboy_r(char *eboy)
{
- int i, len;
+ int len;
len = (((strlen(eboy)) < (EMAILLEN)) ? (strlen(eboy)) : (EMAILLEN));
if (len <= 4) {
return QM_EMAILTOOSHORT;
}
- if (strstr(&eboy[1], "@") == NULL) {
- return QM_EMAILNOAT;
- }
-
- if (eboy[len - 1] == '@') {
- return QM_EMAILATEND;
- }
-
- for (i = 0; i < len; i++) {
- if (!isalpha(eboy[i]) && !isdigit(eboy[i])
- && !(eboy[i] == '@') && !(eboy[i] == '.')
- && !(eboy[i] == '_') && !(eboy[i] == '-')) {
- return QM_EMAILINVCHR;
- }
- }
-
/* catch some real lame attempts */
if (!ircd_strncmp("user@mymailhost.xx", eboy, len) || !ircd_strncmp("info@quakenet.org", eboy, len)
|| !ircd_strncmp("user@mymail.xx", eboy, len) || !ircd_strncmp("user@mail.cc", eboy, len)
return QM_NOTYOUREMAIL;
}
- if (regexec(&remail, eboy, (size_t) 0, NULL, 0)) {
+ if (pcre_exec(remail, NULL, eboy, strlen(eboy), 0, 0, NULL, 0) < 0) {
return QM_INVALIDEMAIL;
}
/*
* use regex matching to determine if it's a valid account name or not
+ * returns 1 if bad, 0 if good
*/
int csa_checkaccountname_r(char *accountname) {
- if (regexec(&raccount, accountname, (size_t) 0, NULL, 0)) {
+ if (pcre_exec(raccount, NULL, accountname, strlen(accountname), 0, 0, NULL, 0) < 0) {
return (1);
}
return (0);
/* Functions in authlib.c */
int cs_checkeboy(nick *np, char *arg);
void cs_createrandompw(char *arg, int n);
-int csa_initregex(void);
+void csa_initregex(void);
void csa_freeregex(void);
int csa_checkaccountname(nick *sender, char *accountname);
int csa_checkaccountname_r(char *accountname);
/* email */
#define MAX_RESEND_TIME 2*3600L /* cooling off period */
-#define VALID_EMAIL "^[-_.+[:alpha:][:digit:]]+(\\.[-_[:digit:][:alpha:]]+)*@([[:digit:][:alpha:]](-?[[:digit:][:alpha:]])*\\.)+[[:alpha:]]{2}([zmuvtgol]|fo|me|seum|op|ro)?$"
+#define VALID_EMAIL "\\A[^\\s\\+@]+@([a-z0-9][a-z0-9\\-]*\\.)+[a-z]{2,}\\Z"
-#define VALID_ACCOUNT_NAME "^[a-z][-a-z0-9]+$"
+#define VALID_ACCOUNT_NAME "\\A[a-z][a-z0-9\\-]+\\Z"
#define QMAIL_NEWACCOUNT 1 /* new account */
#define QMAIL_REQPW 2 /* requestpassword */
#include "../localuser/localuserchannel.h"
#include "glines.h"
+//#define DEBUG
+
+#ifdef DEBUG
+#define Debug(...) Error("debuggline", ERR_DEBUG, ##__VA_ARGS__)
+#else
+#define Debug(...)
+#endif
+
/*
<prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>] [<lifetime>] [:<reason>]
*/
return CMD_ERROR;
}
- Error("debuggline", ERR_WARNING, "GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);
+ Debug("GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);
agline = findgline(mask);
if (agline) {
- Error("debuggline", ERR_WARNING, "Update for existing gline received for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason ? agline->reason->content : "", agline->creator->content);
+ Debug("Update for existing gline received for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason ? agline->reason->content : "", agline->creator->content);
agline->flags |= GLINE_ACTIVE;
freesstring(agline->reason);
agline->reason = getsstring(reason, 255);
} else {
- Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
+ Debug("received a gline with a lower lastmod");
/* Don't send our gline as that might cause loops in case we don't understand the gline properly. */
}
freesstring(agline->reason);
agline->reason = getsstring(reason, 255);
} else {
- Error("debuggline", ERR_WARNING, "received a gline modification with a lower lastmod");
+ Debug("received a gline modification with a lower lastmod");
}
return CMD_OK;
} else {
- Error("gline", ERR_WARNING, "Received modification for G-Line that does not exist for mask %s", mask);
+ Debug("Received modification for G-Line that does not exist for mask %s", mask);
return CMD_ERROR;
}
}
/* The top-level node needs to return a BOOL */
search=coerceNode(ctx, search, RETURNTYPE_BOOL);
- for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
- ww = &whowasrecs[i % WW_MAXENTRIES];
+ for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+ ww = &whowasrecs[i % whowasmax];
if (ww->type == WHOWAS_UNUSED)
continue;
}
}
} else {
- for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
- ww = &whowasrecs[i % WW_MAXENTRIES];
+ for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+ ww = &whowasrecs[i % whowasmax];
if (ww->type == WHOWAS_UNUSED)
continue;
#include "patricia.h"
+//#define LEAK_DETECTION
+
+#ifdef LEAK_DETECTION
+#define MAGIC 0x6a3b4ef3
+
+struct fake_node {
+ patricia_node_t node;
+ uint32_t magic;
+ patricia_node_t *real_node;
+};
+#endif
+
/* prefix_tochar
* convert prefix information to bytes
*/
}
}
+#ifdef LEAK_DETECTION
+static patricia_node_t *getrealnode(patricia_node_t *node) {
+ struct fake_node *f = (struct fake_node *)node;
+ if(f->magic != MAGIC) {
+ printf("magic failure\n");
+ abort();
+ }
+ return f->real_node;
+}
+#endif
patricia_node_t *
refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) {
patricia_ref_prefix(node->prefix);
}
+#ifdef LEAK_DETECTION
+ struct fake_node *f = malloc(sizeof(struct fake_node));
+ f->magic = MAGIC;
+ f->node = *node;
+ f->real_node = node;
+ node = (patricia_node_t *)f;
+#endif
+
return node;
}
if (!node || !node->prefix)
return;
+#ifdef LEAK_DETECTION
+ patricia_node_t *real_node = getrealnode(node);
+ free(node);
+ node = real_node;
+
+ if (!node || !node->prefix)
+ return;
+#endif
+
if (node->prefix->ref_count == 1) {
patricia_remove(tree, node);
} else
}
void node_increment_usercount( patricia_node_t *node) {
+#ifdef LEAK_DETECTION
+ node = getrealnode(node);
+#endif
+
while(node) {
node->usercount++;
node=node->parent;
}
void node_decrement_usercount( patricia_node_t *node) {
+#ifdef LEAK_DETECTION
+ node = getrealnode(node);
+#endif
+
while(node) {
node->usercount--;
node=node->parent;
#include "../irc/irc.h"
#include "../lib/irc_string.h"
#include "../lib/version.h"
+#include "../core/config.h"
#include "whowas.h"
MODULE_VERSION("");
-whowas whowasrecs[WW_MAXENTRIES];
+whowas *whowasrecs;
int whowasoffset = 0;
+int whowasmax;
whowas *whowas_fromnick(nick *np, int standalone) {
whowas *ww;
else {
ww = &whowasrecs[whowasoffset];
whowas_clean(ww);
- whowasoffset = (whowasoffset + 1) % WW_MAXENTRIES;
+ whowasoffset = (whowasoffset + 1) % whowasmax;
}
memset(ww, 0, sizeof(whowas));
freesstring(np->opername);
freeauthname(np->auth);
freesstring(np->away);
-
+ derefnode(iptree, np->ipnode);
freesstring(ww->reason);
+ freesstring(ww->newnick);
ww->type = WHOWAS_UNUSED;
}
now = getnettime();
- for (i = whowasoffset + WW_MAXENTRIES - 1; i >= whowasoffset; i--) {
- ww = &whowasrecs[i % WW_MAXENTRIES];
+ for (i = whowasoffset + whowasmax - 1; i >= whowasoffset; i--) {
+ ww = &whowasrecs[i % whowasmax];
if (ww->type == WHOWAS_UNUSED)
continue;
if (!whowasmarker) {
/* If we wrapped to zero, zap the marker on all records */
- for (i = 0; i < WW_MAXENTRIES; i++) {
- ww = &whowasrecs[i % WW_MAXENTRIES];
+ for (i = 0; i < whowasmax; i++) {
+ ww = &whowasrecs[i % whowasmax];
ww->marker=0;
}
}
void _init(void) {
- memset(whowasrecs, 0, sizeof(whowasrecs));
+ {
+ sstring *temp = getcopyconfigitem("whowas", "maxentries", XStringify(WW_DEFAULT_MAXENTRIES), 10);
+ whowasmax = atoi(temp->content);
+ freesstring(temp);
+ }
+ whowasrecs = calloc(whowasmax, sizeof(whowas));
registerhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
registerhook(HOOK_NICK_KILL, whowas_handlequitorkill);
deregisterhook(HOOK_NICK_KILL, whowas_handlequitorkill);
deregisterhook(HOOK_NICK_RENAME, whowas_handlerename);
- for (i = 0; i < WW_MAXENTRIES; i++) {
+ for (i = 0; i < whowasmax; i++) {
ww = &whowasrecs[i];
whowas_clean(ww);
}
+
+ free(whowasrecs);
}
#define __WHOWAS_H
#define WW_MAXCHANNELS 20
-#define WW_MAXENTRIES 1000000
+#define WW_DEFAULT_MAXENTRIES 1000
#define WW_MASKLEN (HOSTLEN + USERLEN + NICKLEN)
#define WW_REASONLEN 512
struct whowas *prev;
} whowas;
-extern whowas whowasrecs[WW_MAXENTRIES];
+extern whowas *whowasrecs;
+extern int whowasmax;
extern int whowasoffset; /* points to oldest record */
#define WHOWAS_UNUSED 0
if (cargc > 1)
limit = strtol(cargv[1], NULL, 10);
- for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
- ww = &whowasrecs[i % WW_MAXENTRIES];
+ for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+ ww = &whowasrecs[i % whowasmax];
if (ww->type == WHOWAS_UNUSED)
continue;