summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h7
-rw-r--r--include/snomasks.h10
-rw-r--r--include/users.h7
-rw-r--r--src/inspircd.cpp1
-rw-r--r--src/modes/umode_n.cpp10
-rw-r--r--src/modules/m_globops.cpp46
-rw-r--r--src/snomasks.cpp59
-rw-r--r--src/users.cpp28
8 files changed, 115 insertions, 53 deletions
diff --git a/include/inspircd.h b/include/inspircd.h
index 965cf44fc..dfc36a720 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -25,9 +25,9 @@
#include "channels.h"
#include "socket.h"
#include "mode.h"
-
#include "socketengine.h"
#include "command_parse.h"
+#include "snomasks.h"
/** Returned by some functions to indicate failure,
* and the exit code of the program if it terminates.
@@ -373,6 +373,11 @@ class InspIRCd : public classbase
*/
ServerConfig* Config;
+ /** Snomask manager - handles routing of snomask messages
+ * to opers.
+ */
+ SnomaskManager* SNO;
+
/** Client list, a hash_map containing all clients, local and remote
*/
user_hash clientlist;
diff --git a/include/snomasks.h b/include/snomasks.h
index ab8980c26..a6ee0d050 100644
--- a/include/snomasks.h
+++ b/include/snomasks.h
@@ -19,18 +19,26 @@
#include <string>
#include <vector>
+#include <map>
#include "configreader.h"
#include "inspircd.h"
+typedef std::map<char, std::string> SnoList;
+
class SnomaskManager : public Extensible
{
private:
InspIRCd* ServerInstance;
+ SnoList SnoMasks;
public:
SnomaskManager(InspIRCd* Instance);
~SnomaskManager();
-
+ bool EnableSnomask(char letter, const std::string &description);
+ bool DisableSnomask(char letter);
+ void WriteToSnoMask(char letter, const std::string &text);
+ void WriteToSnoMask(char letter, const char* text, ...);
+ bool IsEnabled(char letter);
};
#endif
diff --git a/include/users.h b/include/users.h
index 83ea9bf3f..731cb785a 100644
--- a/include/users.h
+++ b/include/users.h
@@ -46,6 +46,7 @@ enum UserModes {
UM_WALLOPS = 'w'-65,
UM_INVISIBLE = 'i'-65,
UM_OPERATOR = 'o'-65,
+ UM_SNOMASK = 'n'-65,
};
enum RegistrationState {
@@ -372,9 +373,11 @@ class userrec : public connection
/** Process a snomask modifier string, e.g. +abc-de
* @param sm A sequence of notice mask characters
- * @return True if the notice masks were successfully applied
+ * @return The cleaned mode sequence which can be output,
+ * e.g. in the above example if masks c and e are not
+ * valid, this function will return +ab-d
*/
- bool userrec::ProcessNoticeMasks(const char *sm);
+ std::string userrec::ProcessNoticeMasks(const char *sm);
/** Returns true if a notice mask is set
* @param sm A notice mask character to check
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 79ae8b7bc..328306744 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -183,6 +183,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
factory.resize(255);
this->Config = new ServerConfig(this);
+ this->SNO = new SnomaskManager(this);
this->Start();
this->TIME = this->OLDTIME = this->startup_time = time(NULL);
srand(this->TIME);
diff --git a/src/modes/umode_n.cpp b/src/modes/umode_n.cpp
index e3370fa56..7bb8dbbf0 100644
--- a/src/modes/umode_n.cpp
+++ b/src/modes/umode_n.cpp
@@ -15,12 +15,18 @@ ModeAction ModeUserServerNoticeMask::OnModeChange(userrec* source, userrec* dest
return MODEACTION_DENY;
/* Set the bitfields */
- if (dest->modes[UM_SERVERNOTICE] != adding)
+ if (adding)
{
- dest->modes[UM_SERVERNOTICE] = adding;
+ parameter = dest->ProcessNoticeMasks(parameter.c_str());
+ return MODEACTION_ALLOW;
+ }
+ else if (dest->modes[UM_SNOMASK] != false)
+ {
+ dest->modes[UM_SNOMASK] = false;
return MODEACTION_ALLOW;
}
/* Allow the change */
return MODEACTION_DENY;
}
+
diff --git a/src/modules/m_globops.cpp b/src/modules/m_globops.cpp
index 77a35294a..f0a879d4b 100644
--- a/src/modules/m_globops.cpp
+++ b/src/modules/m_globops.cpp
@@ -32,76 +32,44 @@ using namespace std;
class cmd_globops : public command_t
{
public:
- cmd_globops (InspIRCd* Instance) : command_t(Instance,"GLOBOPS",'o',1)
+ cmd_globops (InspIRCd* Instance) : command_t(Instance,"GLOBOPS",'o',1)
{
this->source = "m_globops.so";
syntax = "<any-text>";
}
-
+
void Handle (const char** parameters, int pcnt, userrec *user)
{
- std::string line = "*** GLOBOPS - From " + std::string(user->nick) + ": ";
+ std::string line = "From " + std::string(user->nick) + ": ";
for (int i = 0; i < pcnt; i++)
{
line = line + std::string(parameters[i]) + " ";
}
- ServerInstance->WriteMode("og",WM_AND,line.c_str());
+ ServerInstance->SNO->WriteToSnoMask('g',line);
}
};
-class ModeGlobops : public ModeHandler
-{
- public:
- ModeGlobops(InspIRCd* Instance) : ModeHandler(Instance, 'g', 0, 0, false, MODETYPE_USER, true) { }
-
- ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
- {
- if (adding)
- {
- if (!dest->IsModeSet('g'))
- {
- dest->SetMode('P',true);
- return MODEACTION_ALLOW;
- }
- }
- else
- {
- if (dest->IsModeSet('g'))
- {
- dest->SetMode('P',false);
- return MODEACTION_ALLOW;
- }
- }
-
- return MODEACTION_DENY;
- }
-};
-
-
class ModuleGlobops : public Module
{
cmd_globops* mycommand;
- ModeGlobops* mg;
public:
ModuleGlobops(InspIRCd* Me)
: Module::Module(Me)
{
-
- mg = new ModeGlobops(ServerInstance);
- ServerInstance->AddMode(mg, 'g');
mycommand = new cmd_globops(ServerInstance);
ServerInstance->AddCommand(mycommand);
+ ServerInstance->SNO->EnableSnomask('g',"GLOBOPS");
}
virtual ~ModuleGlobops()
{
+ ServerInstance->SNO->DisableSnomask('g');
DELETE(mycommand);
- DELETE(mg);
}
virtual Version GetVersion()
{
- return Version(1,0,0,1,VF_STATIC|VF_VENDOR);
+ return Version(1,0,0,1,VF_VENDOR);
}
void Implements(char* List)
diff --git a/src/snomasks.cpp b/src/snomasks.cpp
index 6750ebcc6..650403a53 100644
--- a/src/snomasks.cpp
+++ b/src/snomasks.cpp
@@ -16,6 +16,7 @@
#include <string>
#include <vector>
+#include <stdarg.h>
#include "configreader.h"
#include "users.h"
#include "modules.h"
@@ -25,9 +26,67 @@
SnomaskManager::SnomaskManager(InspIRCd* Instance) : ServerInstance(Instance)
{
+ SnoMasks.clear();
}
SnomaskManager::~SnomaskManager()
{
}
+bool SnomaskManager::EnableSnomask(char letter, const std::string &type)
+{
+ if (SnoMasks.find(letter) == SnoMasks.end())
+ {
+ SnoMasks[letter] = type;
+ return true;
+ }
+ return false;
+}
+
+bool SnomaskManager::DisableSnomask(char letter)
+{
+ SnoList::iterator n = SnoMasks.find(letter);
+ if (n != SnoMasks.end())
+ {
+ SnoMasks.erase(n);
+ return true;
+ }
+ return false;
+}
+
+void SnomaskManager::WriteToSnoMask(char letter, const std::string &text)
+{
+ /* Only send to snomask chars which are enabled */
+ SnoList::iterator n = SnoMasks.find(letter);
+ if (n != SnoMasks.end())
+ {
+ /* Only opers can receive snotices, so we iterate the oper list */
+ for (std::vector<userrec*>::iterator i = ServerInstance->all_opers.begin(); i != ServerInstance->all_opers.end(); i++)
+ {
+ userrec* a = *i;
+ if (IS_LOCAL(a) && a->modes[UM_SERVERNOTICE] && a->modes[UM_SNOMASK] && a->IsNoticeMaskSet(n->first))
+ {
+ /* send server notices to all with +ns */
+ a->WriteServ("NOTICE %s :*** %s: %s",a->nick, n->second.c_str(), text.c_str());
+ }
+ }
+ }
+}
+
+void SnomaskManager::WriteToSnoMask(char letter, const char* text, ...)
+{
+ char textbuffer[MAXBUF];
+ va_list argsPtr;
+
+ va_start(argsPtr, text);
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+
+ this->WriteToSnoMask(letter, std::string(textbuffer));
+}
+
+bool SnomaskManager::IsEnabled(char letter)
+{
+ return (SnoMasks.find(letter) != SnoMasks.end());
+}
+
diff --git a/src/users.cpp b/src/users.cpp
index 09a8c37a5..27eb0a1f6 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -92,10 +92,11 @@ bool DoneClassesAndTypes(ServerConfig* conf, const char* tag)
return true;
}
-bool userrec::ProcessNoticeMasks(const char *sm)
+std::string userrec::ProcessNoticeMasks(const char *sm)
{
- bool adding = true;
+ bool adding = true, oldadding = false;
const char *c = sm;
+ std::string output = "";
while (c && *c)
{
@@ -103,20 +104,31 @@ bool userrec::ProcessNoticeMasks(const char *sm)
{
case '+':
adding = true;
- break;
+ break;
case '-':
adding = false;
- break;
+ break;
default:
- if ((*c >= 'A') && (*c <= 'z'))
- this->SetNoticeMask(*c, adding);
- break;
+ if ((*c >= 'A') && (*c <= 'z') && (ServerInstance->SNO->IsEnabled(*c)))
+ {
+ if ((IsNoticeMaskSet(*c) && adding) || (!IsNoticeMaskSet(*c) && !adding))
+ {
+ if ((oldadding != adding) || (sm == c))
+ output += (adding ? '+' : '-');
+
+ this->SetNoticeMask(*c, adding);
+
+ output += *c;
+ }
+ }
+ oldadding = adding;
+ break;
}
*c++;
}
- return true;
+ return output;
}
void userrec::StartDNSLookup()