return CMD_ERROR;
}
- if (*cargv[0] != '#') {
+ if (*cargv[0] != '#' || strlen(cargv[0]) > CHANNELLEN) {
chanservstdmessage(sender, QM_INVALIDCHANNAME, cargv[0]);
return CMD_ERROR;
}
void rotatechanstats();
void savechanstats();
void loadchanstats();
+int dochanstatssave(void *source, int argc, char **argv);
int dochanstats(void *source, int argc, char **argv);
int doexpirecheck(void *source, int cargc, char **cargv);
int douserhistogram(void *source, int cargc, char **cargv);
registercontrolcmd("channelhistogram",10,13,&dochanhistogram);
registercontrolcmd("userhistogram",10,1,&douserhistogram);
registercontrolcmd("expirecheck",10,1,&doexpirecheck);
+ registercontrolhelpcmd("chanstatssave",NO_DEVELOPER,1, &dochanstatssave, "Usage: chanstatssave\nForce a save of chanstats data");
schedulerecurring(when,0,SAMPLEINTERVAL,&doupdate,NULL);
}
}
deregistercontrolcmd("channelhistogram",&dochanhistogram);
deregistercontrolcmd("userhistogram",&douserhistogram);
deregistercontrolcmd("expirecheck",&doexpirecheck);
+ deregistercontrolcmd("chanstatssave",&dochanstatssave);
releasechanext(csext);
cstsfreeall();
}
chanindex *cip;
chanstats *chp;
- if ((fp=fopen("chanstats","w"))==NULL) {
+ if ((fp=fopen("data/chanstats","w"))==NULL) {
return;
}
chanstats *chp;
chanindex *cip;
- if ((fp=fopen("chanstats","r"))==NULL) {
+ if ((fp=fopen("data/chanstats","r"))==NULL) {
Error("chanstats",ERR_ERROR,"Unable to load channel stats file");
return;
}
}
}
}
+
+int dochanstatssave(void *source, int cargc, char **cargv) {
+ nick *sender=(nick *)source;
+
+ controlreply(sender,"Saving Chanstats..");
+ savechanstats();
+ controlreply(sender,"Chanstats saved");
+ return CMD_OK;
+}
chanban *cbp;
char buf[BUFSIZE];
char buf2[12];
- int i,j;
+ int i,j, ops=0, voice=0;
char timebuf[30];
if (cargc<1)
controlreply((nick *)sender,"Topic : %s",cp->topic->content);
strftime(timebuf, 30, "%d/%m/%y %H:%M", localtime(&(cp->topictime)));
controlreply((nick *)sender,"T-time : %ld [%s]",cp->topictime,timebuf);
+ } else {
+ controlreply((nick *)sender,"Topic : (none)");
}
controlreply((nick *)sender,"Mode(s) : %s %s%s%s",printflags(cp->flags,cmodeflags),IsLimit(cp)?buf2:"",
IsLimit(cp)?" ":"",IsKey(cp)?cp->key->content:"");
break;
}
if (cp->users->content[j]!=nouser) {
+ if (cp->users->content[j]&CUMODE_OP)
+ ops++;
+ else if (cp->users->content[j]&CUMODE_VOICE)
+ voice++;
np=getnickbynumeric(cp->users->content[j]);
sprintf(&buf[i*18],"%c%c%-15s ",cp->users->content[j]&CUMODE_VOICE?'+':' ',
cp->users->content[j]&CUMODE_OP?'@':' ', np?np->nick:"!BUG-NONICK!");
buf[i*18]=' ';
}
}
-
+ controlreply((nick *)sender, "Users : Opped: %d, Voiced: %d", ops,voice);
for (cbp=cp->bans;cbp;cbp=cbp->next) {
controlreply((nick *)sender,"Ban : %s",bantostringdebug(cbp));
}
pool(NTERFACER),
pool(SQLITE),
pool(PQSQL),
+ pool(PATRICIA),
} endpools()
#undef pool
if (hcom == NULL)
{
+ controlwall(NO_DEVELOPER, NL_ALL_COMMANDS, "(G) From: %s!%s@%s%s%s: %s",
+ sender->real_user->nick, sender->real_user->ident,
+ sender->real_user->host->name->content, IsAccount(sender->real_user)?"/":"",
+ IsAccount(sender->real_user)?sender->real_user->authname:"", args);
if ((returntype == NULL) ||
(sender->account != NULL && !(sender->account->flags & H_NO_CMD_ERROR)))
helpmod_reply(sender, returntype, "Unknown command '%s', please see showcommands for a list of all commands available to you", parsed_args[0]);
#include "../lib/base64.h"
#include "../lib/splitline.h"
#include "../lib/version.h"
+#include "../lib/irc_string.h"
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAX_NUMERIC 999
void irc_connect(void *arg);
+void ircstats(int hooknum, void *arg);
CommandTree *servercommands;
Command *numericcommands[MAX_NUMERIC-MIN_NUMERIC];
registerserverhandler("SE",&handlesettime,1);
registerserverhandler("Z",&handlepingreply,1);
registerserverhandler("SERVER",&irc_handleserver,8);
+
+ registerhook(HOOK_CORE_STATSREQUEST,&ircstats);
}
void _fini() {
deregisterserverhandler("SE",&handlesettime);
deregisterserverhandler("Z",&handlepingreply);
deregisterserverhandler("SERVER",&irc_handleserver);
+
+ deregisterhook(HOOK_CORE_STATSREQUEST,&ircstats);
deleteschedule(NULL,&sendping,NULL);
deleteschedule(NULL,&irc_connect,NULL);
Error("irc",ERR_INFO,"Connecting to %s:%s",conto->content,conport->content);
irc_send("PASS :%s",conpass->content);
- irc_send("SERVER %s 1 %ld %ld J10 %s%s +sh :%s",myserver->content,starttime,time(NULL),mynumeric->content,longtonumeric(MAXLOCALUSER,3),mydesc->content);
+ irc_send("SERVER %s 1 %ld %ld J10 %s%s +sh6 :%s",myserver->content,starttime,time(NULL),mynumeric->content,longtonumeric(MAXLOCALUSER,3),mydesc->content);
registerhandler(serverfd, POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL, &handledata);
awaitingping=0;
return CMD_OK;
}
+
+
+void ircstats(int hooknum, void *arg) {
+ long level=(long)arg;
+ char buf[100];
+
+ if (level>5) {
+ sprintf(buf,"irc : start time %lu (running %s)", starttime,longtoduration(time(NULL)-starttime,0));
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+ sprintf(buf,"Time : %lu (current time is %lu, offset %ld)",getnettime(),time(NULL),timeoffset);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+ }
+}
@include@ @includel@../build.mk@includel@
.PHONY: all
-all: sstring.o array.o splitline.o base64.o flags.o irc_string.o strlfunc.o sha1.o irc_ipv6.o patricia.o rijndael.o sha2.o hmac.o prng.o md5.o stringbuf.o
+all: sstring.o array.o splitline.o base64.o flags.o irc_string.o strlfunc.o sha1.o irc_ipv6.o rijndael.o sha2.o hmac.o prng.o md5.o stringbuf.o
#include <arpa/inet.h>
#include <netdb.h>
#include "irc_ipv6.h"
+#include <stdio.h>
#warning This source file is probably GPLed, it needs relicensing.
-/*
- * this new faster inet_ntoa was ripped from:
- * From: Thomas Helvey <tomh@inxpress.net>
- */
-/** Array of text strings for dotted quads. */
-static const char* IpQuadTab[] =
-{
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
- "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
- "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
- "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
- "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
- "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
- "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
- "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
- "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
- "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
- "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
- "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
- "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
- "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
- "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
- "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
- "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
- "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
- "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
- "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
- "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
- "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
- "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
- "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
- "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
- "250", "251", "252", "253", "254", "255"
-};
-
/** Convert an IP address to printable ASCII form.
* This is generally deprecated in favor of ircd_ntoa_r().
* @param[in] in Address to convert.
assert(in != NULL);
if (irc_in_addr_is_ipv4(in)) {
- unsigned int pos, len;
unsigned char *pch;
pch = (unsigned char*)&in->in6_16[6];
- len = strlen(IpQuadTab[*pch]);
- memcpy(buf, IpQuadTab[*pch++], len);
- pos = len;
- buf[pos++] = '.';
- len = strlen(IpQuadTab[*pch]);
- memcpy(buf+pos, IpQuadTab[*pch++], len);
- pos += len;
- buf[pos++] = '.';
- len = strlen(IpQuadTab[*pch]);
- memcpy(buf+pos, IpQuadTab[*pch++], len);
- pos += len;
- buf[pos++] = '.';
- len = strlen(IpQuadTab[*pch]);
- memcpy(buf+pos, IpQuadTab[*pch++], len);
- buf[pos + len] = '\0';
+ sprintf(buf,"%d.%d.%d.%d",pch[0],pch[1],pch[2],pch[3]);
return buf;
} else {
- static const char hexdigits[] = "0123456789abcdef";
unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
/* Find longest run of zeros. */
continue;
}
part = ntohs(in->in6_16[ii]);
- if (part >= 0x1000)
- APPEND(hexdigits[part >> 12]);
- if (part >= 0x100)
- APPEND(hexdigits[(part >> 8) & 15]);
- if (part >= 0x10)
- APPEND(hexdigits[(part >> 4) & 15]);
- APPEND(hexdigits[part & 15]);
+ pos+=sprintf(buf+pos,"%x",part);
if (ii < 7)
APPEND(':');
}
unsigned short port; /**< Port number, host-endian. */
};
+#define irc_bitlen(ADDR, BITS) (irc_in_addr_is_ipv4(ADDR) ? (BITS) - 96 : (BITS))
+
/** Evaluate to non-zero if \a ADDR is a valid address (not all 0s and not all 1s). */
#define irc_in_addr_valid(ADDR) (((ADDR)->in6_16[0] && ~(ADDR)->in6_16[0]) \
|| (ADDR)->in6_16[1] != (ADDR)->in6_16[0] \
((unsigned char *)(ipaddress.in6_16))[15] = (currentlocalunum%253)+1;
newuser->ipnode = refnode(iptree, &ipaddress, PATRICIA_MAXBITS);
- newuser->ipnode->usercount++;
+ node_increment_usercount(newuser->ipnode);
newuser->timestamp=getnettime();
newuser->shident=NULL;
nick **servernicks[MAXSERVERS];
sstring *nickextnames[MAXNICKEXTS];
-sstring *nodeextnames[PATRICIA_MAXSLOTS];
-patricia_tree_t *iptree;
void nickstats(int hooknum, void *arg);
/* Fake the addition of our own server */
handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
-
- iptree = patricia_new_tree(PATRICIA_MAXBITS);
}
void _fini() {
freesstring(np->shident); /* freesstring(NULL) is OK */
freesstring(np->sethost);
- np->ipnode->usercount--;
+ node_decrement_usercount(np->ipnode);
derefnode(iptree, np->ipnode);
/* TODO: figure out how to cleanly remove nodes without affecting other modules */
#endif
-int registernodeext(const char *name) {
- int i;
-
- if (findnodeext(name)!=-1) {
- Error("nick",ERR_WARNING,"Tried to register duplicate node extension %s",name);
- return -1;
- }
-
- for (i=0;i<PATRICIA_MAXSLOTS;i++) {
- if (nodeextnames[i]==NULL) {
- nodeextnames[i]=getsstring(name,100);
- return i;
- }
- }
-
- Error("nick",ERR_WARNING,"Tried to register too many extensions: %s",name);
- return -1;
-}
-
-int findnodeext(const char *name) {
- int i;
-
- for (i=0;i<PATRICIA_MAXSLOTS;i++) {
- if (nodeextnames[i]!=NULL && !ircd_strcmp(name,nodeextnames[i]->content)) {
- return i;
- }
- }
-
- return -1;
-}
-
-void releasenodeext(int index) {
- patricia_node_t *head, *node;
-
- freesstring(nodeextnames[index]);
- nodeextnames[index]=NULL;
-
- head = iptree->head;
-
- PATRICIA_WALK_ALL(head, node)
- {
- node->exts[index]=NULL;
- } PATRICIA_WALK_END;
-}
#include "../server/server.h"
#include "../lib/base64.h"
#include "../lib/irc_ipv6.h"
-#include "../lib/patricia.h"
+#include "../patricia/patricia.h"
#include "../authext/authext.h"
extern realname *realnametable[REALNAMEHASHSIZE];
extern const flag umodeflags[];
extern const flag accountflags[];
-extern patricia_tree_t *iptree;
#define MAXNUMERIC 0x3FFFFFFF
void releasenickext(int index);
char *visiblehostmask(nick *np, char *buf);
char *visibleuserhost(nick *np, char *buf);
-int registernodeext(const char *name);
-int findnodeext(const char *name);
-void releasenodeext(int index);
/* nickhandlers.c functions */
int handlenickmsg(void *source, int cargc, char **cargv);
base64toip(cargv[cargc-3], &ipaddress);
/* todo: use a single node for /64 prefixes */
np->ipnode = refnode(iptree, &ipaddress, irc_in_addr_is_ipv4(&ipaddress) ? PATRICIA_MAXBITS : 64);
- np->ipnode->usercount++;
+ node_increment_usercount(np->ipnode);
np->shident=NULL;
np->sethost=NULL;
LDFLAGS+=$(LIBDBAPI)
.PHONY: all
-all: noperserv.so noperserv_commands.so noperserv_fakeuser.so
+all: noperserv.so noperserv_commands.so noperserv_raw.so noperserv_fakeuser.so
noperserv.so: noperserv.o noperserv_db.o noperserv_hooks.o noperserv_policy.o
noperserv_commands.so: noperserv_commands.o
+noperserv_raw.so: noperserv_raw.o
+
noperserv_fakeuser.so: noperserv_fakeuser.o
registercontrolhelpcmd("spewchan", NO_OPER, 1, &controlspewchan, "Usage: spewchan <pattern>\nShows all channels which are matched by the given pattern");
- registercontrolhelpcmd("spew", NO_OPER, 1, &controlspew, "Usage: spewchan <pattern>\nShows all userss which are matched by the given pattern");
+ registercontrolhelpcmd("spew", NO_OPER, 1, &controlspew, "Usage: spew <pattern>\nShows all userss which are matched by the given pattern");
- registercontrolhelpcmd("resync", NO_OPER, 1, &controlresync, "Usage: resync <channel>\nResyncs a desynched channel");
+ /* doesnt seem to work for me + pointless command?(paul)
+ registercontrolhelpcmd("resync", NO_OPER, 1, &controlresync, "Usage: resync <channel>\nResyncs a desynched channel"); */
registercontrolhelpcmd("broadcast", NO_OPER, 1, &controlbroadcast, "Usage: broadcast <text>\nSends a message to all users.");
registercontrolhelpcmd("obroadcast", NO_OPER, 1, &controlobroadcast, "Usage: obroadcast <text>\nSends a message to all IRC operators.");
deregistercontrolcmd("mbroadcast", controlmbroadcast);
deregistercontrolcmd("broadcast", controlbroadcast);
- deregistercontrolcmd("resync", controlresync);
+ /* deregistercontrolcmd("resync", controlresync); */
deregistercontrolcmd("spew", controlspew);
deregistercontrolcmd("spewchan", controlspewchan);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+
+#include "../control/control.h"
+#include "../nick/nick.h"
+#include "../lib/irc_string.h"
+#include "../lib/strlfunc.h"
+#include "../localuser/localuserchannel.h"
+#include "../lib/version.h"
+#include "../core/modules.h"
+
+MODULE_VERSION("");
+
+int controlraw(void *sender, int cargc, char **cargv);
+
+void _init() {
+ registercontrolhelpcmd("raw", NO_OPER, 2, &controlraw, "Usage: raw <type> <text>\ntype is one of client,server,raw\nUSE THIS COMMAND WITH CAUTION, YOU WILL MOST LIKELY CORRUPT NEWSERV STATE.");
+}
+
+void _fini() {
+ deregistercontrolcmd("raw", controlraw);
+}
+
+int controlraw(void *sender, int cargc, char **cargv) {
+ nick *np=(nick *)sender;
+ if (cargc<2)
+ return CMD_USAGE;
+
+ controlreply(sender, "Sending Raw.. %s", cargv[1]);
+ if (strcmp(cargv[0], "server") == 0) {
+ irc_send("%s %s",mynumeric->content,cargv[1]);
+ controlwall(NO_DEVELOPER, NL_OPERATIONS, "%s/%s sent SERVER RAW for %s", np->nick, np->authname, cargv[1]);
+ } else if (strcmp( cargv[0], "client") == 0) {
+ controlwall(NO_DEVELOPER, NL_OPERATIONS, "%s/%s sent CLIENT RAW for %s", np->nick, np->authname, cargv[1]);
+ irc_send("%s %s",longtonumeric(mynick->numeric,5),cargv[1]);
+ } else if (strcmp( cargv[0], "raw") == 0) {
+ controlwall(NO_DEVELOPER, NL_OPERATIONS, "%s/%s sent RAW for %s", np->nick, np->authname, cargv[1]);
+ irc_send("%s", cargv[1]);
+ } else {
+ controlreply(sender, "Invalid Mode - server or client");
+ return CMD_ERROR;
+ }
+
+ controlreply(sender, "RAW sent.");
+
+ return CMD_OK;
+}
--- /dev/null
+@include@ @includel@../build.mk@includel@
+
+.PHONY: all
+all: patricia.so
+
+patricia.so: patricia.o patricia_alloc.o patricialib.o
--- /dev/null
+#include "../core/nsmalloc.h"
+#include "../lib/irc_string.h"
+#include "../lib/version.h"
+#include "patricia.h"
+#include "../core/error.h"
+#include "../core/hooks.h"
+#include "../control/control.h"
+
+#include <assert.h> /* assert */
+#include <stdio.h>
+#include <string.h>
+
+MODULE_VERSION("");
+
+patricia_tree_t *iptree;
+sstring *nodeextnames[PATRICIA_MAXSLOTS];
+
+void patriciastats(int hooknum, void *arg);
+
+void _init(void) {
+ iptree = patricia_new_tree(PATRICIA_MAXBITS);
+ assert(iptree);
+
+ registerhook(HOOK_CORE_STATSREQUEST,&patriciastats);
+}
+
+void _fini(void) {
+ deregisterhook(HOOK_CORE_STATSREQUEST,&patriciastats);
+ patricia_destroy_tree (iptree, NULL);
+ nsfreeall(POOL_PATRICIA);
+}
+
+void patriciastats(int hooknum, void *arg) {
+ long level=(long)arg;
+ char buf[100];
+ patricia_node_t *head, *node;
+ int i,j,k,l;
+
+ if (level <= 5)
+ return;
+
+ sprintf(buf, "Patricia: %6d Active Nodes (%d bits)", iptree->num_active_node, iptree->maxbits);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+
+ head = iptree->head;
+
+ i=0;j=0;
+ PATRICIA_WALK_ALL(head, node) {
+ if ( node->prefix )
+ j++;
+ else
+ i++;
+ } PATRICIA_WALK_END;
+ sprintf(buf, "Patricia: %6d Nodes, %6d Prefix (walk all)", i,j);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+
+ head = iptree->head;
+ i=0;j=0;k=0;l=0;
+ PATRICIA_WALK(head, node) {
+ if ( node->prefix ) {
+ if (irc_in_addr_is_ipv4(&(node->prefix->sin)))
+ k++;
+ else
+ l++;
+ j++;
+ } else
+ i++;
+ } PATRICIA_WALK_END;
+ sprintf(buf, "Patricia: %6d Nodes, %6d Prefix (walk prefixes only)", i,j);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+ sprintf(buf, "Patricia: %6d IP4Node, %6d IP6Node", k, l);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+
+ j=0;
+ for (i=0;i<PATRICIA_MAXSLOTS;i++) {
+ if (nodeextnames[i]!=NULL) {
+ j++;
+ }
+ }
+ sprintf(buf, "Patricia: %6d ExtsUsed, %5d Max", j,PATRICIA_MAXSLOTS);
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+
+}
+
+int registernodeext(const char *name) {
+ int i;
+
+ if (findnodeext(name)!=-1) {
+ Error("patricia",ERR_WARNING,"Tried to register duplicate node extension %s",name);
+ return -1;
+ }
+
+ for (i=0;i<PATRICIA_MAXSLOTS;i++) {
+ if (nodeextnames[i]==NULL) {
+ nodeextnames[i]=getsstring(name,100);
+ return i;
+ }
+ }
+
+ Error("patricia",ERR_WARNING,"Tried to register too many extensions: %s",name);
+ return -1;
+}
+
+int findnodeext(const char *name) {
+ int i;
+
+ for (i=0;i<PATRICIA_MAXSLOTS;i++) {
+ if (nodeextnames[i]!=NULL && !ircd_strcmp(name,nodeextnames[i]->content)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void releasenodeext(int index) {
+ patricia_node_t *head, *node;
+
+ freesstring(nodeextnames[index]);
+ nodeextnames[index]=NULL;
+
+ head = iptree->head;
+
+ PATRICIA_WALK_ALL(head, node)
+ {
+ node->exts[index]=NULL;
+ } PATRICIA_WALK_END;
+}
+
#ifndef _PATRICIA_H
#define _PATRICIA_H
-#include "irc_ipv6.h"
+#include "../lib/irc_ipv6.h"
typedef unsigned short u_short;
typedef unsigned int u_int;
/* { from defs.h */
#define prefix_touchar(prefix) ((u_char *)&(prefix)->sin)
#define MAXLINE 1024
-#define BIT_TEST(f, b) ((f) & (b))
/* } */
#include <sys/types.h> /* for u_* definitions (on FreeBSD 5) */
#define PATRICIA_MAXSLOTS 5
+
typedef struct _prefix_t {
u_short bitlen; /* same as mask? */
int ref_count; /* reference count */
struct irc_in_addr sin;
} prefix_t;
+union prefixes {
+ struct _prefix_t prefix;
+ union prefixes *next;
+};
+
/* } */
typedef struct _patricia_node_t {
int num_active_node; /* for debug purpose */
} patricia_tree_t;
+extern patricia_tree_t *iptree;
prefix_t *patricia_new_prefix (struct irc_in_addr *dest, int bitlen);
prefix_t * patricia_ref_prefix (prefix_t * prefix);
void patricia_destroy_tree (patricia_tree_t *patricia, void_fn_t func);
void patricia_process (patricia_tree_t *patricia, void_fn_t func);
+patricia_node_t *patricia_new_node(patricia_tree_t *patricia, unsigned char bit,prefix_t *prefix);
+
+int registernodeext(const char *name);
+int findnodeext(const char *name);
+void releasenodeext(int index);
+
+void node_increment_usercount( patricia_node_t *node);
+void node_decrement_usercount( patricia_node_t *node);
+
+/* alloc */
+void freeprefix (prefix_t *prefix);
+prefix_t *newprefix();
+patricia_node_t *newnode();
+void freenode (patricia_node_t *node);
+
/* } */
patricia_node_t *refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen);
void derefnode(patricia_tree_t *tree, patricia_node_t *node);
-#define PATRICIA_MAXBITS 128
-#define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
-#define PATRICIA_NBYTE(x) ((x) >> 3)
+#define get_byte_for_bit(base, nr) (base)[(nr) >> 3]
+#define bigendian_bitfor(nr) (0x80 >> ((nr) & 0x07))
+#define is_bit_set(base, nr) (get_byte_for_bit(base, nr) & bigendian_bitfor(nr))
-/*#define PATRICIA_DATA_GET(node, type) (type *)((node)->data)
-#define PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))*/
+#define PATRICIA_MAXBITS 128
#define PATRICIA_WALK(Xhead, Xnode) \
do { \
--- /dev/null
+
+#include <stdlib.h>
+#include "patricia.h"
+#include <assert.h>
+#include "../core/nsmalloc.h"
+
+#define ALLOCUNIT 100
+
+patricia_node_t *node_freelist;
+union prefixes *prefix_freelist;
+
+prefix_t *newprefix() {
+ union prefixes *prefixes = prefix_freelist;
+ int i;
+
+ if (prefixes==NULL) {
+ prefixes=(union prefixes *)nsmalloc(POOL_PATRICIA,ALLOCUNIT*sizeof(prefix_t));
+
+ for (i=0;i<(ALLOCUNIT-1);i++) {
+ prefixes[i].next=&(prefixes[i+1]);
+ }
+ prefixes[ALLOCUNIT-1].next=NULL;
+ }
+
+ prefix_freelist = prefixes->next;
+ return &(prefixes->prefix);
+
+}
+
+void freeprefix (prefix_t *prefix) {
+ union prefixes *ups = (union prefixes *)prefix;
+ ups->next = prefix_freelist;
+ prefix_freelist = ups;
+}
+
+
+patricia_node_t *newnode() {
+ int i;
+ patricia_node_t *node;
+
+ if( node_freelist==NULL ) {
+ node_freelist=(patricia_node_t *)nsmalloc(POOL_PATRICIA,ALLOCUNIT*sizeof(patricia_node_t));
+
+ for (i=0;i<(ALLOCUNIT-1);i++) {
+ node_freelist[i].parent=(patricia_node_t *)&(node_freelist[i+1]);
+ }
+ node_freelist[ALLOCUNIT-1].parent=NULL;
+ }
+
+ node=node_freelist;
+ node_freelist=(patricia_node_t *)node->parent;
+
+ return node;
+}
+
+void freenode (patricia_node_t *node) {
+ node->parent=(patricia_node_t *)node_freelist;
+ node_freelist=node;
+}
+
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+
+#include "../nick/nick.h"
+#include "../localuser/localuserchannel.h"
+#include "../core/hooks.h"
+#include "../core/schedule.h"
+#include "../lib/array.h"
+#include "../lib/base64.h"
+#include "../lib/irc_string.h"
+#include "../lib/splitline.h"
+#include "../control/control.h"
+
+FILE* dumpip_logfp;
+int nc_cmd_dumptree(void *source, int cargc, char **cargv);
+int nc_cmd_nodecount(void *source, int cargc, char **cargv);
+
+void _init() {
+ if (!(dumpip_logfp = fopen("log/iplist", "w")))
+ Error("dumpip", ERR_ERROR, "Failed to open log file!");
+ registercontrolcmd("dumptree", 10, 2, &nc_cmd_dumptree);
+ registercontrolcmd("nodecount", 10, 1, &nc_cmd_nodecount);
+}
+
+void _fini() {
+ if (dumpip_logfp)
+ fclose(dumpip_logfp);
+ deregistercontrolcmd("dumptree", &nc_cmd_dumptree);
+ deregistercontrolcmd("nodecount", &nc_cmd_nodecount);
+}
+
+int nc_cmd_dumptree(void *source, int cargc, char **cargv) {
+ nick *np=(nick *)source;
+ struct irc_in_addr sin;
+ unsigned char bits;
+ patricia_node_t *head, *node;
+ unsigned int level=0;
+ int i = 0;
+
+ if (cargc < 1) {
+ controlreply(np, "Syntax: dumptree <ipv4|ipv6|cidr4|cidr6>");
+ return CMD_OK;
+ }
+
+ if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
+ controlreply(np, "Invalid mask.");
+ return CMD_OK;
+ }
+
+ if (cargc>1) {
+ level=strtoul(cargv[1],NULL,10);
+ }
+
+ head = refnode(iptree, &sin, bits);
+
+ if (level < 10) {
+ PATRICIA_WALK(head, node)
+ {
+ switch (level) {
+ case 0:
+ controlreply(np,"%p: %s", node, IPtostr(node->prefix->sin));
+ break;
+ case 1:
+ controlreply(np,"%p: prefix %p, bit %d, ref_count %d, IP: %s",node, node->prefix,
+ node->prefix->bitlen, node->prefix->ref_count, IPtostr(node->prefix->sin));
+ break;
+ case 2:
+ controlreply(np,"%p: bit: %d, usercount: %d, IP: %s", node, node->bit, node->usercount, IPtostr(node->prefix->sin));
+ break;
+ case 3:
+ controlreply(np,"%p: L: %p, R: %p P: %p", node, node->l, node->r, node->parent);
+ break;
+ case 4:
+ controlreply(np,"%p: 0: %p, 1: %p, 2: %p, 3: %p, 4: %p", node,
+ node->exts[0], node->exts[1], node->exts[2], node->exts[3], node->exts[4]);
+ break;
+ default:
+ if( i == 0 ) controlreply(np,"Invalid Level");
+ }
+ if ( i++ > 500) {
+ controlreply(np,"too many... aborting...");
+ break;
+ }
+ }
+ PATRICIA_WALK_END;
+ } else {
+ PATRICIA_WALK_ALL(head, node)
+ {
+ switch (level) {
+ case 10:
+ controlreply(np,"%p: prefix: %p %s", node, node->prefix, node->prefix?IPtostr(node->prefix->sin):"");
+ break;
+ case 11:
+ if(node->prefix)
+ controlreply(np,"%p: prefix bit: %d, ref_count %d, IP: %s",node,
+ node->prefix->bitlen, node->prefix->ref_count, IPtostr(node->prefix->sin));
+ else
+ controlreply(np,"%p: --", node);
+ break;
+ case 12:
+ controlreply(np,"%p: bit: %d, usercount: %d, IP: %s", node, node->bit, node->usercount, node->prefix?IPtostr(node->prefix->sin):"");
+ break;
+ case 13:
+ controlreply(np,"%p: L: %p, R: %p P: %p", node, node->l, node->r, node->parent);
+ break;
+ case 14:
+ controlreply(np,"%p%s 0: %p, 1: %p, 2: %p, 3: %p, 4: %p", node, node->prefix?"-":":",
+ node->exts[0], node->exts[1], node->exts[2], node->exts[3], node->exts[4]);
+ break;
+ default:
+ if ( i == 0 ) controlreply(np,"Invalid Level");
+ }
+ if ( i++ > 500) {
+ controlreply(np,"too many... aborting...");
+ break;
+ }
+ }
+ PATRICIA_WALK_END;
+ }
+ derefnode(iptree, head);
+ return CMD_OK;
+}
+
+int nc_cmd_nodecount(void *source, int cargc, char **cargv) {
+ nick *np = (nick *)source;
+ struct irc_in_addr sin;
+ unsigned char bits;
+ patricia_node_t *head, *node;
+ int count;
+
+ if (cargc < 1) {
+ controlreply(np, "Syntax: nodecount <ipv4|ipv6|cidr4|cidr6>");
+ return CMD_OK;
+ }
+
+ if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
+ controlreply(np, "Invalid mask.");
+
+ return CMD_OK;
+ }
+
+ head = refnode(iptree, &sin, bits);
+
+ count = head->usercount;
+
+ derefnode(iptree, head);
+
+ controlreply(np, "%d user(s) found.", count);
+
+ return CMD_OK;
+}
+
#include "patricia.h"
-/* { from prefix.c */
-
/* prefix_tochar
* convert prefix information to bytes
*/
return (0);
}
+
prefix_t *
patricia_new_prefix (struct irc_in_addr *dest, int bitlen)
{
- prefix_t *prefix = NULL;
+ prefix_t *prefix = newprefix();
+ assert (0 != prefix);
- prefix = malloc(sizeof (prefix_t));
memcpy (&prefix->sin, dest, 16);
-
prefix->bitlen = (bitlen >= 0)? bitlen: 128;
prefix->ref_count = 1;
+
return prefix;
}
return (patricia_new_prefix (&prefix->sin, prefix->bitlen));
}
prefix->ref_count++;
-/* fprintf(stderr, "[A %s, %d]\n", prefix_toa (prefix), prefix->ref_count); */
return (prefix);
}
assert (prefix->ref_count > 0);
prefix->ref_count--;
- assert (prefix->ref_count >= 0);
if (prefix->ref_count <= 0) {
- free(prefix);
+ freeprefix(prefix);
return;
}
}
-/* } */
-
-/* #define PATRICIA_DEBUG 1 */
-
/* these routines support continuous mask only */
patricia_tree_t *
func(Xrn->exts);
patricia_deref_prefix (Xrn->prefix);
}
- free(Xrn);
+ freenode(Xrn);
patricia->num_active_node--;
if (l) {
}
}
assert (patricia->num_active_node == 0);
- /* free(patricia); */
}
-
void
patricia_destroy_tree (patricia_tree_t *patricia, void_fn_t func)
{
patricia_clear_tree (patricia, func);
free(patricia);
+ /*TODO: EXTENSIONS!*/
}
addr = (u_char *)sin;
while (node->bit < bitlen) {
- if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ if (is_bit_set(addr,node->bit))
node = node->r;
else
node = node->l;
return (NULL);
assert (node->bit == bitlen);
assert (node->bit == node->prefix->bitlen);
- if (comp_with_mask (prefix_tochar (node->prefix), addr, bitlen)) {
+ if (comp_with_mask (prefix_tochar (node->prefix), addr, bitlen)) {
return (node);
}
return (NULL);
stack[cnt++] = node;
}
- if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
+ if (is_bit_set(addr,node->bit)) {
node = node->r;
}
else {
/* if new trie, create the first node */
if (patricia->head == NULL) {
- node = malloc(sizeof *node);
- memset(node->exts, 0, PATRICIA_MAXSLOTS * sizeof(void *));
- node->bit = prefix->bitlen;
- node->prefix = patricia_ref_prefix (prefix);
- node->parent = NULL;
- node->l = node->r = NULL;
- node->usercount = 0;
+ node = patricia_new_node(patricia, prefix->bitlen, patricia_ref_prefix (prefix));
patricia->head = node;
- patricia->num_active_node++;
return (node);
}
while (node->bit < bitlen || node->prefix == NULL) {
/* check that we're not at the lowest leaf i.e. node->bit is less than max bits */
if (node->bit < patricia->maxbits &&
- (addr[node->bit >> 3]) & (0x80 >> (node->bit & 0x07))) {
+ (is_bit_set(addr,node->bit))) {
if (node->r == NULL)
break;
node = node->r;
continue;
}
/* I know the better way, but for now */
- for (j = 0; j < 8; j++) {
+ for (j = 0; j < 8; j++) {
if ((r) & ((0x80 >> j)))
break;
}
}
if (differ_bit == bitlen && node->bit == bitlen) {
- if (node->prefix) {
- return (node);
- }
- node->prefix = patricia_ref_prefix (prefix);
+ if (!node->prefix) {
+ node->prefix = patricia_ref_prefix (prefix);
+ }
return (node);
}
- new_node = malloc(sizeof *new_node);
- memset(new_node->exts, 0, PATRICIA_MAXSLOTS * sizeof(void *));
- new_node->bit = prefix->bitlen;
- new_node->prefix = patricia_ref_prefix (prefix);
- new_node->parent = NULL;
- new_node->l = new_node->r = NULL;
- new_node->usercount = 0;
- patricia->num_active_node++;
-
+ new_node = patricia_new_node(patricia, prefix->bitlen, patricia_ref_prefix (prefix));
if (node->bit == differ_bit) {
new_node->parent = node;
if (node->bit < patricia->maxbits &&
- (addr[node->bit >> 3]) & (0x80 >> (node->bit & 0x07))) {
+ (is_bit_set(addr, node->bit))) {
assert (node->r == NULL);
node->r = new_node;
}
if (bitlen == differ_bit) {
if (bitlen < patricia->maxbits &&
- (test_addr[bitlen >> 3]) & (0x80 >> (bitlen & 0x07))) {
+ (is_bit_set(test_addr,bitlen))) {
new_node->r = node;
}
else {
node->parent->l = new_node;
}
node->parent = new_node;
+ new_node->usercount = node->usercount;
}
else {
- glue = malloc(sizeof *glue);
- memset(glue->exts, 0, PATRICIA_MAXSLOTS * sizeof(void *));
- glue->bit = differ_bit;
- glue->prefix = NULL;
+ glue = patricia_new_node(patricia, differ_bit, NULL);
glue->parent = node->parent;
- glue->usercount = 0;
- patricia->num_active_node++;
if (differ_bit < patricia->maxbits &&
- (addr[differ_bit >> 3]) & (0x80 >> (differ_bit & 0x07))) {
+ (is_bit_set(addr, differ_bit))) {
glue->r = new_node;
glue->l = node;
}
node->parent->l = glue;
}
node->parent = glue;
+ glue->usercount = node->usercount;
}
+
return (new_node);
}
if (node->r == NULL && node->l == NULL) {
parent = node->parent;
patricia_deref_prefix (node->prefix);
- free(node);
+ freenode(node);
patricia->num_active_node--;
if (parent == NULL) {
parent->parent->l = child;
}
child->parent = parent->parent;
- free(parent);
+ freenode(parent);
patricia->num_active_node--;
return;
}
child->parent = parent;
patricia_deref_prefix (node->prefix);
- free(node);
+ freenode(node);
patricia->num_active_node--;
if (parent == NULL) {
}
}
-/* } */
patricia_node_t *
refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) {
} else
patricia_deref_prefix(node->prefix);
}
+
+patricia_node_t *patricia_new_node(patricia_tree_t *patricia, unsigned char bit,prefix_t *prefix ) {
+ patricia_node_t *new_node = newnode();
+ memset(new_node->exts, 0, PATRICIA_MAXSLOTS * sizeof(void *));
+ new_node->bit = bit;
+ new_node->prefix = prefix;
+ new_node->usercount = 0;
+ new_node->parent = NULL;
+ new_node->l = new_node->r = NULL;
+ patricia->num_active_node++;
+ return new_node;
+}
+
+void node_increment_usercount( patricia_node_t *node) {
+ while(node) {
+ node->usercount++;
+ node=node->parent;
+ }
+}
+
+void node_decrement_usercount( patricia_node_t *node) {
+ while(node) {
+ node->usercount--;
+ node=node->parent;
+ }
+}
#define min(a,b) ((a > b) ? b : a)
-int lr_requestl(nick *svc, nick *np, channel *cp, nick *lnick) {
+int lr_requestl(nick *svc, nick *np, channel *cp, nick *qnick) {
chanfix *cf;
regop *rolist[LR_TOPX], *ro;
int i, rocount;
}
sendnoticetouser(svc, np, "Sorry You do not meet the "
- "requirements to request L. Please Try again in an hour. "
- "(see http://www.quakenet.org/faq/faq.php?c=3&f=112 )");
+ "requirements to request %s. Please Try again in an hour. "
+ "(see http://www.quakenet.org/faq/faq.php?c=1&f=239#239 )", RQ_QNICK);
lr_scoretoolow++;
return RQ_ERROR;
}
- sendmessagetouser(svc, lnick, "addchan %s #%s %s", cp->index->name->content,
+
+ sendmessagetouser(svc, qnick, "addchan %s #%s +jp upgrade %s", cp->index->name->content,
np->authname, np->nick);
- sendnoticetouser(svc, np, "Requirements met, L should be added. Contact #help"
- " should further assistance be required.");
+ sendnoticetouser(svc, np, "Requirements met, %s should be added. Contact #help"
+ " should further assistance be required.", RQ_QNICK);
return RQ_OK;
}
void lr_requeststats(nick *rqnick, nick *np) {
- sendnoticetouser(rqnick, np, "- No registered ops (L): %d", lr_noregops);
- sendnoticetouser(rqnick, np, "- Score too low (L): %d", lr_scoretoolow);
- sendnoticetouser(rqnick, np, "- Not in top%d (L): %d", LR_TOPX, lr_top5);
- sendnoticetouser(rqnick, np, "- Floods (L): %d", lr_floodattempts);
+ sendnoticetouser(rqnick, np, "- No registered ops (Q): %d", lr_noregops);
+ sendnoticetouser(rqnick, np, "- Score too low (Q): %d", lr_scoretoolow);
+ sendnoticetouser(rqnick, np, "- Not in top%d (Q): %d", LR_TOPX, lr_top5);
+ sendnoticetouser(rqnick, np, "- Floods (Q): %d", lr_floodattempts);
}
#define LR_TOPX 5
#define LR_CFSCORE 12
-#define LR_MAXCHANLEN 29
+#define LR_MAXCHANLEN 89
int lr_requestl(nick *svc, nick *np, channel *cp, nick *lnick);
void lr_requeststats(nick *rqnick, nick *np);
void rq_registeruser(void) {
channel *cp;
- rqnick = registerlocaluser(RQ_REQUEST_NICK, RQ_REQUEST_USER, RQ_REQUEST_HOST,
- RQ_REQUEST_REAL, RQ_REQUEST_AUTH,
+ rqnick = registerlocaluserwithuserid(RQ_REQUEST_NICK, RQ_REQUEST_USER, RQ_REQUEST_HOST,
+ RQ_REQUEST_REAL, RQ_REQUEST_AUTH, 1780711,
UMODE_ACCOUNT | UMODE_SERVICE | UMODE_OPER,
rq_handler);
return 0;
}
-int rq_genericrequestcheck(nick *np, char *channelname, channel **cp, nick **lnick, nick **qnick) {
+int rq_genericrequestcheck(nick *np, char *channelname, channel **cp, nick **qnick) {
unsigned long *userhand;
rq_block *block;
return RQ_ERROR;
}
- *lnick = getnickbynick(RQ_LNICK);
-
- if (*lnick == NULL || findserver(RQ_LSERVER) < 0) {
- sendnoticetouser(rqnick, np, "Error: %s does not seem to be online. "
- "Try again later.", RQ_LNICK);
-
- return RQ_ERROR;
- }
-
*qnick = getnickbynick(RQ_QNICK);
if (*qnick == NULL || findserver(RQ_QSERVER) < 0) {
int rqcmd_request(void *user, int cargc, char **cargv) {
nick *np = (nick*)user;
- nick *lnick, *qnick;
- unsigned long *lhand, *qhand;
+ nick *qnick;
+ unsigned long *qhand;
channel *cp;
int retval;
time_t now_ts;
rq_count++;
- if (rq_genericrequestcheck(np, cargv[0], &cp, &lnick, &qnick) == RQ_ERROR) {
+ if (rq_genericrequestcheck(np, cargv[0], &cp, &qnick) == RQ_ERROR) {
rq_failed++;
return RQ_ERROR;
}
- lhand = getnumerichandlefromchanhash(cp->users, lnick->numeric);
-
qhand = getnumerichandlefromchanhash(cp->users, qnick->numeric);
if (qhand != NULL) {
retval = RQ_ERROR;
- if (lhand == NULL && qhand == NULL) {
- /* try 'instant' Q request */
- retval = qr_instantrequestq(np, cp);
- }
-
- if (retval == RQ_ERROR) {
- if (lhand == NULL) {
- /* user 'wants' L */
-
- retval = lr_requestl(rqnick, np, cp, lnick);
+ retval = lr_requestl(rqnick, np, cp, qnick);
- if (rq_logfd != NULL) {
- now[0] = '\0';
- now_ts = time(NULL);
- strftime(now, sizeof(now), "%c", localtime(&now_ts));
+ if (rq_logfd != NULL) {
+ now[0] = '\0';
+ now_ts = time(NULL);
+ strftime(now, sizeof(now), "%c", localtime(&now_ts));
- fprintf(rq_logfd, "%s: request (%s) for %s from %s: Request was %s.\n", now, RQ_LNICK, cp->index->name->content, np->nick, (retval == RQ_OK) ? "accepted" : "denied");
- fflush(rq_logfd);
- }
- } else {
- /* user 'wants' Q */
-
- retval = qr_requestq(rqnick, np, cp, lnick, qnick);
- }
+ fprintf(rq_logfd, "%s: request (%s) for %s from %s: Request was %s.\n", now, RQ_QNICK, cp->index->name->content, np->nick, (retval == RQ_OK) ? "accepted" : "denied");
+ fflush(rq_logfd);
}
if (retval == RQ_ERROR)
int rqcmd_requestspamscan(void *user, int cargc, char **cargv) {
nick *np = (nick*)user;
channel *cp;
- nick *lnick, *qnick, *snick;
- unsigned long *lhand, *qhand, *shand;
+ nick *qnick, *snick;
+ unsigned long *qhand, *shand;
int retval;
if (cargc < 1) {
rq_count++;
- if (rq_genericrequestcheck(np, cargv[0], &cp, &lnick, &qnick) == RQ_ERROR) {
+ if (rq_genericrequestcheck(np, cargv[0], &cp, &qnick) == RQ_ERROR) {
rq_failed++;
return RQ_ERROR;
return RQ_ERROR;
}
- /* we need either L or Q */
- lhand = getnumerichandlefromchanhash(cp->users, lnick->numeric);
+ /* we need Q */
qhand = getnumerichandlefromchanhash(cp->users, qnick->numeric);
- if (lhand || qhand) {
+ if (qhand) {
/* great, now try to request */
- retval = qr_requests(rqnick, np, cp, lnick, qnick);
+ retval = qr_requests(rqnick, np, cp, qnick);
if (retval == RQ_OK)
rq_success++;
return retval;
} else {
- /* channel apparently doesn't have L or Q */
+ /* channel apparently doesn't have Q */
- sendnoticetouser(rqnick, np, "Error: You need %s or %s in order to be "
- "able to request %s.", RQ_LNICK, RQ_QNICK, RQ_SNICK);
+ sendnoticetouser(rqnick, np, "Error: You need %s in order to be "
+ "able to request %s.", RQ_QNICK, RQ_SNICK);
rq_failed++;
#define RQ_TLZ "#twilightzone"
-#define RQ_LSERVER "lightweight.quakenet.org"
-#define RQ_LNICK "L"
-
#define RQ_QSERVER "CServe.quakenet.org"
#define RQ_QNICK "Q"
-#define RQ_SSERVER "services.no.quakenet.org"
+#define RQ_SSERVER "services.de.quakenet.org"
#define RQ_SNICK "S"
#define RQ_REQUEST_NICK "R"
}
if (outcome==QR_OK) {
- if (req->what == QR_CSERVE) {
- /* Delete L, add Q. Check that they both exist first, though. */
-
- if (!(lnp=getnickbynick(RQ_LNICK)) || !(qnp=getnickbynick(RQ_QNICK))) {
- sendnoticetouser(rqnick, tnp,
- "Error: Cannot find %s and %s on the network. "
- "Please request again later.", RQ_LNICK, RQ_QNICK);
- free(req);
- return;
- }
-
- if ( !IsAccount(lnp) ) {
- sendnoticetouser(rqnick, tnp, "Internal Error Occured: L is not authed. Contact #help");
- free(req);
- return;
- }
-
- /* /msg Q ADDCHAN <channel> <flags> <owners nick> <channeltype> */
- sendmessagetouser(rqnick, qnp, "ADDCHAN %s +ap #%s upgrade",
- req->cip->name->content,
- np->authname);
-
- sendnoticetouser(rqnick, tnp, "Adding %s to channel, please wait...",
- RQ_QNICK);
- } else if (req->what == QR_SPAMSCAN) {
+ if (req->what == QR_SPAMSCAN) {
/* Add S */
if (!(snp=getnickbynick(RQ_SNICK))) {
int delrequest = 0, state, who;
requestrec *nextreq;
-/* logcp = findchannel("#qnet.request");
-
- if (logcp)
- sendmessagetochannel(rqnick, logcp, "%s: %s - %d %d %x %x", sender->nick, message, rlstate, rqstate, nextreql, nextreqq);
-*/
if (!ircd_strcmp(sender->nick, RQ_QNICK) && nextqreq) {
/* Message from Q */
if (!ircd_strcmp(message,"Done.")) {
/* Q added the channel: delete from L and tell the user. */
/* If L has conspired to vanish between the request and the outcome,
* we have a chan with Q and L... too bad. */
-
- if ((np=getnickbynick(RQ_LNICK))) {
- sendmessagetouser(rqnick, np, "SENDCHANLEV %s %s",
- nextqreq->cip->name->content, RQ_QNICK);
-
- sendmessagetouser(rqnick, np, "DELCHAN %s",
- nextqreq->cip->name->content);
- }
-
- if ((np=getnickbynumeric(nextqreq->reqnumeric))) {
- sendnoticetouser(rqnick, np, "Request completed. %s added.", RQ_QNICK);
- }
delrequest = 1;
} else if (!ircd_strcmp(message,"That channel already exists.")) {
- if ((np=getnickbynumeric(nextqreq->reqnumeric))) {
- sendnoticetouser(rqnick, np,
- "Your channel '%s' appears to have %s already "
- "(it may be suspended).", nextqreq->cip->name->content, RQ_QNICK);
-
- qr_suspended++;
delrequest = 1;
- }
}
/* For either of the two messages above we want to delete the request
}
}
- if (!ircd_strcmp(sender->nick, RQ_LNICK) || !ircd_strcmp(sender->nick, RQ_QNICK)) {
- who = !ircd_strcmp(sender->nick, RQ_LNICK) ? QR_L : QR_Q;
+ if (!ircd_strcmp(sender->nick, RQ_QNICK)) {
+ who = QR_Q;
state = (who == QR_Q) ? rqstate : rlstate;
nextreq = (who == QR_Q) ? nextreqq : nextreql;
(!ircd_strncmp(message,"Known users on",14) && who == QR_Q)
) {
/* Looks like the right message. Let's find a channel name */
-
for (ch=message;*ch;ch++)
if (*ch=='#')
break;
/* chop off any remaining words */
chop = ch;
while (*(chop++)) {
- if (*chop == ' ') {
+ if (*chop == ' ' || *chop == ':') {
*chop = '\0';
break;
}
}
-
if (!(cip=findchanindex(ch))) {
Error("qrequest",ERR_WARNING,
"Unable to find channel from L/Q message: %s",ch);
rlstate = QRLstate_AWAITINGUSER;
else
rqstate = QRLstate_AWAITINGUSER;
-
return;
} else {
/* Uh-oh, not the channel we wanted. Something is fucked
/* Oh dear, we got to the end of the chanlev in this state.
* This means that we didn't find the user.
*/
-
qr_result(nextreq, QR_FAILED, 'X',
"Error: You are not known on %s.",
nextreq->cip->name->content);
/* This is not the user you are looking for */
return;
}
-
/* Check for owner flag. Both branches of this if will
* take the request off the list, one way or the other. */
- if (strchr(ch, 'n')) {
+
+ /* chop off any remaining words */
+ chop = ch;
+ while (*(chop++)) {
+ if (*chop != ' ' ) {
+ break;
+ }
+ }
+ /* chop off any remaining words */
+ ch = chop;
+ while (*(chop++)) {
+ if (*chop == ' ' || *chop == ':') {
+ *chop = '\0';
+ break;
+ }
+ }
+
+ if (strchr(ch, 'n')) {
char failcode;
/* They iz teh +n! */
-
/* Note: We're checking for blocks kind of late, so the request
system gets a chance to send other error messages first (like
'no chanstats', 'not known on channel', etc.). This is required
if (qr_checksize(nextreq->cip, nextreq->what, &failcode) && !qr_blockcheck(nextreq)) {
qr_result(nextreq, QR_OK, '-', "OK");
} else {
- if (nextreq->what == QR_CSERVE) {
- qr_result(nextreq, QR_FAILED, failcode,
- "Error: Sorry, Your channel '%s' does not meet the requirements "
- "for %s. Please continue to use %s.", nextreq->cip->name->content, RQ_QNICK, RQ_LNICK);
- } else {
qr_result(nextreq, QR_FAILED, failcode,
"Error: Sorry, Your channel '%s' does not require %s. Please try again in a few days.", nextreq->cip->name->content, RQ_SNICK);
- }
-
+
qr_toosmall++;
}
} else {
*/
int qr_requestq(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick) {
- chanindex *cip = cp->index;
-
- /* Check:
- * - we have some form of channel stats for the channel
- *
- * Note that the actual channel stats will not be checked
- * until we're sure the user has +n on the channel.
- */
-
- if (rq_isspam(sender)) {
- sendnoticetouser(rqnick, sender, "Error: Do not flood the request system."
- " Try again in %s.", rq_longtoduration(rq_blocktime(sender)));
-
- return RQ_ERROR;
- }
-
- if (!cip->exts[csext]) {
- sendnoticetouser(rqnick, sender,
- "Error: No historical record exists for %s.",
- cip->name->content);
-
- qr_nohist++;
-
- return RQ_ERROR;
- }
-
- /* Request stats from L */
- sendmessagetouser(rqnick, lnick, "CHANLEV %s", cip->name->content);
-
- /* Sort out a request record */
- if (lastreql) {
- lastreql->next = (requestrec *)malloc(sizeof(requestrec));
- lastreql=lastreql->next;
- } else {
- lastreql=nextreql=(requestrec *)malloc(sizeof(requestrec));
- }
-
- lastreql->next = NULL;
- lastreql->cip = cip;
- lastreql->what = QR_CSERVE;
- lastreql->who = QR_L;
- lastreql->reqnumeric = sender->numeric;
-
- if (rlstate == QRLstate_IDLE)
- rlstate = QRLstate_AWAITINGCHAN;
-
- sendnoticetouser(rqnick, sender,
- "Checking your %s access. "
- "This may take a while, please be patient...", RQ_LNICK);
-
- /* we don't know yet whether the request was successful */
return RQ_UNKNOWN;
}
return RQ_OK;
}
-int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick) {
+int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *qnick) {
chanindex *cip = cp->index;
int who = 0;
requestrec *nextreq, *lastreq;
}
/* check which service is on the channel */
- if (getnumerichandlefromchanhash(cp->users, lnick->numeric) != NULL) {
- /* we've found L */
- who = QR_L;
-
- /* Request stats from L */
- sendmessagetouser(rqnick, lnick, "CHANLEV %s", cip->name->content);
-
- if (rlstate == QRLstate_IDLE)
- rlstate = QRLstate_AWAITINGCHAN;
- } else if (getnumerichandlefromchanhash(cp->users, qnick->numeric) != NULL) {
+ if (getnumerichandlefromchanhash(cp->users, qnick->numeric) != NULL) {
/* we've found Q */
who = QR_Q;
rqstate = QRLstate_AWAITINGCHAN;
} /* 'else' cannot happen as R has already checked whether the user has L or Q */
- lastreq = (who == QR_Q) ? lastreqq : lastreql;
- nextreq = (who == QR_Q) ? nextreqq : nextreql;
+ lastreq = lastreqq;
+ nextreq = nextreqq;
/* Sort out a request record */
if (lastreq) {
lastreq->what = QR_SPAMSCAN;
lastreq->reqnumeric = sender->numeric;
- if (who == QR_Q) {
- nextreqq = nextreq;
- lastreqq = lastreq;
- } else {
- nextreql = nextreq;
- lastreql = lastreq;
- }
+ nextreqq = nextreq;
+ lastreqq = lastreq;
- sendnoticetouser(rqnick, sender,
+ sendnoticetouser(rqnick, sender,
"Checking your %s access. "
"This may take a while, please be patient...",
- who == QR_Q ? RQ_QNICK : RQ_LNICK);
+ RQ_QNICK);
return RQ_UNKNOWN;
}
}
void qr_requeststats(nick *rqnick, nick *np) {
- sendnoticetouser(rqnick, np, "- Suspended (Q): %d", qr_suspended);
- sendnoticetouser(rqnick, np, "- No chanstats (Q/S): %d", qr_nohist);
- sendnoticetouser(rqnick, np, "- Too small (Q/S): %d", qr_toosmall);
- sendnoticetouser(rqnick, np, "- User was not on chanlev (Q/S): %d", qr_nochanlev);
- sendnoticetouser(rqnick, np, "- User was not the owner (Q/S): %d", qr_notowner);
+ sendnoticetouser(rqnick, np, "- Suspended (S): %d", qr_suspended);
+ sendnoticetouser(rqnick, np, "- No chanstats (S): %d", qr_nohist);
+ sendnoticetouser(rqnick, np, "- Too small (S): %d", qr_toosmall);
+ sendnoticetouser(rqnick, np, "- User was not on chanlev (S): %d", qr_nochanlev);
+ sendnoticetouser(rqnick, np, "- User was not the owner (S): %d", qr_notowner);
sendnoticetouser(rqnick, np, "- A: %d", qr_a);
sendnoticetouser(rqnick, np, "- B: %d", qr_b);
sendnoticetouser(rqnick, np, "- C: %d", qr_c);
#include "../channel/channel.h"
#define QR_REQUIREDSIZE_CSERVE 15
-#define QR_REQUIREDSIZE_SPAMSCAN 120
+#define QR_REQUIREDSIZE_SPAMSCAN 75
#define QR_TOPX 5
#define QR_AUTHEDPCT_SPAMSCANMIN 25
#define QR_AUTHEDPCT_SCALE 35
void qr_finirequest(void);
int qr_requestq(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick);
int qr_instantrequestq(nick *sender, channel *cp);
-int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick);
+int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *qnick);
void qr_requeststats(nick *rqnick, nick *np);
void qr_handle_notice(nick *sender, char *message);
#include <string.h>
#include "../irc/irc.h"
#include "../core/schedule.h"
+#include "../control/control.h"
schedule *settime_schedule;
+int settime_cmd(void *sender, int cargc, char **cargv);
void settime_sendsettime()
{
void _init()
{
settime_schedule = schedulerecurring(time(NULL) + 300, 0, 1800, &settime_sendsettime, NULL);
+ registercontrolhelpcmd("settime",NO_DEVELOPER,0,&settime_cmd,"Usage: settime\nForce send a settime to network.");
+
}
void _fini()
{
deleteschedule(settime_schedule, &settime_sendsettime, NULL);
+ deregistercontrolcmd("settime",&settime_cmd);
+}
+
+int settime_cmd(void *sender, int cargc, char **cargv) {
+ controlreply(sender,"Sending Settime...");
+ settime_sendsettime();
+ controlreply(sender,"Done");
+ return CMD_OK;
}