summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd_io.h7
-rw-r--r--src/inspircd_io.cpp62
-rw-r--r--src/message.cpp30
3 files changed, 55 insertions, 44 deletions
diff --git a/include/inspircd_io.h b/include/inspircd_io.h
index d3eaecfa9..531026778 100644
--- a/include/inspircd_io.h
+++ b/include/inspircd_io.h
@@ -256,6 +256,11 @@ class ServerConfig : public classbase
*/
bool HideBans;
+ /** If this is enabled then operators will
+ * see invisible (+i) channels in /whois.
+ */
+ bool OperSpyWhois;
+
/** Set to a non-empty string to obfuscate the server name of users in WHOIS
*/
char HideWhoisServer[MAXBUF];
@@ -322,7 +327,7 @@ class ServerConfig : public classbase
* only to operators.
*/
char OperOnlyStats[MAXBUF];
-
+
/** The path and filename of the ircd.log file
*/
std::string logpath;
diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp
index 328d7c67e..a405ed4bf 100644
--- a/src/inspircd_io.cpp
+++ b/src/inspircd_io.cpp
@@ -523,36 +523,37 @@ void ServerConfig::Read(bool bail, userrec* user)
/* These tags can occur ONCE or not at all */
static InitialConfig Values[] = {
- {"options", "softlimit", &this->SoftLimit, DT_INTEGER, ValidateSoftLimit},
- {"options", "somaxconn", &this->MaxConn, DT_INTEGER, ValidateMaxConn},
- {"server", "name", &this->ServerName, DT_CHARPTR, ValidateServerName},
- {"server", "description", &this->ServerDesc, DT_CHARPTR, NoValidation},
- {"server", "network", &this->Network, DT_CHARPTR, NoValidation},
- {"admin", "name", &this->AdminName, DT_CHARPTR, NoValidation},
- {"admin", "email", &this->AdminEmail, DT_CHARPTR, NoValidation},
- {"admin", "nick", &this->AdminNick, DT_CHARPTR, NoValidation},
- {"files", "motd", &this->motd, DT_CHARPTR, ValidateMotd},
- {"files", "rules", &this->rules, DT_CHARPTR, ValidateRules},
- {"power", "diepass", &this->diepass, DT_CHARPTR, NoValidation},
- {"power", "pauseval", &this->DieDelay, DT_INTEGER, NoValidation},
- {"power", "restartpass", &this->restartpass, DT_CHARPTR, NoValidation},
- {"options", "prefixquit", &this->PrefixQuit, DT_CHARPTR, NoValidation},
- {"die", "value", &this->DieValue, DT_CHARPTR, NoValidation},
- {"options", "loglevel", &debug, DT_CHARPTR, ValidateLogLevel},
- {"options", "netbuffersize", &this->NetBufferSize, DT_INTEGER, ValidateNetBufferSize},
- {"options", "maxwho", &this->MaxWhoResults, DT_INTEGER, ValidateMaxWho},
- {"options", "allowhalfop", &this->AllowHalfop, DT_BOOLEAN, NoValidation},
- {"dns", "server", &this->DNSServer, DT_CHARPTR, ValidateDnsServer},
- {"dns", "timeout", &this->dns_timeout, DT_INTEGER, ValidateDnsTimeout},
- {"options", "moduledir", &this->ModPath, DT_CHARPTR, ValidateModPath},
- {"disabled", "commands", &this->DisabledCommands, DT_CHARPTR, NoValidation},
- {"options", "operonlystats", &this->OperOnlyStats, DT_CHARPTR, NoValidation},
- {"options", "customversion", &this->CustomVersion, DT_CHARPTR, NoValidation},
- {"options", "hidesplits", &this->HideSplits, DT_BOOLEAN, NoValidation},
- {"options", "hidebans", &this->HideBans, DT_BOOLEAN, NoValidation},
- {"options", "hidewhois", &this->HideWhoisServer, DT_CHARPTR, NoValidation},
- {"options", "tempdir", &this->TempDir, DT_CHARPTR, ValidateTempDir},
- {"pid", "file", &this->PID, DT_CHARPTR, NoValidation},
+ {"options", "softlimit", &this->SoftLimit, DT_INTEGER, ValidateSoftLimit},
+ {"options", "somaxconn", &this->MaxConn, DT_INTEGER, ValidateMaxConn},
+ {"server", "name", &this->ServerName, DT_CHARPTR, ValidateServerName},
+ {"server", "description", &this->ServerDesc, DT_CHARPTR, NoValidation},
+ {"server", "network", &this->Network, DT_CHARPTR, NoValidation},
+ {"admin", "name", &this->AdminName, DT_CHARPTR, NoValidation},
+ {"admin", "email", &this->AdminEmail, DT_CHARPTR, NoValidation},
+ {"admin", "nick", &this->AdminNick, DT_CHARPTR, NoValidation},
+ {"files", "motd", &this->motd, DT_CHARPTR, ValidateMotd},
+ {"files", "rules", &this->rules, DT_CHARPTR, ValidateRules},
+ {"power", "diepass", &this->diepass, DT_CHARPTR, NoValidation},
+ {"power", "pauseval", &this->DieDelay, DT_INTEGER, NoValidation},
+ {"power", "restartpass", &this->restartpass, DT_CHARPTR, NoValidation},
+ {"options", "prefixquit", &this->PrefixQuit, DT_CHARPTR, NoValidation},
+ {"die", "value", &this->DieValue, DT_CHARPTR, NoValidation},
+ {"options", "loglevel", &debug, DT_CHARPTR, ValidateLogLevel},
+ {"options", "netbuffersize", &this->NetBufferSize, DT_INTEGER, ValidateNetBufferSize},
+ {"options", "maxwho", &this->MaxWhoResults, DT_INTEGER, ValidateMaxWho},
+ {"options", "allowhalfop", &this->AllowHalfop, DT_BOOLEAN, NoValidation},
+ {"dns", "server", &this->DNSServer, DT_CHARPTR, ValidateDnsServer},
+ {"dns", "timeout", &this->dns_timeout, DT_INTEGER, ValidateDnsTimeout},
+ {"options", "moduledir", &this->ModPath, DT_CHARPTR, ValidateModPath},
+ {"disabled", "commands", &this->DisabledCommands,DT_CHARPTR, NoValidation},
+ {"options", "operonlystats", &this->OperOnlyStats, DT_CHARPTR, NoValidation},
+ {"options", "customversion", &this->CustomVersion, DT_CHARPTR, NoValidation},
+ {"options", "hidesplits", &this->HideSplits, DT_BOOLEAN, NoValidation},
+ {"options", "hidebans", &this->HideBans, DT_BOOLEAN, NoValidation},
+ {"options", "hidewhois", &this->HideWhoisServer, DT_CHARPTR, NoValidation},
+ {"options", "operspywhois", &this->OperSpyWhois, DT_BOOLEAN, NoValidation},
+ {"options", "tempdir", &this->TempDir, DT_CHARPTR, ValidateTempDir},
+ {"pid", "file", &this->PID, DT_CHARPTR, NoValidation},
{NULL}
};
@@ -1677,4 +1678,3 @@ int BindPorts(bool bail)
return BoundPortCount;
}
-
diff --git a/src/message.cpp b/src/message.cpp
index 0a41e5b8a..e9d634e76 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -400,29 +400,35 @@ char lst[MAXBUF];
std::string chlist(userrec *user,userrec* source)
{
- std::string cmp = "";
- std::string lst = "";
+ /* Should this be a stringstream? Not sure if it would be faster as streams are more oriented at appending stuff, which is all we do */
+ std::string lst;
+
if (!user || !source)
{
return lst;
}
- bool userinvisible = (user->modebits & UM_INVISIBLE);
+
for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
{
- if ((((ucrec*)(*i))->channel != NULL) && (((ucrec*)(*i))->channel->name))
+ ucrec* rec = *i;
+
+ if(rec->channel && rec->channel->name)
{
- cmp = std::string(((ucrec*)(*i))->channel->name) + " ";
- if (!strstr(lst.c_str(),cmp.c_str()))
- {
+ /* XXX - Why does this check need to be here at all? :< */
+ /* Commenting this out until someone finds a case where we need it */
+ //if (lst.find(rec->channel->name) == std::string::npos)
+ //{
// if the channel is NOT private/secret, OR the source user is on the channel, AND the user is not invisible.
- // if the user is the same as the source, shortcircuit the comparison.
- if ((source == user) || ((((!(((ucrec*)(*i))->channel->modes[CM_PRIVATE])) && (!(((ucrec*)(*i))->channel->modes[CM_SECRET])) && (!userinvisible)) || (((ucrec*)(*i))->channel->HasUser(source)))))
+ // if the user is the same as the source or is an oper, shortcircuit the comparison.
+ if ((source == user) || (*source->oper && Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET]) && !(user->modebits & UM_INVISIBLE)) || (rec->channel->HasUser(source))))
{
- lst = lst + std::string(cmode(user,((ucrec*)(*i))->channel)) + std::string(((ucrec*)(*i))->channel->name) + " ";
+ lst += cmode(user, rec->channel);
+ lst += rec->channel->name;
+ lst += " ";
}
- }
+ //}
}
}
+
return lst;
}
-