summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/InspIRCd.dev22
-rw-r--r--src/InspIRCd.layout102
-rw-r--r--src/commands.cpp29
-rw-r--r--src/inspircd.cpp323
-rw-r--r--src/users.cpp2
-rw-r--r--src/wildcard.cpp2
-rw-r--r--src/xline.cpp452
7 files changed, 731 insertions, 201 deletions
diff --git a/src/InspIRCd.dev b/src/InspIRCd.dev
index 5012e26ff..ae24fa043 100644
--- a/src/InspIRCd.dev
+++ b/src/InspIRCd.dev
@@ -1,7 +1,7 @@
[Project]
FileName=InspIRCd.dev
Name=InspIRCd - The Inspire Internet Relay Chat Daemon
-UnitCount=45
+UnitCount=47
Type=1
Ver=1
ObjFiles=
@@ -495,3 +495,23 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
+[Unit46]
+FileName=..\include\xline.h
+CompileCpp=1
+Folder=Headers
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit47]
+FileName=xline.cpp
+CompileCpp=1
+Folder=Source
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout
index b5fe0474f..df55af071 100644
--- a/src/InspIRCd.layout
+++ b/src/InspIRCd.layout
@@ -1,29 +1,29 @@
[Editors]
Focused=-1
-Order=2,4,6,3,7,25,5,24,39,42,43,-1,1
+Order=2,4,6,3,7,25,5,24,39,42,43,-1,1,46,0
[Editor_0]
-Open=0
+Open=1
Top=0
-CursorCol=20
-CursorRow=57
-TopLine=26
+CursorCol=39
+CursorRow=78
+TopLine=35
LeftChar=1
[Editor_1]
Open=1
Top=0
-CursorCol=44
-CursorRow=830
-TopLine=790
+CursorCol=7
+CursorRow=2372
+TopLine=2333
LeftChar=1
[Editor_2]
Open=1
Top=0
-CursorCol=1
-CursorRow=428
-TopLine=377
+CursorCol=18
+CursorRow=354
+TopLine=327
LeftChar=1
[Editor_3]
@@ -37,9 +37,9 @@ LeftChar=1
[Editor_4]
Open=1
Top=0
-CursorCol=2
-CursorRow=183
-TopLine=163
+CursorCol=58
+CursorRow=163
+TopLine=135
LeftChar=1
[Editor_5]
@@ -53,16 +53,16 @@ LeftChar=1
[Editor_6]
Open=1
Top=0
-CursorCol=18
-CursorRow=34
+CursorCol=16
+CursorRow=17
TopLine=1
LeftChar=1
[Editor_7]
Open=1
Top=0
-CursorCol=20
-CursorRow=15
+CursorCol=10
+CursorRow=18
TopLine=1
LeftChar=1
@@ -91,10 +91,10 @@ TopLine=76
LeftChar=1
[Editor_11]
-Open=0
-Top=0
-CursorCol=1
-CursorRow=7
+Open=1
+Top=1
+CursorCol=39
+CursorRow=6
TopLine=1
LeftChar=1
@@ -109,9 +109,9 @@ LeftChar=1
[Editor_13]
Open=1
Top=0
-CursorCol=37
-CursorRow=61
-TopLine=7
+CursorCol=12
+CursorRow=174
+TopLine=12
LeftChar=1
[Editor_14]
@@ -164,7 +164,7 @@ LeftChar=1
[Editor_20]
Open=1
-Top=1
+Top=0
CursorCol=5
CursorRow=506
TopLine=470
@@ -179,11 +179,11 @@ TopLine=12
LeftChar=1
[Editor_22]
-Open=0
+Open=1
Top=0
CursorCol=15
CursorRow=121
-TopLine=83
+TopLine=119
LeftChar=1
[Editor_23]
@@ -209,7 +209,7 @@ CursorRow=39
TopLine=1
LeftChar=1
[Editor_26]
-Open=0
+Open=1
Top=0
CursorCol=1
CursorRow=13
@@ -293,11 +293,11 @@ CursorRow=178
TopLine=156
LeftChar=1
[Editor_38]
-Open=0
+Open=1
Top=0
-CursorCol=1
-CursorRow=70
-TopLine=40
+CursorCol=39
+CursorRow=52
+TopLine=13
LeftChar=1
[Editor_39]
Open=1
@@ -316,28 +316,42 @@ LeftChar=1
[Editor_41]
Open=1
Top=0
-CursorCol=22
-CursorRow=13
+CursorCol=1
+CursorRow=1
TopLine=1
LeftChar=1
[Editor_42]
Open=1
Top=0
-CursorCol=4
-CursorRow=1729
-TopLine=1685
+CursorCol=19
+CursorRow=36
+TopLine=10
LeftChar=1
[Editor_43]
Open=1
Top=0
-CursorCol=6
-CursorRow=1259
-TopLine=1259
+CursorCol=1
+CursorRow=1367
+TopLine=1351
LeftChar=1
[Editor_44]
Open=1
Top=0
-CursorCol=34
-CursorRow=93
-TopLine=40
+CursorCol=63
+CursorRow=63
+TopLine=16
+LeftChar=1
+[Editor_45]
+Open=1
+Top=0
+CursorCol=27
+CursorRow=103
+TopLine=54
+LeftChar=1
+[Editor_46]
+Open=1
+Top=0
+CursorCol=27
+CursorRow=322
+TopLine=306
LeftChar=1
diff --git a/src/commands.cpp b/src/commands.cpp
index 28d10c3b5..043547180 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -1361,6 +1361,12 @@ void handle_nick(char **parameters, int pcnt, userrec *user)
*parameters[0]++;
}
}
+ if (matches_qline(parameters[0]))
+ {
+ WriteOpers("*** Q-Lined nickname %s from %s!%s@%s: %s",parameters[0],user->nick,user->ident,user->host,matches_qline(parameters[0]));
+ WriteServ(user->fd,"432 %s %s :Invalid nickname: %s",user->nick,parameters[0],matches_qline(parameters[0]));
+ return;
+ }
if ((Find(parameters[0])) && (Find(parameters[0]) != user))
{
WriteServ(user->fd,"433 %s %s :Nickname is already in use.",user->nick,parameters[0]);
@@ -1679,6 +1685,11 @@ void handle_n(char token,char* params,serverrec* source,serverrec* reply, char*
kill_link(user,"Nickname collision");
return;
}
+ if (matches_qline(newnick))
+ {
+ kill_link(user,"Nickname collision");
+ return;
+ }
// broadcast this because its a services thingy
char buffer[MAXBUF];
@@ -2604,3 +2615,21 @@ void handle_link_packet(char* udp_msg, char* tcp_host, serverrec *serv)
}
}
+
+void handle_kline(char **parameters, int pcnt, userrec *user)
+{
+}
+
+void handle_gline(char **parameters, int pcnt, userrec *user)
+{
+}
+
+void handle_zline(char **parameters, int pcnt, userrec *user)
+{
+}
+
+void handle_qline(char **parameters, int pcnt, userrec *user)
+{
+}
+
+
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 989faf9c7..a3177e949 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -267,184 +267,189 @@ void log(int level,char *text, ...)
void readfile(file_cache &F, const char* fname)
{
- FILE* file;
- char linebuf[MAXBUF];
-
- log(DEBUG,"readfile: loading %s",fname);
- F.clear();
- file = fopen(fname,"r");
- if (file)
- {
- while (!feof(file))
- {
- fgets(linebuf,sizeof(linebuf),file);
- linebuf[strlen(linebuf)-1]='\0';
- if (!strcmp(linebuf,""))
- {
- strcpy(linebuf," ");
- }
- if (!feof(file))
- {
- F.push_back(linebuf);
- }
- }
- fclose(file);
- }
- else
- {
- log(DEBUG,"readfile: failed to load file: %s",fname);
- }
- log(DEBUG,"readfile: loaded %s, %d lines",fname,F.size());
+ FILE* file;
+ char linebuf[MAXBUF];
+
+ log(DEBUG,"readfile: loading %s",fname);
+ F.clear();
+ file = fopen(fname,"r");
+ if (file)
+ {
+ while (!feof(file))
+ {
+ fgets(linebuf,sizeof(linebuf),file);
+ linebuf[strlen(linebuf)-1]='\0';
+ if (!strcmp(linebuf,""))
+ {
+ strcpy(linebuf," ");
+ }
+ if (!feof(file))
+ {
+ F.push_back(linebuf);
+ }
+ }
+ fclose(file);
+ }
+ else
+ {
+ log(DEBUG,"readfile: failed to load file: %s",fname);
+ }
+ log(DEBUG,"readfile: loaded %s, %d lines",fname,F.size());
}
void ReadConfig(void)
{
- char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF];
- ConnectClass c;
-
- LoadConf(CONFIG_FILE,&config_f);
-
- ConfValue("server","name",0,ServerName,&config_f);
- ConfValue("server","description",0,ServerDesc,&config_f);
- ConfValue("server","network",0,Network,&config_f);
- ConfValue("admin","name",0,AdminName,&config_f);
- ConfValue("admin","email",0,AdminEmail,&config_f);
- ConfValue("admin","nick",0,AdminNick,&config_f);
- ConfValue("files","motd",0,motd,&config_f);
- ConfValue("files","rules",0,rules,&config_f);
- ConfValue("power","diepass",0,diepass,&config_f);
- ConfValue("power","pause",0,pauseval,&config_f);
- ConfValue("power","restartpass",0,restartpass,&config_f);
- ConfValue("options","prefixquit",0,PrefixQuit,&config_f);
- ConfValue("die","value",0,DieValue,&config_f);
- ConfValue("options","loglevel",0,dbg,&config_f);
- ConfValue("options","netbuffersize",0,NB,&config_f);
- NetBufferSize = atoi(NB);
- if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024))
- {
- log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240.");
- NetBufferSize = 10240;
- }
- if (!strcmp(dbg,"debug"))
- LogLevel = DEBUG;
- if (!strcmp(dbg,"verbose"))
- LogLevel = VERBOSE;
- if (!strcmp(dbg,"default"))
- LogLevel = DEFAULT;
- if (!strcmp(dbg,"sparse"))
- LogLevel = SPARSE;
- if (!strcmp(dbg,"none"))
- LogLevel = NONE;
- readfile(MOTD,motd);
- log(DEBUG,"Reading message of the day");
- readfile(RULES,rules);
- log(DEBUG,"Reading connect classes");
- Classes.clear();
- for (int i = 0; i < ConfValueEnum("connect",&config_f); i++)
- {
- strcpy(Value,"");
- ConfValue("connect","allow",i,Value,&config_f);
- ConfValue("connect","timeout",i,timeout,&config_f);
- ConfValue("connect","flood",i,flood,&config_f);
- if (strcmp(Value,""))
- {
- strcpy(c.host,Value);
- c.type = CC_ALLOW;
+ char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF];
+ ConnectClass c;
+
+ LoadConf(CONFIG_FILE,&config_f);
+
+ ConfValue("server","name",0,ServerName,&config_f);
+ ConfValue("server","description",0,ServerDesc,&config_f);
+ ConfValue("server","network",0,Network,&config_f);
+ ConfValue("admin","name",0,AdminName,&config_f);
+ ConfValue("admin","email",0,AdminEmail,&config_f);
+ ConfValue("admin","nick",0,AdminNick,&config_f);
+ ConfValue("files","motd",0,motd,&config_f);
+ ConfValue("files","rules",0,rules,&config_f);
+ ConfValue("power","diepass",0,diepass,&config_f);
+ ConfValue("power","pause",0,pauseval,&config_f);
+ ConfValue("power","restartpass",0,restartpass,&config_f);
+ ConfValue("options","prefixquit",0,PrefixQuit,&config_f);
+ ConfValue("die","value",0,DieValue,&config_f);
+ ConfValue("options","loglevel",0,dbg,&config_f);
+ ConfValue("options","netbuffersize",0,NB,&config_f);
+ NetBufferSize = atoi(NB);
+ if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024))
+ {
+ log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240.");
+ NetBufferSize = 10240;
+ }
+ if (!strcmp(dbg,"debug"))
+ LogLevel = DEBUG;
+ if (!strcmp(dbg,"verbose"))
+ LogLevel = VERBOSE;
+ if (!strcmp(dbg,"default"))
+ LogLevel = DEFAULT;
+ if (!strcmp(dbg,"sparse"))
+ LogLevel = SPARSE;
+ if (!strcmp(dbg,"none"))
+ LogLevel = NONE;
+ readfile(MOTD,motd);
+ log(DEFAULT,"Reading message of the day...");
+ readfile(RULES,rules);
+ log(DEFAULT,"Reading connect classes...");
+ Classes.clear();
+ for (int i = 0; i < ConfValueEnum("connect",&config_f); i++)
+ {
strcpy(Value,"");
- ConfValue("connect","password",i,Value,&config_f);
- strcpy(c.pass,Value);
- c.registration_timeout = 90; // default is 2 minutes
- c.flood = atoi(flood);
- if (atoi(timeout)>0)
+ ConfValue("connect","allow",i,Value,&config_f);
+ ConfValue("connect","timeout",i,timeout,&config_f);
+ ConfValue("connect","flood",i,flood,&config_f);
+ if (strcmp(Value,""))
+ {
+ strcpy(c.host,Value);
+ c.type = CC_ALLOW;
+ strcpy(Value,"");
+ ConfValue("connect","password",i,Value,&config_f);
+ strcpy(c.pass,Value);
+ c.registration_timeout = 90; // default is 2 minutes
+ c.flood = atoi(flood);
+ if (atoi(timeout)>0)
+ {
+ c.registration_timeout = atoi(timeout);
+ }
+ Classes.push_back(c);
+ log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood);
+ }
+ else
{
- c.registration_timeout = atoi(timeout);
+ ConfValue("connect","deny",i,Value,&config_f);
+ strcpy(c.host,Value);
+ c.type = CC_DENY;
+ Classes.push_back(c);
+ log(DEBUG,"Read connect class type DENY, host=%s",c.host);
}
- Classes.push_back(c);
- log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood);
- }
- else
- {
- ConfValue("connect","deny",i,Value,&config_f);
- strcpy(c.host,Value);
- c.type = CC_DENY;
- Classes.push_back(c);
- log(DEBUG,"Read connect class type DENY, host=%s",c.host);
- }
- }
+ }
+ log(DEFAULT,"Reading K lines,Q lines and Z lines from config...");
+ read_xline_defaults();
+ log(DEFAULT,"Applying K lines, Q lines and Z lines...");
+ apply_lines();
+ log(DEFAULT,"Done reading configuration file, InspIRCd is now running.");
}
/* write formatted text to a socket, in same format as printf */
void Write(int sock,char *text, ...)
{
- if (!text)
- {
- log(DEFAULT,"*** BUG *** Write was given an invalid parameter");
- return;
- }
- char textbuffer[MAXBUF];
- va_list argsPtr;
- char tb[MAXBUF];
-
- va_start (argsPtr, text);
- vsnprintf(textbuffer, MAXBUF, text, argsPtr);
- va_end(argsPtr);
- sprintf(tb,"%s\r\n",textbuffer);
- chop(tb);
- if (sock != -1)
- {
- write(sock,tb,strlen(tb));
- update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
- }
+ if (!text)
+ {
+ log(DEFAULT,"*** BUG *** Write was given an invalid parameter");
+ return;
+ }
+ char textbuffer[MAXBUF];
+ va_list argsPtr;
+ char tb[MAXBUF];
+
+ va_start (argsPtr, text);
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+ sprintf(tb,"%s\r\n",textbuffer);
+ chop(tb);
+ if (sock != -1)
+ {
+ write(sock,tb,strlen(tb));
+ update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
+ }
}
/* write a server formatted numeric response to a single socket */
void WriteServ(int sock, char* text, ...)
{
- if (!text)
- {
- log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter");
- return;
- }
- char textbuffer[MAXBUF],tb[MAXBUF];
- va_list argsPtr;
- va_start (argsPtr, text);
-
- vsnprintf(textbuffer, MAXBUF, text, argsPtr);
- va_end(argsPtr);
- sprintf(tb,":%s %s\r\n",ServerName,textbuffer);
- chop(tb);
- if (sock != -1)
- {
- write(sock,tb,strlen(tb));
- update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
- }
+ if (!text)
+ {
+ log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter");
+ return;
+ }
+ char textbuffer[MAXBUF],tb[MAXBUF];
+ va_list argsPtr;
+ va_start (argsPtr, text);
+
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+ sprintf(tb,":%s %s\r\n",ServerName,textbuffer);
+ chop(tb);
+ if (sock != -1)
+ {
+ write(sock,tb,strlen(tb));
+ update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
+ }
}
/* write text from an originating user to originating user */
void WriteFrom(int sock, userrec *user,char* text, ...)
{
- if ((!text) || (!user))
- {
- log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter");
- return;
- }
- char textbuffer[MAXBUF],tb[MAXBUF];
- va_list argsPtr;
- va_start (argsPtr, text);
-
- vsnprintf(textbuffer, MAXBUF, text, argsPtr);
- va_end(argsPtr);
- sprintf(tb,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer);
- chop(tb);
- if (sock != -1)
- {
- write(sock,tb,strlen(tb));
- update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
- }
+ if ((!text) || (!user))
+ {
+ log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter");
+ return;
+ }
+ char textbuffer[MAXBUF],tb[MAXBUF];
+ va_list argsPtr;
+ va_start (argsPtr, text);
+
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+ sprintf(tb,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer);
+ chop(tb);
+ if (sock != -1)
+ {
+ write(sock,tb,strlen(tb));
+ update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */
+ }
}
/* write text to an destination user from a source user (e.g. user privmsg) */
@@ -2015,7 +2020,7 @@ void AddWhoWas(userrec* u)
/* add a client connection to the sockets list */
-void AddClient(int socket, char* host, int port, bool iscached)
+void AddClient(int socket, char* host, int port, bool iscached, char* ip)
{
int i;
int blocking = 1;
@@ -2054,6 +2059,7 @@ void AddClient(int socket, char* host, int port, bool iscached)
clientlist[tempnick]->nping = time(NULL)+240;
clientlist[tempnick]->lastping = 1;
clientlist[tempnick]->port = port;
+ strncpy(clientlist[tempnick]->ip,ip,32);
if (iscached)
{
@@ -2366,6 +2372,11 @@ void force_nickchange(userrec* user,const char* newnick)
kill_link(user,"Nickname collision");
return;
}
+ if (matches_qline(newnick))
+ {
+ kill_link(user,"Nickname collision");
+ return;
+ }
if (user)
{
@@ -2738,6 +2749,10 @@ void SetupCommandTable(void)
createcommand("MODULES",handle_modules,'o',0);
createcommand("LINKS",handle_links,0,0);
createcommand("MAP",handle_map,0,0);
+ createcommand("KLINE",handle_kline,'o',3);
+ createcommand("GLINE",handle_gline,'o',3);
+ createcommand("ZLINE",handle_zline,'o',3);
+ createcommand("QLINE",handle_qline,'o',3);
}
void process_buffer(const char* cmdbuf,userrec *user)
@@ -3448,7 +3463,7 @@ int InspIRCd(void)
}
else
{
- AddClient(incomingSockfd, resolved, ports[count], iscached);
+ AddClient(incomingSockfd, resolved, ports[count], iscached, target);
log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd);
}
goto label;
diff --git a/src/users.cpp b/src/users.cpp
index 48295eddd..6fb0e6a5c 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -12,7 +12,7 @@ userrec::userrec()
{
// the PROPER way to do it, AVOID bzero at *ALL* costs
strcpy(nick,"");
- ip = 0;
+ strcpy(ip,"127.0.0.1");
timeout = 0;
strcpy(ident,"");
strcpy(host,"");
diff --git a/src/wildcard.cpp b/src/wildcard.cpp
index 41070d145..f74de804a 100644
--- a/src/wildcard.cpp
+++ b/src/wildcard.cpp
@@ -75,7 +75,7 @@ if ((strstr(mask,"*")==0) && (strlen(literal) != strlen(mask)))
}
-bool match(char* literal, char* mask)
+bool match(const char* literal, const char* mask)
{
char L[10240];
char M[10240];
diff --git a/src/xline.cpp b/src/xline.cpp
index f653d80af..6ca005bad 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -35,6 +35,13 @@
#include "commands.h"
#include "xline.h"
+#ifdef GCC3
+#define nspace __gnu_cxx
+#else
+#define nspace std
+#endif
+
+
using namespace std;
extern int MODCOUNT;
@@ -56,8 +63,453 @@ extern char list[MAXBUF];
extern char PrefixQuit[MAXBUF];
extern char DieValue[MAXBUF];
+extern int debugging;
+extern int WHOWAS_STALE;
+extern int WHOWAS_MAX;
+extern int DieDelay;
+extern time_t startup_time;
+extern int NetBufferSize;
+extern time_t nb_start;
+
+extern std::vector<int> fd_reap;
+extern std::vector<std::string> module_names;
+
+extern char bannerBuffer[MAXBUF];
+extern int boundPortCount;
+extern int portCount;
+extern int UDPportCount;
+extern int ports[MAXSOCKS];
+extern int defaultRoute;
+
+extern std::vector<long> auth_cookies;
+extern std::stringstream config_f;
+
+extern serverrec* me[32];
+
+extern FILE *log_file;
+
+namespace nspace
+{
+ template<> struct nspace::hash<in_addr>
+ {
+ size_t operator()(const struct in_addr &a) const
+ {
+ size_t q;
+ memcpy(&q,&a,sizeof(size_t));
+ return q;
+ }
+ };
+
+ template<> struct nspace::hash<string>
+ {
+ size_t operator()(const string &s) const
+ {
+ char a[MAXBUF];
+ static struct hash<const char *> strhash;
+ strcpy(a,s.c_str());
+ strlower(a);
+ return strhash(a);
+ }
+ };
+}
+
+
+struct StrHashComp
+{
+
+ bool operator()(const string& s1, const string& s2) const
+ {
+ char a[MAXBUF],b[MAXBUF];
+ strcpy(a,s1.c_str());
+ strcpy(b,s2.c_str());
+ return (strcasecmp(a,b) == 0);
+ }
+
+};
+
+struct InAddr_HashComp
+{
+
+ bool operator()(const in_addr &s1, const in_addr &s2) const
+ {
+ size_t q;
+ size_t p;
+
+ memcpy(&q,&s1,sizeof(size_t));
+ memcpy(&p,&s2,sizeof(size_t));
+
+ return (q == p);
+ }
+
+};
+
+
+typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, StrHashComp> user_hash;
+typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, StrHashComp> chan_hash;
+typedef nspace::hash_map<in_addr,string*, nspace::hash<in_addr>, InAddr_HashComp> address_cache;
+typedef std::deque<command_t> command_table;
+
+
+extern user_hash clientlist;
+extern chan_hash chanlist;
+extern user_hash whowas;
+extern command_table cmdlist;
+extern file_cache MOTD;
+extern file_cache RULES;
+extern address_cache IP;
+
+
std::vector<KLine> klines;
std::vector<GLine> glines;
std::vector<ZLine> zlines;
std::vector<QLine> qlines;
+// Reads the default bans from the config file.
+// only a very small number of bans are defined
+// this way these days, such as qlines against
+// services nicks, etc.
+
+void read_xline_defaults()
+{
+ char ipmask[MAXBUF];
+ char nick[MAXBUF];
+ char host[MAXBUF];
+ char reason[MAXBUF];
+
+ for (int i = 0; i < ConfValueEnum("badip",&config_f); i++)
+ {
+ ConfValue("badip","ipmask",i,ipmask,&config_f);
+ ConfValue("badip","reason",i,reason,&config_f);
+ add_zline(0,"<Config>",reason,ipmask);
+ log(DEBUG,"Read Z line (badip tag): ipmask=%s reason=%s",ipmask,reason);
+ }
+
+ for (int i = 0; i < ConfValueEnum("badnick",&config_f); i++)
+ {
+ ConfValue("badnick","nick",i,nick,&config_f);
+ ConfValue("badnick","reason",i,reason,&config_f);
+ add_qline(0,"<Config>",reason,nick);
+ log(DEBUG,"Read Q line (badnick tag): nick=%s reason=%s",nick,reason);
+ }
+
+ for (int i = 0; i < ConfValueEnum("badhost",&config_f); i++)
+ {
+ ConfValue("badhost","host",i,host,&config_f);
+ ConfValue("badhost","reason",i,reason,&config_f);
+ add_kline(0,"<Config>",reason,host);
+ log(DEBUG,"Read K line (badhost tag): host=%s reason=%s",host,reason);
+ }
+}
+
+// adds a g:line
+
+void add_gline(long duration, char* source, char* reason, char* hostmask)
+{
+ GLine item;
+ item.duration = duration;
+ strncpy(item.hostmask,hostmask,MAXBUF);
+ strncpy(item.reason,reason,MAXBUF);
+ strncpy(item.source,source,MAXBUF);
+ item.n_matches = 0;
+ item.set_time = time(NULL);
+ glines.push_back(item);
+}
+
+// adds a q:line
+
+void add_qline(long duration, char* source, char* reason, char* nickname)
+{
+ QLine item;
+ item.duration = duration;
+ strncpy(item.nick,nickname,MAXBUF);
+ strncpy(item.reason,reason,MAXBUF);
+ strncpy(item.source,source,MAXBUF);
+ item.n_matches = 0;
+ item.set_time = time(NULL);
+ qlines.push_back(item);
+}
+
+// adds a z:line
+
+void add_zline(long duration, char* source, char* reason, char* ipaddr)
+{
+ ZLine item;
+ item.duration = duration;
+ strncpy(item.ipaddr,ipaddr,MAXBUF);
+ strncpy(item.reason,reason,MAXBUF);
+ strncpy(item.source,source,MAXBUF);
+ item.n_matches = 0;
+ item.set_time = time(NULL);
+ zlines.push_back(item);
+}
+
+// adds a k:line
+
+void add_kline(long duration, char* source, char* reason, char* hostmask)
+{
+ KLine item;
+ item.duration = duration;
+ strncpy(item.hostmask,hostmask,MAXBUF);
+ strncpy(item.reason,reason,MAXBUF);
+ strncpy(item.source,source,MAXBUF);
+ item.n_matches = 0;
+ item.set_time = time(NULL);
+ klines.push_back(item);
+}
+
+// deletes a g:line, returns true if the line existed and was removed
+
+bool del_gline(char* hostmask)
+{
+ for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++)
+ {
+ if (!strcasecmp(hostmask,i->hostmask))
+ {
+ glines.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+// deletes a q:line, returns true if the line existed and was removed
+
+bool del_qline(char* nickname)
+{
+ for (std::vector<QLine>::iterator i = qlines.begin(); i != qlines.end(); i++)
+ {
+ if (!strcasecmp(nickname,i->nick))
+ {
+ qlines.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+// deletes a z:line, returns true if the line existed and was removed
+
+bool del_zline(char* ipaddr)
+{
+ for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++)
+ {
+ if (!strcasecmp(ipaddr,i->ipaddr))
+ {
+ zlines.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+// deletes a k:line, returns true if the line existed and was removed
+
+bool del_kline(char* hostmask)
+{
+ for (std::vector<KLine>::iterator i = klines.begin(); i != klines.end(); i++)
+ {
+ if (!strcasecmp(hostmask,i->hostmask))
+ {
+ klines.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+// returns a pointer to the reason if a nickname matches a qline, NULL if it didnt match
+
+char* matches_qline(const char* nick)
+{
+ for (std::vector<QLine>::iterator i = qlines.begin(); i != qlines.end(); i++)
+ {
+ if (match(nick,i->nick))
+ {
+ return i->reason;
+ }
+ }
+ return NULL;
+}
+
+// returns a pointer to the reason if a host matches a gline, NULL if it didnt match
+
+char* matches_gline(const char* host)
+{
+ for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++)
+ {
+ if (match(host,i->hostmask))
+ {
+ return i->reason;
+ }
+ }
+ return NULL;
+}
+
+// returns a pointer to the reason if an ip address matches a zline, NULL if it didnt match
+
+char* matches_zline(const char* ipaddr)
+{
+ for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++)
+ {
+ if (match(ipaddr,i->ipaddr))
+ {
+ return i->reason;
+ }
+ }
+ return NULL;
+}
+
+// returns a pointer to the reason if a host matches a kline, NULL if it didnt match
+
+char* matches_kline(const char* host)
+{
+ for (std::vector<KLine>::iterator i = klines.begin(); i != klines.end(); i++)
+ {
+ if (match(host,i->hostmask))
+ {
+ return i->reason;
+ }
+ }
+ return NULL;
+}
+
+// removes lines that have expired
+
+void expire_lines()
+{
+ bool go_again = true;
+ time_t current = time(NULL);
+
+ // because we mess up an iterator when we remove from the vector, we must bail from
+ // the loop early if we delete an item, therefore this outer while loop is required.
+ while (go_again)
+ {
+ go_again = false;
+
+ for (std::vector<KLine>::iterator i = klines.begin(); i != klines.end(); i++)
+ {
+ if ((current > (i->duration + i->set_time)) && (i->duration > 0))
+ {
+ WriteOpers("Expiring timed K-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration);
+ klines.erase(i);
+ go_again = true;
+ break;
+ }
+ }
+
+ for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++)
+ {
+ if ((current > (i->duration + i->set_time)) && (i->duration > 0))
+ {
+ WriteOpers("Expiring timed G-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration);
+ glines.erase(i);
+ go_again = true;
+ break;
+ }
+ }
+
+ for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++)
+ {
+ if ((current > (i->duration + i->set_time)) && (i->duration > 0))
+ {
+ WriteOpers("Expiring timed Z-Line %s (set by %s %d seconds ago)",i->ipaddr,i->source,i->duration);
+ zlines.erase(i);
+ go_again = true;
+ break;
+ }
+ }
+
+ for (std::vector<QLine>::iterator i = qlines.begin(); i != qlines.end(); i++)
+ {
+ if ((current > (i->duration + i->set_time)) && (i->duration > 0))
+ {
+ WriteOpers("Expiring timed Q-Line %s (set by %s %d seconds ago)",i->nick,i->source,i->duration);
+ qlines.erase(i);
+ go_again = true;
+ break;
+ }
+ }
+ }
+}
+
+// applies lines, removing clients and changing nicks etc as applicable
+
+void apply_lines()
+{
+ bool go_again = true;
+ char reason[MAXBUF];
+ char host[MAXBUF];
+
+ while (go_again)
+ {
+ go_again = false;
+ for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ {
+ if (!strcasecmp(u->second->server,ServerName))
+ {
+ snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host);
+ char* check = matches_gline(host);
+ if (check)
+ {
+ WriteOpers("*** User %s matches G-Line: %s",u->second->nick,check);
+ snprintf(reason,MAXBUF,"G-Lined: %s",check);
+ kill_link(u->second,reason);
+ go_again = true;
+ break;
+ }
+ }
+ }
+
+ for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ {
+ if (!strcasecmp(u->second->server,ServerName))
+ {
+ snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host);
+ char* check = matches_kline(host);
+ if (check)
+ {
+ WriteOpers("*** User %s matches K-Line: %s",u->second->nick,check);
+ snprintf(reason,MAXBUF,"K-Lined: %s",check);
+ kill_link(u->second,reason);
+ go_again = true;
+ break;
+ }
+ }
+ }
+
+ for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ {
+ if (!strcasecmp(u->second->server,ServerName))
+ {
+ char* check = matches_qline(u->second->nick);
+ if (check)
+ {
+ snprintf(reason,MAXBUF,"Matched Q-Lined nick: %s",check);
+ WriteOpers("*** Q-Lined nickname %s from %s: %s",u->second->nick,u->second->host,check);
+ WriteServ(u->second->fd,"432 %s %s :Invalid nickname: %s",u->second->nick,u->second->nick,check);
+ kill_link(u->second,reason);
+ go_again = true;
+ break;
+ }
+ }
+ }
+
+ for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ {
+ if (!strcasecmp(u->second->server,ServerName))
+ {
+ char* check = matches_zline(u->second->ip);
+ if (check)
+ {
+ WriteOpers("*** User %s matches Z-Line: %s",u->second->nick,u->second->host,check);
+ WriteServ(u->second->fd,"432 %s %s :Invalid nickname: %s",u->second->nick,u->second->nick,check);
+ go_again = true;
+ break;
+ }
+ }
+ }
+
+ }
+}
+
+