summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md24
-rw-r--r--docs/README10
-rw-r--r--docs/conf/aliases/anope.conf.example (renamed from docs/aliases/anope.conf.example)0
-rw-r--r--docs/conf/aliases/atheme.conf.example (renamed from docs/aliases/atheme.conf.example)0
-rw-r--r--docs/conf/aliases/ircservices.conf.example (renamed from docs/aliases/ircservices.conf.example)0
-rw-r--r--docs/conf/aliases/neostats.conf.example (renamed from docs/aliases/neostats.conf.example)0
-rw-r--r--docs/conf/inspircd.censor.example (renamed from docs/inspircd.censor.example)0
-rw-r--r--docs/conf/inspircd.conf.example (renamed from docs/inspircd.conf.example)0
-rw-r--r--docs/conf/inspircd.filter.example (renamed from docs/inspircd.filter.example)0
-rw-r--r--docs/conf/inspircd.helpop-full.example (renamed from docs/inspircd.helpop-full.example)0
-rw-r--r--docs/conf/inspircd.helpop.example (renamed from docs/inspircd.helpop.example)0
-rw-r--r--docs/conf/inspircd.motd.example (renamed from docs/inspircd.motd.example)0
-rw-r--r--docs/conf/inspircd.quotes.example (renamed from docs/inspircd.quotes.example)0
-rw-r--r--docs/conf/inspircd.rules.example (renamed from docs/inspircd.rules.example)0
-rw-r--r--docs/conf/links.conf.example (renamed from docs/links.conf.example)2
-rw-r--r--docs/conf/modules.conf.example (renamed from docs/modules.conf.example)0
-rw-r--r--docs/conf/modules/modules.conf.charybdis (renamed from docs/modules/modules.conf.charybdis)0
-rw-r--r--docs/conf/modules/modules.conf.unreal (renamed from docs/modules/modules.conf.unreal)0
-rw-r--r--docs/conf/opers.conf.example (renamed from docs/opers.conf.example)0
-rw-r--r--include/modules.h8
-rw-r--r--include/users.h5
-rw-r--r--make/template/main.mk10
-rw-r--r--src/modules.cpp3
-rw-r--r--src/modules/extra/m_geoip.cpp63
-rw-r--r--src/modules/m_cap.h9
-rw-r--r--src/modules/m_check.cpp4
-rw-r--r--src/modules/m_dnsbl.cpp22
-rw-r--r--src/modules/m_ircv3.cpp214
-rw-r--r--src/modules/m_namesx.cpp39
-rw-r--r--src/modules/m_services_account.cpp4
-rw-r--r--src/modules/m_spanningtree/main.cpp16
-rw-r--r--src/modules/m_spanningtree/resolvers.cpp30
-rw-r--r--src/modules/m_spanningtree/resolvers.h25
-rw-r--r--src/modules/m_spanningtree/server.cpp8
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp12
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp13
-rw-r--r--src/modules/m_spanningtree/uid.cpp2
-rw-r--r--src/modules/m_spanningtree/utils.cpp79
-rw-r--r--src/modules/m_stripcolor.cpp2
-rw-r--r--src/usermanager.cpp10
-rw-r--r--src/users.cpp21
-rw-r--r--win/configure.cpp10
42 files changed, 489 insertions, 156 deletions
diff --git a/README.md b/README.md
index f62911b69..2f77c5c15 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,21 @@
-### InspIRCd
+### About
-InspIRCd is an IRC daemon written entirely from scratch, it is one of the
-few IRC daemons to be written in C++ and it was released under the GNU
-General Public License. InspIRCd is the second most used IRC daemon
-according to the ranking on SearchIRC.
+InspIRCd is a modular Internet Relay Chat (IRC) server written in C++ for Linux,
+BSD, Windows and Mac OS X systems which was created from scratch to be stable,
+modern and lightweight.
-The first stable release of InspIRCd was in 2002.
+As InspIRCd is one of the few IRC servers written from scratch, it avoids a
+number of design flaws and performance issues that plague other more established
+projects, such as UnrealIRCd, while providing the same level of feature parity.
+
+InspIRCd is one of only a few IRC servers to provide a tunable number of
+features through the use of an advanced but well documented module system. By
+keeping core functionality to a minimum we hope to increase the stability,
+security and speed of InspIRCd while also making it customisable to the needs of
+many different users.
### Links
-Website: http://www.inspircd.org
-GitHub: https://github.com/inspircd/inspircd
+* [Website](http://inspircd.github.com)
+* [GitHub]( https://github.com/inspircd)
+* [IRC](irc://irc.chatspike.net/inspircd) \ No newline at end of file
diff --git a/docs/README b/docs/README
deleted file mode 100644
index e8dcfea77..000000000
--- a/docs/README
+++ /dev/null
@@ -1,10 +0,0 @@
-Because of the dynamic nature of InspIRCd, we do not have traditional documentation in our tarball.
-
-The documentation for InspIRCd can be found on our wiki, at http://wiki.inspircd.org
-Our Bugtracker can be found at http://www.inspircd.org/bugtrack
-Our Forum can be found at http://www.inspircd.org/forum
-
-For online support, please connect to irc.inspircd.org, and join #inspircd
-
- -- The InspIRCd Team
-
diff --git a/docs/aliases/anope.conf.example b/docs/conf/aliases/anope.conf.example
index 406adc29a..406adc29a 100644
--- a/docs/aliases/anope.conf.example
+++ b/docs/conf/aliases/anope.conf.example
diff --git a/docs/aliases/atheme.conf.example b/docs/conf/aliases/atheme.conf.example
index 7a0bc015a..7a0bc015a 100644
--- a/docs/aliases/atheme.conf.example
+++ b/docs/conf/aliases/atheme.conf.example
diff --git a/docs/aliases/ircservices.conf.example b/docs/conf/aliases/ircservices.conf.example
index a4c31dd05..a4c31dd05 100644
--- a/docs/aliases/ircservices.conf.example
+++ b/docs/conf/aliases/ircservices.conf.example
diff --git a/docs/aliases/neostats.conf.example b/docs/conf/aliases/neostats.conf.example
index baa7fe0ba..baa7fe0ba 100644
--- a/docs/aliases/neostats.conf.example
+++ b/docs/conf/aliases/neostats.conf.example
diff --git a/docs/inspircd.censor.example b/docs/conf/inspircd.censor.example
index 342ccd875..342ccd875 100644
--- a/docs/inspircd.censor.example
+++ b/docs/conf/inspircd.censor.example
diff --git a/docs/inspircd.conf.example b/docs/conf/inspircd.conf.example
index d1293be25..d1293be25 100644
--- a/docs/inspircd.conf.example
+++ b/docs/conf/inspircd.conf.example
diff --git a/docs/inspircd.filter.example b/docs/conf/inspircd.filter.example
index 8200a028f..8200a028f 100644
--- a/docs/inspircd.filter.example
+++ b/docs/conf/inspircd.filter.example
diff --git a/docs/inspircd.helpop-full.example b/docs/conf/inspircd.helpop-full.example
index 9c4ae0b92..9c4ae0b92 100644
--- a/docs/inspircd.helpop-full.example
+++ b/docs/conf/inspircd.helpop-full.example
diff --git a/docs/inspircd.helpop.example b/docs/conf/inspircd.helpop.example
index 4b3354837..4b3354837 100644
--- a/docs/inspircd.helpop.example
+++ b/docs/conf/inspircd.helpop.example
diff --git a/docs/inspircd.motd.example b/docs/conf/inspircd.motd.example
index 0a1260c0c..0a1260c0c 100644
--- a/docs/inspircd.motd.example
+++ b/docs/conf/inspircd.motd.example
diff --git a/docs/inspircd.quotes.example b/docs/conf/inspircd.quotes.example
index 56a580e33..56a580e33 100644
--- a/docs/inspircd.quotes.example
+++ b/docs/conf/inspircd.quotes.example
diff --git a/docs/inspircd.rules.example b/docs/conf/inspircd.rules.example
index e51f0afd9..e51f0afd9 100644
--- a/docs/inspircd.rules.example
+++ b/docs/conf/inspircd.rules.example
diff --git a/docs/links.conf.example b/docs/conf/links.conf.example
index a573b66da..94340cd31 100644
--- a/docs/links.conf.example
+++ b/docs/conf/links.conf.example
@@ -65,6 +65,8 @@
# passwords: the passwords we send and receive.
# The remote server will have these passwords reversed.
+ # Passwords that contain a space character or begin with
+ # a colon (:) are invalid and may not be used.
sendpass="outgoing!password"
recvpass="incoming!password">
diff --git a/docs/modules.conf.example b/docs/conf/modules.conf.example
index e987f4878..e987f4878 100644
--- a/docs/modules.conf.example
+++ b/docs/conf/modules.conf.example
diff --git a/docs/modules/modules.conf.charybdis b/docs/conf/modules/modules.conf.charybdis
index 8ba2f1b40..8ba2f1b40 100644
--- a/docs/modules/modules.conf.charybdis
+++ b/docs/conf/modules/modules.conf.charybdis
diff --git a/docs/modules/modules.conf.unreal b/docs/conf/modules/modules.conf.unreal
index 105acefee..105acefee 100644
--- a/docs/modules/modules.conf.unreal
+++ b/docs/conf/modules/modules.conf.unreal
diff --git a/docs/opers.conf.example b/docs/conf/opers.conf.example
index d76496e66..d76496e66 100644
--- a/docs/opers.conf.example
+++ b/docs/conf/opers.conf.example
diff --git a/include/modules.h b/include/modules.h
index b428a5f8d..7cd6bbeab 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -116,7 +116,7 @@ struct ModResult {
* and numerical comparisons in preprocessor macros if they wish to support
* multiple versions of InspIRCd in one file.
*/
-#define INSPIRCD_VERSION_API 1
+#define INSPIRCD_VERSION_API 2
/**
* This #define allows us to call a method in all
@@ -339,6 +339,7 @@ enum Implementation
I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO,
I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent,
+ I_OnSetClientIP,
I_END
};
@@ -1288,6 +1289,11 @@ class CoreExport Module : public classbase, public usecountbase
* @param line The raw line to send; modifiable, if empty no line will be returned.
*/
virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line);
+
+ /** Called whenever a User's ip changes.
+ * @param user The user whose ip changed.
+ */
+ virtual void OnSetClientIP(User *user);
};
diff --git a/include/users.h b/include/users.h
index 56297bed8..cdc0d8078 100644
--- a/include/users.h
+++ b/include/users.h
@@ -394,6 +394,11 @@ class CoreExport User : public Extensible
*/
bool SetClientIP(const char* sip);
+ /** Sets the client IP for this user
+ * @return true always
+ */
+ bool SetClientIP(irc::sockets::sockaddrs *sa);
+
/** Constructor
* @throw CoreException if the UID allocated to the user already exists
*/
diff --git a/make/template/main.mk b/make/template/main.mk
index 9a5f4db05..3d7b8a694 100644
--- a/make/template/main.mk
+++ b/make/template/main.mk
@@ -61,6 +61,9 @@ INSTMODE_LIB = 0644
@IFEQ $(SYSTEM) gnukfreebsd
LDLIBS += -ldl -lrt
@ENDIF
+@IFEQ $(SYSTEM) gnu
+ LDLIBS += -ldl -lrt
+@ENDIF
@IFEQ $(SYSTEM) solaris
LDLIBS += -lsocket -lnsl -lrt -lresolv
@ENDIF
@@ -212,7 +215,8 @@ install: target
@-install -d -o $(INSTUID) -m $(INSTMODE_DIR) $(BASE)/data
@-install -d -o $(INSTUID) -m $(INSTMODE_DIR) $(BASE)/logs
@-install -d -m $(INSTMODE_DIR) $(BINPATH)
- @-install -d -m $(INSTMODE_DIR) $(CONPATH)/examples
+ @-install -d -m $(INSTMODE_DIR) $(CONPATH)/examples/aliases
+ @-install -d -m $(INSTMODE_DIR) $(CONPATH)/examples/modules
@-install -d -m $(INSTMODE_DIR) $(MODPATH)
[ $(BUILDPATH)/bin/ -ef $(BINPATH) ] || install -m $(INSTMODE_BIN) $(BUILDPATH)/bin/inspircd $(BINPATH)
@IFNDEF PURE_STATIC
@@ -220,7 +224,9 @@ install: target
@ENDIF
-install -m $(INSTMODE_BIN) @STARTSCRIPT@ $(BASE) 2>/dev/null
-install -m $(INSTMODE_LIB) tools/gdbargs $(BASE)/.gdbargs 2>/dev/null
- -install -m $(INSTMODE_LIB) docs/*.example $(CONPATH)/examples
+ -install -m $(INSTMODE_LIB) docs/conf/*.example $(CONPATH)/examples
+ -install -m $(INSTMODE_LIB) docs/conf/aliases/*.example $(CONPATH)/examples/aliases
+ -install -m $(INSTMODE_LIB) docs/conf/modules/*.conf.* $(CONPATH)/examples/modules
@echo ""
@echo "*************************************"
@echo "* INSTALL COMPLETE! *"
diff --git a/src/modules.cpp b/src/modules.cpp
index 5f1081a1c..8306ff6af 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -176,6 +176,7 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO
void Module::OnHookIO(StreamSocket*, ListenSocket*) { }
ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; }
void Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, std::string&) { }
+void Module::OnSetClientIP(User *) { }
ModuleManager::ModuleManager() : ModCount(0)
{
@@ -313,7 +314,7 @@ swap_now:
for (unsigned int j = my_pos; j != swap_pos; j += incrmnt)
{
- if (( j + incrmnt > EventHandlers[i].size() - 1) || (j + incrmnt < 0))
+ if ((j + incrmnt > EventHandlers[i].size() - 1) || ((incrmnt == -1) && (j == 0)))
continue;
std::swap(EventHandlers[i][j], EventHandlers[i][j+incrmnt]);
diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp
index 939752875..cf87de51e 100644
--- a/src/modules/extra/m_geoip.cpp
+++ b/src/modules/extra/m_geoip.cpp
@@ -35,6 +35,16 @@ class ModuleGeoIP : public Module
LocalStringExt ext;
GeoIP* gi;
+ void SetExt(LocalUser* user)
+ {
+ const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString());
+ if (!c)
+ c = "UNK";
+
+ std::string* cc = new std::string(c);
+ ext.set(user, cc);
+ }
+
public:
ModuleGeoIP() : ext("geoip_cc", this), gi(NULL)
{
@@ -47,13 +57,23 @@ class ModuleGeoIP : public Module
throw ModuleException("Unable to initialize geoip, are you missing GeoIP.dat?");
ServerInstance->Modules->AddService(ext);
- Implementation eventlist[] = { I_OnSetConnectClass };
- ServerInstance->Modules->Attach(eventlist, this, 1);
+ Implementation eventlist[] = { I_OnSetConnectClass, I_OnStats };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
+
+ for (std::vector<LocalUser*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
+ {
+ LocalUser* user = *i;
+ if ((user->registered == REG_ALL) && (!ext.get(user)))
+ {
+ SetExt(user);
+ }
+ }
}
~ModuleGeoIP()
{
- GeoIP_delete(gi);
+ if (gi)
+ GeoIP_delete(gi);
}
Version GetVersion()
@@ -65,13 +85,8 @@ class ModuleGeoIP : public Module
{
std::string* cc = ext.get(user);
if (!cc)
- {
- const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString());
- if (!c)
- c = "UNK";
- cc = new std::string(c);
- ext.set(user, cc);
- }
+ SetExt(user);
+
std::string geoip = myclass->config->getString("geoip");
if (geoip.empty())
return MOD_RES_PASSTHRU;
@@ -82,6 +97,34 @@ class ModuleGeoIP : public Module
return MOD_RES_PASSTHRU;
return MOD_RES_DENY;
}
+
+ ModResult OnStats(char symbol, User* user, string_list &out)
+ {
+ if (symbol != 'G')
+ return MOD_RES_PASSTHRU;
+
+ unsigned int unknown = 0;
+ std::map<std::string, unsigned int> results;
+ for (std::vector<LocalUser*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
+ {
+ std::string* cc = ext.get(*i);
+ if (cc)
+ results[*cc]++;
+ else
+ unknown++;
+ }
+
+ std::string p = ServerInstance->Config->ServerName + " 801 " + user->nick + " :GeoIPSTATS ";
+ for (std::map<std::string, unsigned int>::const_iterator i = results.begin(); i != results.end(); ++i)
+ {
+ out.push_back(p + i->first + " " + ConvToStr(i->second));
+ }
+
+ if (unknown)
+ out.push_back(p + "Unknown " + ConvToStr(unknown));
+
+ return MOD_RES_DENY;
+ }
};
MODULE_INIT(ModuleGeoIP)
diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h
index 0fc782b97..604fdb0ef 100644
--- a/src/modules/m_cap.h
+++ b/src/modules/m_cap.h
@@ -59,19 +59,16 @@ class GenericCap
ext.set(data->user, 1);
}
}
-
- if (ev.id == "cap_ls")
+ else if (ev.id == "cap_ls")
{
data->wanted.push_back(cap);
}
-
- if (ev.id == "cap_list")
+ else if (ev.id == "cap_list")
{
if (ext.get(data->user))
data->wanted.push_back(cap);
}
-
- if (ev.id == "cap_clear")
+ else if (ev.id == "cap_clear")
{
data->ack.push_back("-" + cap);
ext.set(data->user, 0);
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 8316b09fe..099661de7 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -225,13 +225,13 @@ class CommandCheck : public Command
if (InspIRCd::Match(a->second->host, parameters[0], ascii_case_insensitive_map) || InspIRCd::Match(a->second->dhost, parameters[0], ascii_case_insensitive_map))
{
/* host or vhost matches mask */
- user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost());
+ user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost() + " " + a->second->GetIPString() + " " + a->second->fullname);
}
/* IP address */
else if (InspIRCd::MatchCIDR(a->second->GetIPString(), parameters[0]))
{
/* same IP. */
- user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost());
+ user->SendText(checkstr + " match " + ConvToStr(++x) + " " + a->second->GetFullRealHost() + " " + a->second->GetIPString() + " " + a->second->fullname);
}
}
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 2160b02dc..6a41c484f 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -243,7 +243,7 @@ class ModuleDNSBL : public Module
ReadConf();
ServerInstance->Modules->AddService(nameExt);
ServerInstance->Modules->AddService(countExt);
- Implementation eventlist[] = { I_OnRehash, I_OnUserInit, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
+ Implementation eventlist[] = { I_OnRehash, I_OnSetClientIP, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
ServerInstance->Modules->Attach(eventlist, this, 5);
}
@@ -348,22 +348,24 @@ class ModuleDNSBL : public Module
ReadConf();
}
- void OnUserInit(LocalUser* user)
+ void OnSetClientIP(User* user)
{
- if (user->exempt)
+ LocalUser *luser = IS_LOCAL(user);
+
+ if (!luser || luser->exempt)
return;
unsigned char a, b, c, d;
char reversedipbuf[128];
std::string reversedip;
- if (user->client_sa.sa.sa_family != AF_INET)
+ if (luser->client_sa.sa.sa_family != AF_INET)
return;
- d = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
- c = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
- b = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
- a = (unsigned char) user->client_sa.in4.sin_addr.s_addr & 0xFF;
+ d = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
+ c = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
+ b = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
+ a = (unsigned char) luser->client_sa.in4.sin_addr.s_addr & 0xFF;
snprintf(reversedipbuf, 128, "%d.%d.%d.%d", d, c, b, a);
reversedip = std::string(reversedipbuf);
@@ -377,11 +379,11 @@ class ModuleDNSBL : public Module
/* now we'd need to fire off lookups for `hostname'. */
bool cached;
- DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, user, DNSBLConfEntries[i], cached);
+ DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, luser, DNSBLConfEntries[i], cached);
ServerInstance->AddResolver(r, cached);
i++;
}
- countExt.set(user, i);
+ countExt.set(luser, i);
}
ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass)
diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp
new file mode 100644
index 000000000..fe400fa80
--- /dev/null
+++ b/src/modules/m_ircv3.cpp
@@ -0,0 +1,214 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2012 Attila Molnar <attilamolnar@hush.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* $ModDesc: Provides support for extended-join, away-notify and account-notify CAP capabilities */
+
+#include "inspircd.h"
+#include "account.h"
+#include "m_cap.h"
+
+class ModuleIRCv3 : public Module
+{
+ GenericCap cap_accountnotify;
+ GenericCap cap_awaynotify;
+ GenericCap cap_extendedjoin;
+ bool accountnotify;
+ bool awaynotify;
+ bool extendedjoin;
+
+ void WriteNeighboursWithExt(User* user, const std::string& line, const LocalIntExt& ext)
+ {
+ UserChanList chans(user->chans);
+
+ std::map<User*, bool> exceptions;
+ FOREACH_MOD(I_OnBuildNeighborList, OnBuildNeighborList(user, chans, exceptions));
+
+ // Send it to all local users who were explicitly marked as neighbours by modules and have the required ext
+ for (std::map<User*, bool>::const_iterator i = exceptions.begin(); i != exceptions.end(); ++i)
+ {
+ LocalUser* u = IS_LOCAL(i->first);
+ if ((u) && (i->second) && (ext.get(u)))
+ u->Write(line);
+ }
+
+ // Now consider sending it to all other users who has at least a common channel with the user
+ std::set<User*> already_sent;
+ for (UCListIter i = chans.begin(); i != chans.end(); ++i)
+ {
+ const UserMembList* userlist = (*i)->GetUsers();
+ for (UserMembList::const_iterator m = userlist->begin(); m != userlist->end(); ++m)
+ {
+ /*
+ * Send the line if the channel member in question meets all of the following criteria:
+ * - local
+ * - not the user who is doing the action (i.e. whose channels we're iterating)
+ * - has the given extension
+ * - not on the except list built by modules
+ * - we haven't sent the line to the member yet
+ *
+ */
+ LocalUser* member = IS_LOCAL(m->first);
+ if ((member) && (member != user) && (ext.get(member)) && (exceptions.find(member) == exceptions.end()) && (already_sent.insert(member).second))
+ member->Write(line);
+ }
+ }
+ }
+
+ public:
+ ModuleIRCv3() : cap_accountnotify(this, "account-notify"),
+ cap_awaynotify(this, "away-notify"),
+ cap_extendedjoin(this, "extended-join")
+ {
+ OnRehash(NULL);
+ Implementation eventlist[] = { I_OnUserJoin, I_OnSetAway, I_OnEvent };
+ ServerInstance->Modules->Attach(eventlist, this, 3);
+ }
+
+ void OnRehash(User* user)
+ {
+ ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3");
+ accountnotify = conf->getBool("accoutnotify", true);
+ awaynotify = conf->getBool("awaynotify", true);
+ extendedjoin = conf->getBool("extendedjoin", true);
+ }
+
+ void OnEvent(Event& ev)
+ {
+ if (awaynotify)
+ cap_awaynotify.HandleEvent(ev);
+ if (extendedjoin)
+ cap_extendedjoin.HandleEvent(ev);
+
+ if (accountnotify)
+ {
+ cap_accountnotify.HandleEvent(ev);
+
+ if (ev.id == "account_login")
+ {
+ AccountEvent* ae = static_cast<AccountEvent*>(&ev);
+
+ // :nick!user@host ACCOUNT account
+ // or
+ // :nick!user@host ACCOUNT *
+ std::string line = ":" + ae->user->GetFullHost() + " ACCOUNT ";
+ if (ae->account.empty())
+ line += "*";
+ else
+ line += std::string(ae->account);
+
+ WriteNeighboursWithExt(ae->user, line, cap_accountnotify.ext);
+ }
+ }
+ }
+
+ void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts)
+ {
+ if (!extendedjoin)
+ return;
+
+ /*
+ * Send extended joins to clients who have the extended-join capability.
+ * An extended join looks like this:
+ *
+ * :nick!user@host JOIN #chan account :realname
+ *
+ * account is the joining user's account if he's logged in, otherwise it's an asterisk (*).
+ */
+
+ std::string line;
+ std::string mode;
+
+ const UserMembList* userlist = memb->chan->GetUsers();
+ for (UserMembCIter it = userlist->begin(); it != userlist->end(); ++it)
+ {
+ // Send the extended join line if the current member is local, has the extended-join cap and isn't excepted
+ User* member = IS_LOCAL(it->first);
+ if ((member) && (cap_extendedjoin.ext.get(member)) && (excepts.find(member) == excepts.end()))
+ {
+ // Construct the lines we're going to send if we haven't constructed them already
+ if (line.empty())
+ {
+ bool has_account = false;
+ line = ":" + memb->user->GetFullHost() + " JOIN " + memb->chan->name + " ";
+ const AccountExtItem* accountext = GetAccountExtItem();
+ if (accountext)
+ {
+ std::string* accountname;
+ accountname = accountext->get(memb->user);
+ if (accountname)
+ {
+ line += *accountname;
+ has_account = true;
+ }
+ }
+
+ if (!has_account)
+ line += "*";
+
+ line += " :" + memb->user->fullname;
+
+ // If the joining user received privileges from another module then we must send them as well,
+ // since silencing the normal join means the MODE will be silenced as well
+ if (!memb->modes.empty())
+ {
+ const std::string& modefrom = ServerInstance->Config->CycleHostsFromUser ? memb->user->GetFullHost() : ServerInstance->Config->ServerName;
+ mode = ":" + modefrom + " MODE " + memb->chan->name + " +" + memb->modes;
+
+ for (unsigned int i = 0; i < memb->modes.length(); i++)
+ mode += " " + memb->user->nick;
+ }
+ }
+
+ // Write the JOIN and the MODE, if any
+ member->Write(line);
+ if ((!mode.empty()) && (member != memb->user))
+ member->Write(mode);
+
+ // Prevent the core from sending the JOIN and MODE to this user
+ excepts.insert(it->first);
+ }
+ }
+ }
+
+ ModResult OnSetAway(User* user, const std::string &awaymsg)
+ {
+ if (awaynotify)
+ {
+ // Going away: n!u@h AWAY :reason
+ // Back from away: n!u@h AWAY
+ std::string line = ":" + user->GetFullHost() + " AWAY";
+ if (!awaymsg.empty())
+ line += " :" + awaymsg;
+
+ WriteNeighboursWithExt(user, line, cap_awaynotify.ext);
+ }
+ return MOD_RES_PASSTHRU;
+ }
+
+ void Prioritize()
+ {
+ ServerInstance->Modules->SetPriority(this, I_OnUserJoin, PRIORITY_LAST);
+ }
+
+ Version GetVersion()
+ {
+ return Version("Provides support for extended-join, away-notify and account-notify CAP capabilities", VF_VENDOR);
+ }
+};
+
+MODULE_INIT(ModuleIRCv3)
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index 1ab824388..2603b0ce5 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -31,8 +31,8 @@ class ModuleNamesX : public Module
GenericCap cap;
ModuleNamesX() : cap(this, "multi-prefix")
{
- Implementation eventlist[] = { I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent };
- ServerInstance->Modules->Attach(eventlist, this, 4);
+ Implementation eventlist[] = { I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent, I_OnSendWhoLine };
+ ServerInstance->Modules->Attach(eventlist, this, 5);
}
@@ -81,6 +81,41 @@ class ModuleNamesX : public Module
prefixes = memb->chan->GetAllPrefixChars(memb->user);
}
+ void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line)
+ {
+ if (!cap.ext.get(source) || line.empty())
+ return;
+
+ std::string::size_type pos = line.find(':');
+ if (pos == std::string::npos || pos < 2)
+ return;
+ pos -= 2;
+ // Don't do anything if the user has no prefixes
+ if ((line[pos] == 'H') || (line[pos] == 'G') || (line[pos] == '*'))
+ return;
+
+ // 352 21DAAAAAB #chan ident localhost insp21.test 21DAAAAAB H@ :0 a
+ // a b pos
+ std::string::size_type a = 4 + source->nick.length() + 1;
+ std::string::size_type b = line.find(' ', a);
+ if (b == std::string::npos)
+ return;
+
+ // Try to find this channel
+ std::string channame = line.substr(a, b-a);
+ Channel* chan = ServerInstance->FindChan(channame.c_str());
+ if (!chan)
+ return;
+
+ // Don't do anything if the user has only one prefix
+ std::string prefixes = chan->GetAllPrefixChars(user);
+ if (prefixes.length() <= 1)
+ return;
+
+ line.erase(pos, 1);
+ line.insert(pos, prefixes);
+ }
+
void OnEvent(Event& ev)
{
cap.HandleEvent(ev);
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index 7f3c54907..cd34e955a 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -277,6 +277,10 @@ class ModuleServicesAccount : public Module
AccountEvent(this, dest, *account).Send();
}
+ else
+ {
+ AccountEvent(this, dest, "").Send();
+ }
}
}
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 1067852d1..f639a748d 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -765,7 +765,21 @@ void ModuleSpanningTree::OnPreRehash(User* user, const std::string &parameter)
void ModuleSpanningTree::OnRehash(User* user)
{
// Re-read config stuff
- Utils->ReadConfiguration();
+ try
+ {
+ Utils->ReadConfiguration();
+ }
+ catch (ModuleException& e)
+ {
+ // Refresh the IP cache anyway, so servers read before the error will be allowed to connect
+ Utils->RefreshIPCache();
+ // Always warn local opers with snomask +l, also warn globally (snomask +L) if the rehash was issued by a remote user
+ std::string msg = "Error in configuration: ";
+ msg.append(e.GetReason());
+ ServerInstance->SNO->WriteToSnoMask('l', msg);
+ if (!IS_LOCAL(user))
+ ServerInstance->PI->SendSNONotice("L", msg);
+ }
}
void ModuleSpanningTree::OnLoadModule(Module* mod)
diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp
index ae951bd38..b69c5c29e 100644
--- a/src/modules/m_spanningtree/resolvers.cpp
+++ b/src/modules/m_spanningtree/resolvers.cpp
@@ -80,3 +80,33 @@ void ServernameResolver::OnError(ResolverError e, const std::string &errormessag
Utils->Creator->ConnectServer(myautoconnect, false);
}
+SecurityIPResolver::SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt)
+ : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt)
+{
+}
+
+void SecurityIPResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
+{
+ for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i != Utils->LinkBlocks.end(); ++i)
+ {
+ Link* L = *i;
+ if (L->IPAddr == host)
+ {
+ Utils->ValidIPs.push_back(result);
+ break;
+ }
+ }
+}
+
+void SecurityIPResolver::OnError(ResolverError e, const std::string &errormessage)
+{
+ if (query == DNS_QUERY_AAAA)
+ {
+ bool cached;
+ SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A);
+ ServerInstance->AddResolver(res, cached);
+ return;
+ }
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s",
+ MyLink->Name.c_str(),errormessage.c_str());
+}
diff --git a/src/modules/m_spanningtree/resolvers.h b/src/modules/m_spanningtree/resolvers.h
index cb3b38516..65b9e7249 100644
--- a/src/modules/m_spanningtree/resolvers.h
+++ b/src/modules/m_spanningtree/resolvers.h
@@ -39,28 +39,9 @@ class SecurityIPResolver : public Resolver
std::string host;
QueryType query;
public:
- SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt)
- : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt)
- {
- }
-
- void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
- {
- Utils->ValidIPs.push_back(result);
- }
-
- void OnError(ResolverError e, const std::string &errormessage)
- {
- if (query == DNS_QUERY_AAAA)
- {
- bool cached;
- SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A);
- ServerInstance->AddResolver(res, cached);
- return;
- }
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s",
- MyLink->Name.c_str(),errormessage.c_str());
- }
+ SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt);
+ void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached);
+ void OnError(ResolverError e, const std::string &errormessage);
};
/** This class is used to resolve server hostnames during /connect and autoconnect.
diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp
index 1b13fb2da..64c32e8fb 100644
--- a/src/modules/m_spanningtree/server.cpp
+++ b/src/modules/m_spanningtree/server.cpp
@@ -163,15 +163,15 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
linkID = sname;
MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
-
Utils->TreeRoot->AddChild(MyRoot);
+ this->DoBurst(MyRoot);
+
params[4] = ":" + params[4];
/* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */
params[1] = "*";
Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname);
- this->DoBurst(MyRoot);
return true;
}
@@ -259,10 +259,6 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
Utils->TreeRoot->AddChild(MyRoot);
- params[1] = "*";
- params[4] = ":" + params[4];
- Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname);
-
this->LinkState = WAIT_AUTH_2;
return true;
}
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index 673b05c55..dcb35af31 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -183,10 +183,14 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
{
DelServerEvent(Utils->Creator, Current->GetName());
- parameterlist params;
- params.push_back(Current->GetName());
- params.push_back(":"+reason);
- Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName());
+ if (!Current->GetSocket() || Current->GetSocket()->GetLinkState() == CONNECTED)
+ {
+ parameterlist params;
+ params.push_back(Current->GetName());
+ params.push_back(":"+reason);
+ Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName());
+ }
+
if (Current->GetParent() == Utils->TreeRoot)
{
ServerInstance->SNO->WriteGlobalSno('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp
index 4582eb4c5..cb49d92c9 100644
--- a/src/modules/m_spanningtree/treesocket2.cpp
+++ b/src/modules/m_spanningtree/treesocket2.cpp
@@ -165,12 +165,19 @@ void TreeSocket::ProcessLine(std::string &line)
}
}
this->LinkState = CONNECTED;
-
Utils->timeoutlist.erase(this);
- parameterlist sparams;
- Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName());
+
MyRoot->bursting = true;
this->DoBurst(MyRoot);
+
+ parameterlist sparams;
+ sparams.push_back(MyRoot->GetName());
+ sparams.push_back("*");
+ sparams.push_back("0");
+ sparams.push_back(MyRoot->GetID());
+ sparams.push_back(":" + MyRoot->GetDesc());
+ Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(), "SERVER", sparams, MyRoot->GetName());
+ Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName());
}
else if (command == "ERROR")
{
diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp
index 67a21a484..0a8f4dbfc 100644
--- a/src/modules/m_spanningtree/uid.cpp
+++ b/src/modules/m_spanningtree/uid.cpp
@@ -154,7 +154,7 @@ CmdResult CommandUID::Handle(const parameterlist &params, User* serversrc)
dosend = false;
if (dosend)
- ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
+ ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s (%s) [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
FOREACH_MOD(I_OnPostConnect,OnPostConnect(_new));
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index ec9d5aacc..75d4eaca3 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -319,17 +319,9 @@ void SpanningTreeUtilities::RefreshIPCache()
for (std::vector<reference<Link> >::iterator i = LinkBlocks.begin(); i != LinkBlocks.end(); ++i)
{
Link* L = *i;
- if (L->IPAddr.empty() || L->RecvPass.empty() || L->SendPass.empty() || L->Name.empty() || !L->Port)
+ if (!L->Port)
{
- if (L->Name.empty())
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a malformed link block (all link blocks require a name!)");
- }
- else
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block missing recvpass, sendpass, port or ipaddr.");
- }
-
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block without a port.");
/* Invalid link block */
continue;
}
@@ -339,7 +331,7 @@ void SpanningTreeUtilities::RefreshIPCache()
irc::sockets::sockaddrs dummy;
bool ipvalid = irc::sockets::aptosa(L->IPAddr, L->Port, dummy);
- if (ipvalid)
+ if ((L->IPAddr == "*") || (ipvalid))
ValidIPs.push_back(L->IPAddr);
else
{
@@ -377,7 +369,6 @@ void SpanningTreeUtilities::ReadConfiguration()
AutoconnectBlocks.clear();
LinkBlocks.clear();
- ValidIPs.clear();
ConfigTagList tags = ServerInstance->Config->ConfTags("link");
for(ConfigIter i = tags.first; i != tags.second; ++i)
{
@@ -396,55 +387,37 @@ void SpanningTreeUtilities::ReadConfiguration()
L->Bind = tag->getString("bind");
L->Hidden = tag->getBool("hidden");
+ if (L->Name.empty())
+ throw ModuleException("Invalid configuration, found a link tag without a name!" + (!L->IPAddr.empty() ? " IP address: "+L->IPAddr : ""));
+
if (L->Name.find('.') == std::string::npos)
- throw CoreException("The link name '"+assign(L->Name)+"' is invalid and must contain at least one '.' character");
+ throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it must contain at least one '.' character");
if (L->Name.length() > 64)
- throw CoreException("The link name '"+assign(L->Name)+"' is longer than 64 characters!");
+ throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it is longer than 64 characters");
- if (L->Fingerprint.find(':') != std::string::npos)
- {
- std::string tmp = L->Fingerprint;
- L->Fingerprint.clear();
- for(unsigned int j=0; j < tmp.length(); j++)
- if (tmp[j] != ':')
- L->Fingerprint.push_back(tmp[j]);
- }
+ if (L->RecvPass.empty())
+ throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined");
- if ((!L->IPAddr.empty()) && (!L->RecvPass.empty()) && (!L->SendPass.empty()) && (!L->Name.empty()) && (L->Port))
- {
- ValidIPs.push_back(L->IPAddr);
- }
- else
- {
- if (L->IPAddr.empty())
- {
- L->IPAddr = "*";
- ValidIPs.push_back("*");
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want.");
- }
+ if (L->SendPass.empty())
+ throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined");
- if (L->RecvPass.empty())
- {
- throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined!");
- }
+ if ((L->SendPass.find(' ') != std::string::npos) || (L->RecvPass.find(' ') != std::string::npos))
+ throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that contains a space character which is invalid");
- if (L->SendPass.empty())
- {
- throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined!");
- }
+ if ((L->SendPass[0] == ':') || (L->RecvPass[0] == ':'))
+ throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that begins with a colon (:) which is invalid");
- if (L->Name.empty())
- {
- throw CoreException("Invalid configuration, link tag without a name! IP address: "+L->IPAddr);
- }
-
- if (!L->Port)
- {
- ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no port defined, you will not be able to /connect it.");
- }
+ if (L->IPAddr.empty())
+ {
+ L->IPAddr = "*";
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want.");
}
+ if (!L->Port)
+ ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no port defined, you will not be able to /connect it.");
+
+ L->Fingerprint.erase(std::remove(L->Fingerprint.begin(), L->Fingerprint.end(), ':'), L->Fingerprint.end());
LinkBlocks.push_back(L);
}
@@ -465,12 +438,12 @@ void SpanningTreeUtilities::ReadConfiguration()
if (A->Period <= 0)
{
- throw CoreException("Invalid configuration for autoconnect, period not a positive integer!");
+ throw ModuleException("Invalid configuration for autoconnect, period not a positive integer!");
}
if (A->servers.empty())
{
- throw CoreException("Invalid configuration for autoconnect, server cannot be empty!");
+ throw ModuleException("Invalid configuration for autoconnect, server cannot be empty!");
}
AutoconnectBlocks.push_back(A);
diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp
index aab506fdc..cd4f35c4b 100644
--- a/src/modules/m_stripcolor.cpp
+++ b/src/modules/m_stripcolor.cpp
@@ -75,7 +75,7 @@ class ModuleStripColor : public Module
std::string::iterator i,safei;
for (i = sentence.begin(); i != sentence.end();)
{
- if ((*i == 3))
+ if (*i == 3)
seq = 1;
else if (seq && (( ((*i >= '0') && (*i <= '9')) || (*i == ',') ) ))
{
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index e74f7dadc..7da57646f 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -213,7 +213,7 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
/*
* this must come before the ServerInstance->SNO->WriteToSnoMaskso that it doesnt try to fill their buffer with anything
- * if they were an oper with +sn +qQ.
+ * if they were an oper with +s +qQ.
*/
if (user->registered == REG_ALL)
{
@@ -221,16 +221,16 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
{
if (!user->quietquit)
{
- ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s!%s@%s [%s] (%s)",
- user->nick.c_str(), user->ident.c_str(), user->host.c_str(), oper_reason.c_str(), user->GetIPString());
+ ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s!%s@%s (%s) [%s]",
+ user->nick.c_str(), user->ident.c_str(), user->host.c_str(), user->GetIPString(), oper_reason.c_str());
}
}
else
{
if ((!ServerInstance->SilentULine(user->server)) && (!user->quietquit))
{
- ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s!%s@%s [%s] (%s)",
- user->server.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str(), oper_reason.c_str(), user->GetIPString());
+ ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s!%s@%s (%s) [%s]",
+ user->server.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str(), user->GetIPString(), oper_reason.c_str());
}
}
user->AddToWhoWas();
diff --git a/src/users.cpp b/src/users.cpp
index 2ee389c86..39be81272 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -224,7 +224,8 @@ LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::so
{
lastping = 0;
eh.SetFd(myfd);
- memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs));
+
+ SetClientIP(client);
memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs));
}
@@ -841,7 +842,7 @@ void LocalUser::FullConnect()
FOREACH_MOD(I_OnPostConnect,OnPostConnect(this));
- ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d (class %s): %s!%s@%s [%s] [%s]",
+ ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d (class %s): %s!%s@%s (%s) [%s]",
this->GetServerPort(), this->MyClass->name.c_str(), this->nick.c_str(), this->ident.c_str(), this->host.c_str(), this->GetIPString(), this->fullname.c_str());
ServerInstance->Logs->Log("BANCACHE", DEBUG, "BanCache: Adding NEGATIVE hit for %s", this->GetIPString());
ServerInstance->BanCache->AddHit(this->GetIPString(), "", "");
@@ -1008,10 +1009,24 @@ irc::sockets::cidr_mask User::GetCIDRMask()
return irc::sockets::cidr_mask(client_sa, range);
}
+bool User::SetClientIP(irc::sockets::sockaddrs *sa)
+{
+ memcpy(&client_sa, sa, sizeof(irc::sockets::sockaddrs));
+
+ FOREACH_MOD(I_OnSetClientIP, OnSetClientIP(this));
+
+ return true;
+}
+
bool User::SetClientIP(const char* sip)
{
+ irc::sockets::sockaddrs sa;
+
this->cachedip = "";
- return irc::sockets::aptosa(sip, 0, client_sa);
+ if (!irc::sockets::aptosa(sip, 0, sa))
+ return false;
+
+ return SetClientIP(&sa);
}
static std::string wide_newline("\r\n");
diff --git a/win/configure.cpp b/win/configure.cpp
index 29b88d780..ee03b3659 100644
--- a/win/configure.cpp
+++ b/win/configure.cpp
@@ -61,7 +61,7 @@ int get_int_option(const char * text, int def)
static char buffer[500];
int ret;
printf_c("%s\n[\033[1;32m%u\033[0m] -> ", text, def);
- fgets(buffer, 500, stdin);
+ fgets(buffer, sizeof(buffer), stdin);
if(sscanf(buffer, "%u", &ret) != 1)
ret = def;
@@ -74,7 +74,7 @@ bool get_bool_option(const char * text, bool def)
static char buffer[500];
char ret[100];
printf_c("%s [\033[1;32m%c\033[0m] -> ", text, def ? 'y' : 'n');
- fgets(buffer, 500, stdin);
+ fgets(buffer, sizeof(buffer), stdin);
if(sscanf(buffer, "%s", ret) != 1)
strcpy(ret, def ? "y" : "n");
@@ -159,7 +159,7 @@ void get_machine_info(char * buffer, size_t len)
FILE * f = fopen("ver.txt.tmp", "r");
if (f)
{
- while (fgets(buf2, 500, f)) { }
+ while (fgets(buf2, sizeof(buf2), f)) { }
fclose(f);
unlink("ver.txt.tmp");
}
@@ -261,8 +261,8 @@ void Run()
FILE * fI = fopen("..\\src\\version.sh", "r");
if(fI)
{
- fgets(version, 514, fI);
- fgets(version, 514, fI);
+ fgets(version, sizeof(version), fI);
+ fgets(version, sizeof(version), fI);
char * p2 = version;
while(*p2 != '\"')
++p2;