summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-13 20:30:25 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-13 20:30:25 +0000
commit6d57bbe05c31c79eaad02fe81cfb9c1ed6b79c58 (patch)
treee0c89ed36b00f4c2925d7f39c32a835657b0fa6e
parent7eea21b8d43b0d5993e88b62d9d4894c2af49303 (diff)
Change Extensible to use strongly typed entries
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11696 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/base.h118
-rw-r--r--include/extensible.h150
-rw-r--r--include/inspircd.h1
-rw-r--r--include/modules.h3
-rw-r--r--include/u_listmode.h62
-rw-r--r--include/users.h6
-rw-r--r--src/base.cpp155
-rw-r--r--src/commands/cmd_nick.cpp6
-rw-r--r--src/commands/cmd_quit.cpp5
-rw-r--r--src/commands/cmd_who.cpp3
-rw-r--r--src/dns.cpp1
-rw-r--r--src/inspsocket.cpp4
-rw-r--r--src/modules.cpp1
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp87
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp59
-rw-r--r--src/modules/m_antibear.cpp13
-rw-r--r--src/modules/m_banexception.cpp14
-rw-r--r--src/modules/m_banredirect.cpp30
-rw-r--r--src/modules/m_blockamsg.cpp28
-rw-r--r--src/modules/m_callerid.cpp144
-rw-r--r--src/modules/m_cap.cpp29
-rw-r--r--src/modules/m_cap.h65
-rw-r--r--src/modules/m_cgiirc.cpp97
-rw-r--r--src/modules/m_chanfilter.cpp8
-rw-r--r--src/modules/m_channelban.cpp8
-rw-r--r--src/modules/m_check.cpp40
-rw-r--r--src/modules/m_cloaking.cpp64
-rw-r--r--src/modules/m_conn_waitpong.cpp80
-rw-r--r--src/modules/m_customtitle.cpp99
-rw-r--r--src/modules/m_ident.cpp17
-rw-r--r--src/modules/m_inviteexception.cpp22
-rw-r--r--src/modules/m_joinflood.cpp68
-rw-r--r--src/modules/m_kicknorejoin.cpp65
-rw-r--r--src/modules/m_messageflood.cpp53
-rw-r--r--src/modules/m_namesx.cpp35
-rw-r--r--src/modules/m_nickflood.cpp73
-rw-r--r--src/modules/m_nicklock.cpp48
-rw-r--r--src/modules/m_nonicks.cpp2
-rw-r--r--src/modules/m_regonlycreate.cpp2
-rw-r--r--src/modules/m_safelist.cpp87
-rw-r--r--src/modules/m_sasl.cpp89
-rw-r--r--src/modules/m_services_account.cpp81
-rw-r--r--src/modules/m_silence.cpp58
-rw-r--r--src/modules/m_spanningtree/hmac.cpp17
-rw-r--r--src/modules/m_spanningtree/main.cpp2
-rw-r--r--src/modules/m_spanningtree/netburst.cpp28
-rw-r--r--src/modules/m_spanningtree/operquit.cpp2
-rw-r--r--src/modules/m_sslinfo.cpp145
-rw-r--r--src/modules/m_sslmodes.cpp36
-rw-r--r--src/modules/m_swhois.cpp143
-rw-r--r--src/modules/m_uhnames.cpp31
-rw-r--r--src/modules/m_watch.cpp76
-rw-r--r--src/modules/transport.h22
-rw-r--r--src/users.cpp16
54 files changed, 1069 insertions, 1529 deletions
diff --git a/include/base.h b/include/base.h
index 6bcf76817..ab52545f9 100644
--- a/include/base.h
+++ b/include/base.h
@@ -18,9 +18,6 @@
#include <deque>
#include <string>
-/** A private data store for an Extensible class */
-typedef std::map<std::string,char*> ExtensibleStore;
-
/** The base class for all inspircd classes.
* Wherever possible, all classes you create should inherit from this,
* giving them the ability to be passed to various core functions
@@ -29,126 +26,11 @@ typedef std::map<std::string,char*> ExtensibleStore;
class CoreExport classbase
{
public:
- /** Constructor.
- * Sets the object's time
- */
classbase();
- /** Destructor.
- * Does sweet FA.
- */
virtual ~classbase() { }
};
-/** class Extensible is the parent class of many classes such as User and Channel.
- * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
- * a map associated with the object. In this way modules can store their own custom information within user
- * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
- * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
- * supports arbitary data storage).
- */
-class CoreExport Extensible : public classbase
-{
- /** Private data store.
- * Holds all extensible metadata for the class.
- */
- ExtensibleStore Extension_Items;
-
-public:
-
- /** Extend an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @param p This parameter is a pointer to any data you wish to associate with the object
- *
- * You must provide a key to store the data as via the parameter 'key' and store the data
- * in the templated parameter 'p'.
- * The data will be inserted into the map. If the data already exists, you may not insert it
- * twice, Extensible::Extend will return false in this case.
- *
- * @return Returns true on success, false if otherwise
- */
- template<typename T> bool Extend(const std::string &key, T* p)
- {
- /* This will only add an item if it doesnt already exist,
- * the return value is a std::pair of an iterator to the
- * element, and a bool saying if it was actually inserted.
- */
- return this->Extension_Items.insert(std::make_pair(key, (char*)p)).second;
- }
-
- /** Extend an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- *
- * You must provide a key to store the data as via the parameter 'key', this single-parameter
- * version takes no 'data' parameter, this is used purely for boolean values.
- * The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
- * then you may not insert it twice, Extensible::Extend will return false in this case.
- *
- * @return Returns true on success, false if otherwise
- */
- bool Extend(const std::string &key)
- {
- /* This will only add an item if it doesnt already exist,
- * the return value is a std::pair of an iterator to the
- * element, and a bool saying if it was actually inserted.
- */
- return this->Extension_Items.insert(std::make_pair(key, (char*)NULL)).second;
- }
-
- /** Shrink an Extensible class.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- *
- * You must provide a key name. The given key name will be removed from the classes data. If
- * you provide a nonexistent key (case is important) then the function will return false.
- * @return Returns true on success.
- */
- bool Shrink(const std::string &key);
-
- /** Get an extension item.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
- * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
- */
- template<typename T> bool GetExt(const std::string &key, T* &p)
- {
- ExtensibleStore::iterator iter = this->Extension_Items.find(key); /* Find the item */
- if(iter != this->Extension_Items.end())
- {
- p = (T*)iter->second; /* Item found */
- return true;
- }
- else
- {
- p = NULL; /* Item not found */
- return false;
- }
- }
-
- /** Get an extension item.
- *
- * @param key The key parameter is an arbitary string which identifies the extension data
- * @return Returns true if the item was found and false if it was not.
- *
- * This single-parameter version only checks if the key exists, it does nothing with
- * the 'data' field and is probably only useful in conjunction with the single-parameter
- * version of Extend().
- */
- bool GetExt(const std::string &key)
- {
- return (this->Extension_Items.find(key) != this->Extension_Items.end());
- }
-
- /** Get a list of all extension items names.
- * @param list A deque of strings to receive the list
- * @return This function writes a list of all extension items stored in this object by name into the given deque and returns void.
- */
- void GetExtList(std::deque<std::string> &list);
-};
-
/** BoolSet is a utility class designed to hold eight bools in a bitmask.
* Use BoolSet::Set and BoolSet::Get to set and get bools in the bitmask,
* and Unset and Invert for special operations upon them.
diff --git a/include/extensible.h b/include/extensible.h
new file mode 100644
index 000000000..0a33470b5
--- /dev/null
+++ b/include/extensible.h
@@ -0,0 +1,150 @@
+class Extensible;
+class Module;
+
+/** Class represnting an extension of some object
+ */
+class CoreExport ExtensionItem
+{
+ public:
+ const std::string key;
+ Module* const owner;
+ ExtensionItem(const std::string& key, Module* owner);
+ /** Serialize this item into a string */
+ virtual std::string serialize(Module* requestor, const Extensible* container, void* item) = 0;
+ /** Convert the string form back into an item */
+ virtual void unserialize(Module* requestor, Extensible* container, const std::string& value) = 0;
+ /** Free the item */
+ virtual void free(void* item) = 0;
+
+ protected:
+ /** Get the item from the internal map */
+ void* get_raw(const Extensible* container);
+ /** Set the item in the internal map; returns old value */
+ void* set_raw(Extensible* container, void* value);
+ /** Remove the item from the internal map; returns old value */
+ void* unset_raw(Extensible* container);
+};
+
+/** A private data store for an Extensible class */
+typedef std::map<std::string,void*> ExtensibleStore;
+
+/** class Extensible is the parent class of many classes such as User and Channel.
+ * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
+ * a map associated with the object. In this way modules can store their own custom information within user
+ * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
+ * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
+ * supports arbitary data storage).
+ */
+class CoreExport Extensible : public classbase
+{
+ /** Private data store.
+ * Holds all extensible metadata for the class.
+ */
+ ExtensibleStore extensions;
+ typedef std::map<std::string, ExtensionItem*> ExtensibleTypes;
+ static ExtensibleTypes extension_types;
+ public:
+ /**
+ * Get the extension items for iteraton (i.e. for metadata sync during netburst)
+ */
+ inline const ExtensibleStore& GetExtList() const { return extensions; }
+ static inline const ExtensibleTypes& GetTypeList() { return extension_types; }
+ static inline ExtensionItem* GetItem(const std::string& name)
+ {
+ ExtensibleTypes::iterator i = extension_types.find(name);
+ if (i == extension_types.end())
+ return NULL;
+ return i->second;
+ }
+
+ virtual ~Extensible();
+
+ static bool Register(ExtensionItem* item);
+ static void UnRegister(Module* module);
+
+ // Friend access for the protected getter/setter
+ friend class ExtensionItem;
+};
+
+/** Base class for items that are NOT synchronized between servers */
+class CoreExport LocalExtItem : public ExtensionItem
+{
+ public:
+ LocalExtItem(const std::string& key, Module* owner);
+ // this is deliberately NOT virtual; don't subclass LocalExtItem if you want to sync data!
+ std::string serialize(Module* requestor, const Extensible* container, void* item);
+ void unserialize(Module* requestor, Extensible* container, const std::string& value);
+ virtual void free(void* item) = 0;
+};
+
+template<typename T>
+class CoreExport SimpleExtItem : public LocalExtItem
+{
+ public:
+ SimpleExtItem(const std::string& Key, Module* parent) : LocalExtItem(Key, parent)
+ {
+ }
+
+ inline T* get(const Extensible* container)
+ {
+ return static_cast<T*>(get_raw(container));
+ }
+
+ inline T* getNew(Extensible* container)
+ {
+ T* ptr = get(container);
+ if (!ptr)
+ {
+ ptr = new T;
+ set_raw(container, ptr);
+ }
+ return ptr;
+ }
+
+ inline void set(Extensible* container, const T& value)
+ {
+ T* ptr = new T(value);
+ T* old = static_cast<T*>(set_raw(container, ptr));
+ delete old;
+ }
+
+ inline void set(Extensible* container, T* value)
+ {
+ T* old = static_cast<T*>(set_raw(container, value));
+ delete old;
+ }
+
+ inline void unset(Extensible* container)
+ {
+ T* old = static_cast<T*>(unset_raw(container));
+ delete old;
+ }
+
+ virtual void free(void* item)
+ {
+ delete static_cast<T*>(item);
+ }
+};
+
+typedef SimpleExtItem<std::string> LocalStringExt;
+
+class CoreExport LocalIntExt : public LocalExtItem
+{
+ public:
+ LocalIntExt(const std::string& key, Module* owner);
+ intptr_t get(const Extensible* container);
+ intptr_t set(Extensible* container, intptr_t value);
+ void free(void* item);
+};
+
+class CoreExport StringExtItem : public ExtensionItem
+{
+ public:
+ StringExtItem(const std::string& key, Module* owner);
+ std::string* get(const Extensible* container);
+ std::string serialize(Module* requestor, const Extensible* container, void* item);
+ void unserialize(Module* requestor, Extensible* container, const std::string& value);
+ void set(Extensible* container, const std::string& value);
+ void unset(Extensible* container);
+ void free(void* item);
+};
diff --git a/include/inspircd.h b/include/inspircd.h
index ae46569a0..a7eed47ff 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -75,6 +75,7 @@ typedef std::multimap< std::string, KeyValList > ConfigDataHash;
#include "inspircd_config.h"
#include "inspircd_version.h"
+#include "extensible.h"
#include "numerics.h"
#include "uid.h"
#include "users.h"
diff --git a/include/modules.h b/include/modules.h
index 3f779fe80..9e9686ad2 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -442,11 +442,10 @@ class ConfigReader;
*/
class CoreExport Module : public Extensible
{
- protected:
+ public:
/** Creator/owner pointer
*/
InspIRCd* ServerInstance;
- public:
/** File that this module was loaded from
*/
std::string ModuleSourceFile;
diff --git a/include/u_listmode.h b/include/u_listmode.h
index 773ca421f..9d9b5f836 100644
--- a/include/u_listmode.h
+++ b/include/u_listmode.h
@@ -107,9 +107,6 @@ class ListModeRequest : public Request
class ListModeBase : public ModeHandler
{
protected:
- /** Storage key
- */
- std::string infokey;
/** Numeric to use when outputting the list
*/
unsigned int listnumeric;
@@ -131,6 +128,10 @@ class ListModeBase : public ModeHandler
limitlist chanlimits;
public:
+ /** Storage key
+ */
+ SimpleExtItem<modelist> extItem;
+
/** Constructor.
* @param Instance The creator of this class
* @param modechar Mode character
@@ -141,18 +142,19 @@ class ListModeBase : public ModeHandler
* @param ctag Configuration tag to get limits from
*/
ListModeBase(InspIRCd* Instance, Module* Creator, char modechar, const std::string &eolstr, unsigned int lnum, unsigned int eolnum, bool autotidy, const std::string &ctag = "banlist")
- : ModeHandler(Instance, Creator, modechar, 1, 1, true, MODETYPE_CHANNEL, false), listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy), configtag(ctag)
+ : ModeHandler(Instance, Creator, modechar, 1, 1, true, MODETYPE_CHANNEL, false),
+ listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy),
+ configtag(ctag), extItem("listbase_mode_" + std::string(1, mode) + "_list", Creator)
{
this->DoRehash();
- infokey = "listbase_mode_" + std::string(1, mode) + "_list";
+ Extensible::Register(&extItem);
}
/** See mode.h
*/
std::pair<bool,std::string> ModeSet(User*, User*, Channel* channel, const std::string &parameter)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
for (modelist::iterator it = el->begin(); it != el->end(); it++)
@@ -172,8 +174,7 @@ class ListModeBase : public ModeHandler
*/
virtual void DisplayList(User* user, Channel* channel)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
for (modelist::reverse_iterator it = el->rbegin(); it != el->rend(); ++it)
@@ -195,8 +196,7 @@ class ListModeBase : public ModeHandler
*/
virtual void RemoveMode(Channel* channel, irc::modestacker* stack)
{
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (el)
{
irc::modestacker modestack(ServerInstance, false);
@@ -271,8 +271,7 @@ class ListModeBase : public ModeHandler
virtual ModeAction OnModeChange(User* source, User*, Channel* channel, std::string &parameter, bool adding)
{
// Try and grab the list
- modelist* el;
- channel->GetExt(infokey, el);
+ modelist* el = extItem.get(channel);
if (adding)
{
@@ -281,7 +280,7 @@ class ListModeBase : public ModeHandler
{
// Make one
el = new modelist;
- channel->Extend(infokey, el);
+ extItem.set(channel, el);
}
// Clean the mask up
@@ -362,8 +361,7 @@ class ListModeBase : public ModeHandler
el->erase(it);
if (el->size() == 0)
{
- channel->Shrink(infokey);
- delete el;
+ extItem.unset(channel);
}
return MODEACTION_ALLOW;
}
@@ -384,29 +382,6 @@ class ListModeBase : public ModeHandler
return MODEACTION_DENY;
}
- /** Get Extensible key for this mode
- */
- virtual std::string& GetInfoKey()
- {
- return infokey;
- }
-
- /** Handle channel deletion.
- * See modules.h.
- * @param chan Channel being deleted
- */
- virtual void DoChannelDelete(Channel* chan)
- {
- modelist* mlist;
- chan->GetExt(infokey, mlist);
-
- if (mlist)
- {
- chan->Shrink(infokey);
- delete mlist;
- }
- }
-
/** Syncronize channel item list with another server.
* See modules.h
* @param chan Channel to syncronize
@@ -415,8 +390,7 @@ class ListModeBase : public ModeHandler
*/
virtual void DoSyncChannel(Channel* chan, Module* proto, void* opaque)
{
- modelist* mlist;
- chan->GetExt(infokey, mlist);
+ modelist* mlist = extItem.get(chan);
irc::modestacker modestack(ServerInstance, true);
std::vector<std::string> stackresult;
std::vector<TranslateType> types;
@@ -493,8 +467,7 @@ class ListModeBase : public ModeHandler
ListModeRequest* LM = (ListModeRequest*)request;
if (strcmp("LM_CHECKLIST", request->GetId()) == 0)
{
- modelist* mlist;
- LM->chan->GetExt(GetInfoKey(), mlist);
+ modelist* mlist = extItem.get(LM->chan);
if (mlist)
{
std::string mask = LM->user->nick + "!" + LM->user->ident + "@" + LM->user->GetIPString();
@@ -508,8 +481,7 @@ class ListModeBase : public ModeHandler
}
else if (strcmp("LM_CHECKLIST_EX", request->GetId()) == 0)
{
- modelist* mlist;
- LM->chan->GetExt(GetInfoKey(), mlist);
+ modelist* mlist = extItem.get(LM->chan);
if (mlist)
{
diff --git a/include/users.h b/include/users.h
index 5338deb4c..a6c36b7fd 100644
--- a/include/users.h
+++ b/include/users.h
@@ -274,6 +274,9 @@ class CoreExport User : public EventHandler
*/
InspIRCd* ServerInstance;
+ static LocalIntExt NICKForced;
+ static LocalStringExt OperQuit;
+
/** Contains a pointer to the connect class a user is on from - this will be NULL for remote connections.
* The pointer is guarenteed to *always* be valid. :)
*/
@@ -977,7 +980,4 @@ class CoreExport UserResolver : public Resolver
void OnError(ResolverError e, const std::string &errormessage);
};
-/* Configuration callbacks */
-//class ServerConfig;
-
#endif
diff --git a/src/base.cpp b/src/base.cpp
index 7e0cf482a..4d0c17077 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -20,28 +20,12 @@
const int bitfields[] = {1,2,4,8,16,32,64,128};
const int inverted_bitfields[] = {~1,~2,~4,~8,~16,~32,~64,~128};
+std::map<std::string, ExtensionItem*> Extensible::extension_types;
classbase::classbase()
{
}
-bool Extensible::Shrink(const std::string &key)
-{
- /* map::size_type map::erase( const key_type& key );
- * returns the number of elements removed, std::map
- * is single-associative so this should only be 0 or 1
- */
- return this->Extension_Items.erase(key);
-}
-
-void Extensible::GetExtList(std::deque<std::string> &list)
-{
- for (ExtensibleStore::iterator u = Extension_Items.begin(); u != Extension_Items.end(); u++)
- {
- list.push_back(u->first);
- }
-}
-
void BoolSet::Set(int number)
{
this->bits |= bitfields[number];
@@ -94,3 +78,140 @@ bool BoolSet::operator=(BoolSet other)
this->bits = other.bits;
return true;
}
+
+ExtensionItem::ExtensionItem(const std::string& Key, Module* mod) : key(Key), owner(mod)
+{
+}
+
+void* ExtensionItem::get_raw(const Extensible* container)
+{
+ ExtensibleStore::const_iterator i = container->extensions.find(key);
+ if (i == container->extensions.end())
+ return NULL;
+ return i->second;
+}
+
+void* ExtensionItem::set_raw(Extensible* container, void* value)
+{
+ std::pair<ExtensibleStore::iterator,bool> rv =
+ container->extensions.insert(std::make_pair(key, value));
+ if (rv.second)
+ {
+ return NULL;
+ }
+ else
+ {
+ void* old = rv.first->second;
+ rv.first->second = value;
+ return old;
+ }
+}
+
+void* ExtensionItem::unset_raw(Extensible* container)
+{
+ ExtensibleStore::iterator i = container->extensions.find(key);
+ if (i == container->extensions.end())
+ return NULL;
+ void* rv = i->second;
+ container->extensions.erase(i);
+ return rv;
+}
+
+bool Extensible::Register(ExtensionItem* item)
+{
+ return Extensible::extension_types.insert(std::make_pair(item->key, item)).second;
+}
+
+void Extensible::UnRegister(Module* module)
+{
+ ExtensibleTypes::iterator i = extension_types.begin();
+ while (i != extension_types.end())
+ {
+ ExtensibleTypes::iterator c = i++;
+ if (c->second->owner == module)
+ extension_types.erase(c);
+ }
+}
+
+Extensible::~Extensible()
+{
+ for(ExtensibleStore::iterator i = extensions.begin(); i != extensions.end(); ++i)
+ {
+ ExtensionItem* type = extension_types[i->first];
+ if (type)
+ type->free(i->second);
+ }
+}
+
+LocalExtItem::LocalExtItem(const std::string& Key, Module* mod) : ExtensionItem(Key, mod)
+{
+}
+
+std::string LocalExtItem::serialize(Module* requestor, const Extensible* container, void* item)
+{
+ return "";
+}
+
+void LocalExtItem::unserialize(Module* requestor, Extensible* container, const std::string& value)
+{
+}
+
+LocalIntExt::LocalIntExt(const std::string& Key, Module* mod) : LocalExtItem(Key, mod)
+{
+}
+
+intptr_t LocalIntExt::get(const Extensible* container)
+{
+ return reinterpret_cast<intptr_t>(get_raw(container));
+}
+
+intptr_t LocalIntExt::set(Extensible* container, intptr_t value)
+{
+ if (value)
+ return reinterpret_cast<intptr_t>(set_raw(container, reinterpret_cast<void*>(value)));
+ else
+ return reinterpret_cast<intptr_t>(unset_raw(container));
+}
+
+void LocalIntExt::free(void*)
+{
+}
+
+StringExtItem::StringExtItem(const std::string& Key, Module* mod) : ExtensionItem(Key, mod)
+{
+}
+
+std::string* StringExtItem::get(const Extensible* container)
+{
+ return static_cast<std::string*>(get_raw(container));
+}
+
+std::string StringExtItem::serialize(Module* requestor, const Extensible* container, void* item)
+{
+ return item ? *static_cast<std::string*>(item) : "";
+}
+
+void StringExtItem::unserialize(Module* requestor, Extensible* container, const std::string& value)
+{
+ if (value.empty())
+ unset(container);
+ else
+ set(container, value);
+}
+
+void StringExtItem::set(Extensible* container, const std::string& value)
+{
+ void* old = set_raw(container, new std::string(value));
+ delete static_cast<std::string*>(old);
+}
+
+void StringExtItem::unset(Extensible* container)
+{
+ void* old = unset_raw(container);
+ delete static_cast<std::string*>(old);
+}
+
+void StringExtItem::free(void* item)
+{
+ delete static_cast<std::string*>(item);
+}
diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp
index 3851b36e6..6a181bda0 100644
--- a/src/commands/cmd_nick.cpp
+++ b/src/commands/cmd_nick.cpp
@@ -75,16 +75,16 @@ CmdResult CommandNick::Handle (const std::vector<std::string>& parameters, User
if (((!ServerInstance->IsNick(parameters[0].c_str(), ServerInstance->Config->Limits.NickMax))) && (IS_LOCAL(user)))
{
- if (!user->GetExt("NICKForced"))
+ if (!User::NICKForced.get(user))
{
if (parameters[0] == "0")
{
// Special case, Fake a /nick UIDHERE. Useful for evading "ERR: NICK IN USE" on connect etc.
std::vector<std::string> p2;
p2.push_back(user->uuid);
- user->Extend("NICKForced");
+ User::NICKForced.set(user, 1);
this->Handle(p2, user);
- user->Shrink("NICKForced");
+ User::NICKForced.set(user, 0);
return CMD_SUCCESS;
}
diff --git a/src/commands/cmd_quit.cpp b/src/commands/cmd_quit.cpp
index 968374dec..46c728881 100644
--- a/src/commands/cmd_quit.cpp
+++ b/src/commands/cmd_quit.cpp
@@ -63,11 +63,10 @@ CmdResult CommandQuit::Handle (const std::vector<std::string>& parameters, User
else
quitmsg = parameters.size() ? parameters[0] : "Client exited";
- std::string* operquit;
- if (user->GetExt("operquit", operquit))
+ std::string* operquit = User::OperQuit.get(user);
+ if (operquit)
{
ServerInstance->Users->QuitUser(user, quitmsg, operquit->c_str());
- delete operquit;
}
else
{
diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp
index 61b5a0f60..329c0a2d5 100644
--- a/src/commands/cmd_who.cpp
+++ b/src/commands/cmd_who.cpp
@@ -78,7 +78,6 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
{
bool match = false;
bool positive = false;
- char* dummy = NULL;
if (user->registered != REG_ALL)
return false;
@@ -115,7 +114,7 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
* -- w00t
*/
if (opt_metadata)
- match = user->GetExt(matchtext, dummy);
+ match = user->GetExtList().find(matchtext) != user->GetExtList().end();
else if (opt_realname)
match = InspIRCd::Match(user->fullname, matchtext);
else if (opt_showrealhost)
diff --git a/src/dns.cpp b/src/dns.cpp
index b2dbf40a7..94a01e64c 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -34,7 +34,6 @@ looks like this, walks like this or tastes like this.
#include "inspircd_se_config.h"
#endif
-#include "dns.h"
#include "inspircd.h"
#include "socketengine.h"
#include "configreader.h"
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 1ec32742e..0350858e7 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -11,12 +11,10 @@
* ---------------------------------------------------
*/
-/* $Core */
-
+#include "inspircd.h"
#include "socket.h"
#include "inspstring.h"
#include "socketengine.h"
-#include "inspircd.h"
bool BufferedSocket::Readable()
{
diff --git a/src/modules.cpp b/src/modules.cpp
index 59b52b5b1..c7509fad9 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -558,6 +558,7 @@ bool ModuleManager::Unload(const char* filename)
this->DetachAll(modfind->second.second);
Instance->Parser->RemoveCommands(modfind->second.second);
+ Extensible::UnRegister(modfind->second.second);
delete modfind->second.second;
delete modfind->second.first;
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index f5133a1dc..97a5ebe0e 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -98,10 +98,11 @@ class ModuleSSLGnuTLS : public Module
CommandStartTLS starttls;
+ GenericCap capHandler;
public:
ModuleSSLGnuTLS(InspIRCd* Me)
- : Module(Me), starttls(Me, this)
+ : Module(Me), starttls(Me, this), capHandler(this, "tls")
{
ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
@@ -266,13 +267,6 @@ class ModuleSSLGnuTLS : public Module
ServerInstance->Users->QuitUser(user, "SSL module unloading");
user->DelIOHook();
}
- if (user->GetExt("ssl_cert"))
- {
- ssl_cert* tofree;
- user->GetExt("ssl_cert", tofree);
- delete tofree;
- user->Shrink("ssl_cert");
- }
}
}
@@ -339,25 +333,16 @@ class ModuleSSLGnuTLS : public Module
{
if (static_cast<Extensible*>(ServerInstance->SE->GetRef(ISR->Sock->GetFd())) == static_cast<Extensible*>(ISR->Sock))
{
- VerifyCertificate(session, ISR->Sock);
return "OK";
}
}
}
}
- else if (strcmp("GET_FP", request->GetId()) == 0)
+ else if (strcmp("GET_CERT", request->GetId()) == 0)
{
- if (ISR->Sock->GetFd() > -1)
- {
- issl_session* session = &sessions[ISR->Sock->GetFd()];
- if (session->sess)
- {
- Extensible* ext = ISR->Sock;
- ssl_cert* certinfo;
- if (ext->GetExt("ssl_cert",certinfo))
- return certinfo->GetFingerprint().c_str();
- }
- }
+ Module* sslinfo = ServerInstance->Modules->Find("m_sslinfo.so");
+ if (sslinfo)
+ return sslinfo->OnRequest(request);
}
return NULL;
}
@@ -413,16 +398,6 @@ class ModuleSSLGnuTLS : public Module
return;
CloseSession(&sessions[fd]);
-
- EventHandler* user = ServerInstance->SE->GetRef(fd);
-
- if ((user) && (user->GetExt("ssl_cert")))
- {
- ssl_cert* tofree;
- user->GetExt("ssl_cert", tofree);
- delete tofree;
- user->Shrink("ssl_cert");
- }
}
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
@@ -606,17 +581,13 @@ class ModuleSSLGnuTLS : public Module
}
else
{
- // Handshake complete.
- // This will do for setting the ssl flag...it could be done earlier if it's needed. But this seems neater.
- EventHandler *extendme = ServerInstance->SE->GetRef(fd);
- if (extendme)
- {
- extendme->Extend("ssl");
- }
-
// Change the seesion state
session->status = ISSL_HANDSHAKEN;
+ EventHandler* user = ServerInstance->SE->GetRef(fd);
+
+ VerifyCertificate(session,user);
+
// Finish writing, if any left
MakePollWrite(fd);
@@ -630,7 +601,6 @@ class ModuleSSLGnuTLS : public Module
// protocol module has propagated the NICK message.
if (user->GetIOHook() == this && (IS_LOCAL(user)))
{
- ssl_cert* certdata = VerifyCertificate(&sessions[user->GetFd()],user);
if (sessions[user->GetFd()].sess)
{
std::string cipher = gnutls_kx_get_name(gnutls_kx_get(sessions[user->GetFd()].sess));
@@ -638,10 +608,6 @@ class ModuleSSLGnuTLS : public Module
cipher.append(gnutls_mac_get_name(gnutls_mac_get(sessions[user->GetFd()].sess)));
user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), cipher.c_str());
}
-
- ServerInstance->PI->SendMetaData(user, "ssl", "ON");
- if (certdata)
- ServerInstance->PI->SendMetaData(user, "ssl_cert", certdata->GetMetaLine().c_str());
}
}
@@ -676,10 +642,14 @@ class ModuleSSLGnuTLS : public Module
session->status = ISSL_NONE;
}
- ssl_cert* VerifyCertificate(issl_session* session, Extensible* user)
+ void VerifyCertificate(issl_session* session, Extensible* user)
{
if (!session->sess || !user)
- return NULL;
+ return;
+
+ Module* sslinfo = ServerInstance->Modules->Find("m_sslinfo.so");
+ if (!sslinfo)
+ return;
unsigned int status;
const gnutls_datum_t* cert_list;
@@ -692,8 +662,6 @@ class ModuleSSLGnuTLS : public Module
size_t name_size = sizeof(name);
ssl_cert* certinfo = new ssl_cert;
- user->Extend("ssl_cert",certinfo);
-
/* This verification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
@@ -702,7 +670,7 @@ class ModuleSSLGnuTLS : public Module
if (ret < 0)
{
certinfo->error = std::string(gnutls_strerror(ret));
- return certinfo;
+ goto info_done;
}
certinfo->invalid = (status & GNUTLS_CERT_INVALID);
@@ -717,14 +685,14 @@ class ModuleSSLGnuTLS : public Module
if (gnutls_certificate_type_get(session->sess) != GNUTLS_CRT_X509)
{
certinfo->error = "No X509 keys sent";
- return certinfo;
+ goto info_done;
}
ret = gnutls_x509_crt_init(&cert);
if (ret < 0)
{
certinfo->error = gnutls_strerror(ret);
- return certinfo;
+ goto info_done;
}
cert_list_size = 0;
@@ -732,7 +700,7 @@ class ModuleSSLGnuTLS : public Module
if (cert_list == NULL)
{
certinfo->error = "No certificate was found";
- return certinfo;
+ goto info_done_dealloc;
}
/* This is not a real world example, since we only check the first
@@ -743,7 +711,7 @@ class ModuleSSLGnuTLS : public Module
if (ret < 0)
{
certinfo->error = gnutls_strerror(ret);
- return certinfo;
+ goto info_done_dealloc;
}
gnutls_x509_crt_get_dn(cert, name, &name_size);
@@ -768,20 +736,15 @@ class ModuleSSLGnuTLS : public Module
certinfo->error = "Not activated, or expired certificate";
}
+info_done_dealloc:
gnutls_x509_crt_deinit(cert);
-
- return certinfo;
+info_done:
+ BufferedSocketFingerprintSubmission(user, this, sslinfo, certinfo).Send();
}
void OnEvent(Event* ev)
{
- GenericCapHandler(ev, "tls", "tls");
- }
-
- void Prioritize()
- {
- Module* server = ServerInstance->Modules->Find("m_spanningtree.so");
- ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIORITY_AFTER, &server);
+ capHandler.HandleEvent(ev);
}
};
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index a8043457b..a33cf6bc2 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -293,13 +293,6 @@ class ModuleSSLOpenSSL : public Module
ServerInstance->Users->QuitUser(user, "SSL module unloading");
user->DelIOHook();
}
- if (user->GetExt("ssl_cert", dummy))
- {
- ssl_cert* tofree;
- user->GetExt("ssl_cert", tofree);
- delete tofree;
- user->Shrink("ssl_cert");
- }
}
}
@@ -347,23 +340,14 @@ class ModuleSSLOpenSSL : public Module
issl_session* session = &sessions[ISR->Sock->GetFd()];
if (session->sess)
{
- VerifyCertificate(session, (BufferedSocket*)ISR->Sock);
return "OK";
}
}
- else if (strcmp("GET_FP", request->GetId()) == 0)
+ else if (strcmp("GET_CERT", request->GetId()) == 0)
{
- if (ISR->Sock->GetFd() > -1)
- {
- issl_session* session = &sessions[ISR->Sock->GetFd()];
- if (session->sess)
- {
- Extensible* ext = ISR->Sock;
- ssl_cert* certinfo;
- if (ext->GetExt("ssl_cert",certinfo))
- return certinfo->GetFingerprint().c_str();
- }
- }
+ Module* sslinfo = ServerInstance->Modules->Find("m_sslinfo.so");
+ if (sslinfo)
+ return sslinfo->OnRequest(request);
}
return NULL;
}
@@ -430,16 +414,6 @@ class ModuleSSLOpenSSL : public Module
return;
CloseSession(&sessions[fd]);
-
- EventHandler* user = ServerInstance->SE->GetRef(fd);
-
- if ((user) && (user->GetExt("ssl_cert", dummy)))
- {
- ssl_cert* tofree;
- user->GetExt("ssl_cert", tofree);
- delete tofree;
- user->Shrink("ssl_cert");
- }
}
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
@@ -691,10 +665,7 @@ class ModuleSSLOpenSSL : public Module
// Handshake complete.
// This will do for setting the ssl flag...it could be done earlier if it's needed. But this seems neater.
EventHandler *u = ServerInstance->SE->GetRef(session->fd);
- if (u)
- {
- u->Extend("ssl");
- }
+ VerifyCertificate(session, u);
session->status = ISSL_OPEN;
@@ -717,13 +688,8 @@ class ModuleSSLOpenSSL : public Module
// protocol module has propagated the NICK message.
if ((user->GetIOHook() == this) && (IS_LOCAL(user)))
{
- ssl_cert* certdata = VerifyCertificate(&sessions[user->GetFd()], user);
if (sessions[user->GetFd()].sess)
user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), SSL_get_cipher(sessions[user->GetFd()].sess));
-
- ServerInstance->PI->SendMetaData(user, "ssl", "ON");
- if (certdata)
- ServerInstance->PI->SendMetaData(user, "ssl_cert", certdata->GetMetaLine().c_str());
}
}
@@ -767,10 +733,14 @@ class ModuleSSLOpenSSL : public Module
errno = EIO;
}
- ssl_cert* VerifyCertificate(issl_session* session, Extensible* user)
+ void VerifyCertificate(issl_session* session, Extensible* user)
{
if (!session->sess || !user)
- return NULL;
+ return;
+
+ Module* sslinfo = ServerInstance->Modules->Find("m_sslinfo.so");
+ if (!sslinfo)
+ return;
X509* cert;
ssl_cert* certinfo = new ssl_cert;
@@ -778,14 +748,13 @@ class ModuleSSLOpenSSL : public Module
unsigned char md[EVP_MAX_MD_SIZE];
const EVP_MD *digest = EVP_md5();
- user->Extend("ssl_cert",certinfo);
-
cert = SSL_get_peer_certificate((SSL*)session->sess);
if (!cert)
{
certinfo->error = "Could not get peer certificate: "+std::string(get_error());
- return certinfo;
+ BufferedSocketFingerprintSubmission(user, this, sslinfo, certinfo).Send();
+ return;
}
certinfo->invalid = (SSL_get_verify_result(session->sess) != X509_V_OK);
@@ -819,7 +788,7 @@ class ModuleSSLOpenSSL : public Module
}
X509_free(cert);
- return certinfo;
+ BufferedSocketFingerprintSubmission(user, this, sslinfo, certinfo).Send();
}
void Prioritize()
diff --git a/src/modules/m_antibear.cpp b/src/modules/m_antibear.cpp
index 70a4a96fb..8eab13594 100644
--- a/src/modules/m_antibear.cpp
+++ b/src/modules/m_antibear.cpp
@@ -18,12 +18,11 @@
class ModuleAntiBear : public Module
{
- private:
-
+ LocalIntExt bearExt;
public:
- ModuleAntiBear(InspIRCd* Me) : Module(Me)
+ ModuleAntiBear(InspIRCd* Me) : Module(Me), bearExt("antibear_timewait", this)
{
-
+ Extensible::Register(&bearExt);
Implementation eventlist[] = { I_OnUserRegister, I_OnPreCommand };
ServerInstance->Modules->Attach(eventlist, this, 2);
}
@@ -39,7 +38,7 @@ class ModuleAntiBear : public Module
virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
{
- if (command == "NOTICE" && !validated && parameters.size() > 1 && user->GetExt("antibear_timewait"))
+ if (command == "NOTICE" && !validated && parameters.size() > 1 && bearExt.get(user))
{
if (!strncmp(parameters[1].c_str(), "\1TIME Mon May 01 18:54:20 2006", 30))
{
@@ -55,7 +54,7 @@ class ModuleAntiBear : public Module
return MOD_RES_DENY;
}
- user->Shrink("antibear_timewait");
+ bearExt.set(user, 0);
// Block the command, so the user doesn't receive a no such nick notice
return MOD_RES_DENY;
}
@@ -68,7 +67,7 @@ class ModuleAntiBear : public Module
user->WriteNumeric(439, "%s :This server has anti-spambot mechanisms enabled.", user->nick.c_str());
user->WriteNumeric(931, "%s :Malicious bots, spammers, and other automated systems of dubious origin are NOT welcome here.", user->nick.c_str());
user->WriteServ("PRIVMSG %s :\1TIME\1", user->nick.c_str());
- user->Extend("antibear_timewait");
+ bearExt.set(user, 1);
return MOD_RES_PASSTHRU;
}
};
diff --git a/src/modules/m_banexception.cpp b/src/modules/m_banexception.cpp
index dafa47d2c..9137c09d9 100644
--- a/src/modules/m_banexception.cpp
+++ b/src/modules/m_banexception.cpp
@@ -61,8 +61,7 @@ public:
{
if (chan != NULL)
{
- modelist *list;
- chan->GetExt(be.GetInfoKey(), list);
+ modelist *list = be.extItem.get(chan);
if (!list)
return MOD_RES_PASSTHRU;
@@ -90,8 +89,7 @@ public:
{
if (chan != NULL)
{
- modelist *list;
- chan->GetExt(be.GetInfoKey(), list);
+ modelist *list = be.extItem.get(chan);
if (!list)
return MOD_RES_PASSTHRU;
@@ -114,8 +112,7 @@ public:
{
if (chan != NULL)
{
- modelist* list;
- chan->GetExt(be.GetInfoKey(), list);
+ modelist *list = be.extItem.get(chan);
if (!list)
{
@@ -146,11 +143,6 @@ public:
be.DoSyncChannel(chan, proto, opaque);
}
- virtual void OnChannelDelete(Channel* chan)
- {
- be.DoChannelDelete(chan);
- }
-
virtual void OnRehash(User* user)
{
be.DoRehash();
diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp
index 1a486325a..da08d06fb 100644
--- a/src/modules/m_banredirect.cpp
+++ b/src/modules/m_banredirect.cpp
@@ -38,7 +38,9 @@ typedef std::deque<std::string> StringDeque;
class BanRedirect : public ModeWatcher
{
public:
- BanRedirect(InspIRCd* Instance) : ModeWatcher(Instance, 'b', MODETYPE_CHANNEL)
+ SimpleExtItem<BanRedirectList> extItem;
+ BanRedirect(InspIRCd* Instance, Module* parent) : ModeWatcher(Instance, 'b', MODETYPE_CHANNEL),
+ extItem("banredirect", parent)
{
}
@@ -145,10 +147,11 @@ class BanRedirect : public ModeWatcher
if(adding)
{
/* It's a properly valid redirecting ban, and we're adding it */
- if(!channel->GetExt("banredirects", redirects))
+ redirects = extItem.get(channel);
+ if (!redirects)
{
redirects = new BanRedirectList;
- channel->Extend("banredirects", redirects);
+ extItem.set(channel, redirects);
}
/* Here 'param' doesn't have the channel on it yet */
@@ -160,7 +163,8 @@ class BanRedirect : public ModeWatcher
else
{
/* Removing a ban, if there's no extensible there are no redirecting bans and we're fine. */
- if(channel->GetExt("banredirects", redirects))
+ redirects = extItem.get(channel);
+ if (redirects)
{
/* But there were, so we need to remove the matching one if there is one */
@@ -173,8 +177,7 @@ class BanRedirect : public ModeWatcher
if(redirects->empty())
{
- delete redirects;
- channel->Shrink("banredirects");
+ extItem.unset(channel);
}
break;
@@ -200,7 +203,7 @@ class ModuleBanRedirect : public Module
public:
ModuleBanRedirect(InspIRCd* Me)
- : Module(Me), re(Me)
+ : Module(Me), re(Me, this)
{
nofollow = false;
@@ -209,9 +212,9 @@ class ModuleBanRedirect : public Module
OnRehash(NULL);
+ Extensible::Register(&re.extItem);
Implementation list[] = { I_OnRehash, I_OnUserPreJoin, I_OnChannelDelete, I_OnCleanup };
Me->Modules->Attach(list, this, 4);
-
}
virtual void OnChannelDelete(Channel* chan)
@@ -224,9 +227,9 @@ class ModuleBanRedirect : public Module
if(target_type == TYPE_CHANNEL)
{
Channel* chan = static_cast<Channel*>(item);
- BanRedirectList* redirects;
+ BanRedirectList* redirects = re.extItem.get(chan);
- if(chan->GetExt("banredirects", redirects))
+ if(redirects)
{
irc::modestacker modestack(ServerInstance, false);
StringDeque stackresult;
@@ -250,9 +253,6 @@ class ModuleBanRedirect : public Module
ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
}
-
- delete redirects;
- chan->Shrink("banredirects");
}
}
}
@@ -273,9 +273,9 @@ class ModuleBanRedirect : public Module
/* Return 1 to prevent the join, 0 to allow it */
if (chan)
{
- BanRedirectList* redirects;
+ BanRedirectList* redirects = re.extItem.get(chan);
- if(chan->GetExt("banredirects", redirects))
+ if (redirects)
{
/* We actually had some ban redirects to check */
diff --git a/src/modules/m_blockamsg.cpp b/src/modules/m_blockamsg.cpp
index 104086bfe..5ce32ea8e 100644
--- a/src/modules/m_blockamsg.cpp
+++ b/src/modules/m_blockamsg.cpp
@@ -42,13 +42,15 @@ class ModuleBlockAmsg : public Module
{
int ForgetDelay;
BlockAction action;
+ SimpleExtItem<BlockedMessage> blockamsg;
public:
- ModuleBlockAmsg(InspIRCd* Me) : Module(Me)
+ ModuleBlockAmsg(InspIRCd* Me) : Module(Me), blockamsg("blockamsg", this)
{
this->OnRehash(NULL);
- Implementation eventlist[] = { I_OnRehash, I_OnPreCommand, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ Extensible::Register(&blockamsg);
+ Implementation eventlist[] = { I_OnRehash, I_OnPreCommand };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
}
@@ -125,8 +127,7 @@ class ModuleBlockAmsg : public Module
userchans = user->chans.size();
// Check that this message wasn't already sent within a few seconds.
- BlockedMessage* m;
- user->GetExt("amsgblock", m);
+ BlockedMessage* m = blockamsg.get(user);
// If the message is identical and within the time.
// We check the target is *not* identical, that'd straying into the realms of flood control. Which isn't what we're doing...
@@ -157,26 +158,11 @@ class ModuleBlockAmsg : public Module
else
{
m = new BlockedMessage(parameters[1], parameters[0].c_str(), ServerInstance->Time());
- user->Extend("amsgblock", (char*)m);
+ blockamsg.set(user, m);
}
}
return MOD_RES_PASSTHRU;
}
-
- void OnCleanup(int target_type, void* item)
- {
- if(target_type == TYPE_USER)
- {
- User* user = (User*)item;
- BlockedMessage* m;
- user->GetExt("amsgblock", m);
- if(m)
- {
- delete m;
- user->Shrink("amsgblock");
- }
- }
- }
};
diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp
index 543f5d8a1..2e508399b 100644
--- a/src/modules/m_callerid.cpp
+++ b/src/modules/m_callerid.cpp
@@ -70,59 +70,59 @@ class callerid_data : public classbase
}
};
-/** Retrieves the callerid information for a given user record
- * @param who The user to retrieve callerid information for
- * @param extend true to add callerid information if it doesn't already exist, false to return NULL if it doesn't exist
- * @return NULL if extend is false and it doesn't exist, a callerid_data instance otherwise.
- */
-callerid_data* GetData(User* who, bool extend = true)
+struct CallerIDExtInfo : public ExtensionItem
{
- callerid_data* dat;
- if (who->GetExt("callerid_data", dat))
- return dat;
- else
+ CallerIDExtInfo(Module* parent)
+ : ExtensionItem("callerid_data", parent)
{
- if (extend)
- {
- dat = new callerid_data;
- who->Extend("callerid_data", dat);
- return dat;
- }
- else
- return NULL;
}
-}
-void RemoveData(User* who)
-{
- callerid_data* dat;
- who->GetExt("callerid_data", dat);
+ std::string serialize(Module* requestor, const Extensible* container, void* item)
+ {
+ callerid_data* dat = static_cast<callerid_data*>(item);
+ return dat->ToString(requestor);
+ }
- if (!dat)
- return;
+ void unserialize(Module* requestor, Extensible* container, const std::string& value)
+ {
+ callerid_data* dat = new callerid_data(value, requestor->ServerInstance);
+ set_raw(container, dat);
+ }
- // We need to walk the list of users on our accept list, and remove ourselves from their wholistsme.
- for (std::set<User *>::iterator it = dat->accepting.begin(); it != dat->accepting.end(); it++)
+ callerid_data* get(User* user, bool create)
{
- callerid_data *targ = GetData(*it, false);
+ callerid_data* dat = static_cast<callerid_data*>(get_raw(user));
+ if (!dat)
+ {
+ dat = new callerid_data;
+ set_raw(user, dat);
+ }
+ return dat;
+ }
- if (!targ)
- continue; // shouldn't happen, but oh well.
+ void free(void* item)
+ {
+ callerid_data* dat = static_cast<callerid_data*>(item);
- for (std::list<callerid_data *>::iterator it2 = targ->wholistsme.begin(); it2 != targ->wholistsme.end(); it2++)
+ // We need to walk the list of users on our accept list, and remove ourselves from their wholistsme.
+ for (std::set<User *>::iterator it = dat->accepting.begin(); it != dat->accepting.end(); it++)
{
- if (*it2 == dat)
+ callerid_data *targ = this->get(*it, false);
+
+ if (!targ)
+ continue; // shouldn't happen, but oh well.
+
+ for (std::list<callerid_data *>::iterator it2 = targ->wholistsme.begin(); it2 != targ->wholistsme.end(); it2++)
{
- targ->wholistsme.erase(it2);
- break;
+ if (*it2 == dat)
+ {
+ targ->wholistsme.erase(it2);
+ break;
+ }
}
}
}
-
- who->Shrink("callerid_data");
- delete dat;
-}
-
+};
class User_g : public SimpleUserModeHandler
{
@@ -133,8 +133,10 @@ public:
class CommandAccept : public Command
{
public:
+ CallerIDExtInfo extInfo;
unsigned int maxaccepts;
- CommandAccept(InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "ACCEPT", 0, 1)
+ CommandAccept(InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "ACCEPT", 0, 1),
+ extInfo(Creator)
{
syntax = "{[+|-]<nicks>}|*}";
TRANSLATE2(TR_CUSTOM, TR_END);
@@ -221,7 +223,7 @@ public:
void ListAccept(User* user)
{
- callerid_data* dat = GetData(user, false);
+ callerid_data* dat = extInfo.get(user, false);
if (dat)
{
for (std::set<User*>::iterator i = dat->accepting.begin(); i != dat->accepting.end(); ++i)
@@ -233,7 +235,7 @@ public:
bool AddAccept(User* user, User* whotoadd, bool quiet)
{
// Add this user to my accept list first, so look me up..
- callerid_data* dat = GetData(user, true);
+ callerid_data* dat = extInfo.get(user, true);
if (dat->accepting.size() >= maxaccepts)
{
if (!quiet)
@@ -250,7 +252,7 @@ public:
}
// Now, look them up, and add me to their list
- callerid_data *targ = GetData(whotoadd, true);
+ callerid_data *targ = extInfo.get(whotoadd, true);
targ->wholistsme.push_back(dat);
user->WriteServ("NOTICE %s :%s is now on your accept list", user->nick.c_str(), whotoadd->nick.c_str());
@@ -260,7 +262,7 @@ public:
bool RemoveAccept(User* user, User* whotoremove, bool quiet)
{
// Remove them from my list, so look up my list..
- callerid_data* dat = GetData(user, false);
+ callerid_data* dat = extInfo.get(user, false);
if (!dat)
{
if (!quiet)
@@ -280,7 +282,7 @@ public:
dat->accepting.erase(i);
// Look up their list to remove me.
- callerid_data *dat2 = GetData(whotoremove, false);
+ callerid_data *dat2 = extInfo.get(whotoremove, false);
if (!dat2)
{
// How the fuck is this possible.
@@ -305,7 +307,7 @@ public:
class ModuleCallerID : public Module
{
private:
- CommandAccept mycommand;
+ CommandAccept cmd;
User_g myumode;
// Configuration variables:
@@ -319,7 +321,7 @@ private:
void RemoveFromAllAccepts(User* who)
{
// First, find the list of people who have me on accept
- callerid_data *userdata = GetData(who, false);
+ callerid_data *userdata = cmd.extInfo.get(who, false);
if (!userdata)
return;
@@ -339,17 +341,18 @@ private:
}
public:
- ModuleCallerID(InspIRCd* Me) : Module(Me), mycommand(Me, this), myumode(Me, this)
+ ModuleCallerID(InspIRCd* Me) : Module(Me), cmd(Me, this), myumode(Me, this)
{
OnRehash(NULL);
if (!ServerInstance->Modes->AddMode(&myumode))
throw ModuleException("Could not add usermode +g");
- ServerInstance->AddCommand(&mycommand);
+ ServerInstance->AddCommand(&cmd);
+ Extensible::Register(&cmd.extInfo);
- Implementation eventlist[] = { I_OnRehash, I_OnUserPreNick, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 7);
+ Implementation eventlist[] = { I_OnRehash, I_OnUserPreNick, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage };
+ ServerInstance->Modules->Attach(eventlist, this, 6);
}
virtual ~ModuleCallerID()
@@ -375,7 +378,7 @@ public:
if (operoverride && IS_OPER(user))
return MOD_RES_PASSTHRU;
- callerid_data* dat = GetData(dest, true);
+ callerid_data* dat = cmd.extInfo.get(dest, true);
std::set<User*>::iterator i = dat->accepting.find(user);
if (i == dat->accepting.end())
@@ -411,53 +414,22 @@ public:
return MOD_RES_PASSTHRU;
}
- virtual void OnCleanup(int type, void* item)
- {
- if (type != TYPE_USER)
- return;
-
- User* u = (User*)item;
- /* Cleanup only happens on unload (before dtor), so keep this O(n) instead of O(n^2) which deferring to OnUserQuit would do. */
- RemoveData(u);
- }
-
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- callerid_data* dat = GetData(user, false);
- if (dat)
- {
- std::string str = dat->ToString(proto);
- proto->ProtoSendMetaData(opaque, user, "callerid_data", str);
- }
- }
-
- virtual void OnDecodeMetaData(Extensible* target, const std::string& extname, const std::string& extdata)
- {
- User* u = dynamic_cast<User*>(target);
- if (u && extname == "callerid_data")
- {
- callerid_data* dat = new callerid_data(extdata, ServerInstance);
- u->Extend("callerid_data", dat);
- }
- }
-
- virtual ModResult OnUserPreNick(User* user, const std::string& newnick)
+ ModResult OnUserPreNick(User* user, const std::string& newnick)
{
if (!tracknick)
RemoveFromAllAccepts(user);
return MOD_RES_PASSTHRU;
}
- virtual void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
+ void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
{
RemoveFromAllAccepts(user);
- RemoveData(user);
}
virtual void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
- mycommand.maxaccepts = Conf.ReadInteger("callerid", "maxaccepts", "16", 0, true);
+ cmd.maxaccepts = Conf.ReadInteger("callerid", "maxaccepts", "16", 0, true);
operoverride = Conf.ReadFlag("callerid", "operoverride", "0", 0);
tracknick = Conf.ReadFlag("callerid", "tracknick", "0", 0);
notify_cooldown = Conf.ReadInteger("callerid", "cooldown", "60", 0, true);
diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp
index 626b4c23c..160c7a9c9 100644
--- a/src/modules/m_cap.cpp
+++ b/src/modules/m_cap.cpp
@@ -35,7 +35,9 @@ CAP END
class CommandCAP : public Command
{
public:
- CommandCAP (InspIRCd* Instance, Module* mod) : Command(Instance, mod, "CAP", 0, 1, true)
+ LocalIntExt reghold;
+ CommandCAP (InspIRCd* Instance, Module* mod) : Command(Instance, mod, "CAP", 0, 1, true),
+ reghold("CAP_REGHOLD", mod)
{
}
@@ -64,7 +66,7 @@ class CommandCAP : public Command
Data.wanted.push_back(cap_);
}
- user->Extend("CAP_REGHOLD");
+ reghold.set(user, 1);
Event event((char*) &Data, this->creator, "cap_req");
event.Send(this->ServerInstance);
@@ -82,7 +84,7 @@ class CommandCAP : public Command
}
else if (subcommand == "END")
{
- user->Shrink("CAP_REGHOLD");
+ reghold.set(user, 0);
}
else if ((subcommand == "LS") || (subcommand == "LIST"))
{
@@ -92,7 +94,7 @@ class CommandCAP : public Command
Data.user = user;
Data.creator = this->creator;
- user->Extend("CAP_REGHOLD");
+ reghold.set(user, 1);
Event event((char*) &Data, this->creator, subcommand == "LS" ? "cap_ls" : "cap_list");
event.Send(this->ServerInstance);
@@ -112,7 +114,7 @@ class CommandCAP : public Command
Data.user = user;
Data.creator = this->creator;
- user->Extend("CAP_REGHOLD");
+ reghold.set(user, 1);
Event event((char*) &Data, this->creator, "cap_clear");
event.Send(this->ServerInstance);
@@ -130,33 +132,34 @@ class CommandCAP : public Command
class ModuleCAP : public Module
{
- CommandCAP newcommand;
+ CommandCAP cmd;
public:
ModuleCAP(InspIRCd* Me)
- : Module(Me), newcommand(Me, this)
+ : Module(Me), cmd(Me, this)
{
- ServerInstance->AddCommand(&newcommand);
+ ServerInstance->AddCommand(&cmd);
+ Extensible::Register(&cmd.reghold);
Implementation eventlist[] = { I_OnCheckReady };
ServerInstance->Modules->Attach(eventlist, this, 1);
}
- virtual ModResult OnCheckReady(User* user)
+ ModResult OnCheckReady(User* user)
{
/* Users in CAP state get held until CAP END */
- if (user->GetExt("CAP_REGHOLD"))
+ if (cmd.reghold.get(user))
return MOD_RES_DENY;
return MOD_RES_PASSTHRU;
}
- virtual ~ModuleCAP()
+ ~ModuleCAP()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$", VF_VENDOR, API_VERSION);
+ return Version("Client CAP extension support", VF_VENDOR);
}
};
diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h
index ce5aec8ba..72c7a14a5 100644
--- a/src/modules/m_cap.h
+++ b/src/modules/m_cap.h
@@ -27,42 +27,53 @@ class CapData : public classbase
Module* creator;
};
-void GenericCapHandler(Event* ev, const std::string &extname, const std::string &cap)
+class GenericCap
{
- if (ev->GetEventID() == "cap_req")
+ public:
+ LocalIntExt ext;
+ const std::string cap;
+ GenericCap(Module* parent, const std::string &Cap) : ext("cap_" + cap, parent), cap(Cap)
{
- CapData *data = (CapData *) ev->GetData();
-
- std::vector<std::string>::iterator it;
- if ((it = std::find(data->wanted.begin(), data->wanted.end(), cap)) != data->wanted.end())
- {
- // we can handle this, so ACK it, and remove it from the wanted list
- data->ack.push_back(*it);
- data->wanted.erase(it);
- data->user->Extend(extname);
- }
+ Extensible::Register(&ext);
}
- if (ev->GetEventID() == "cap_ls")
+ void HandleEvent(Event* ev)
{
- CapData *data = (CapData *) ev->GetData();
- data->wanted.push_back(cap);
- }
+ if (ev->GetEventID() == "cap_req")
+ {
+ CapData *data = (CapData *) ev->GetData();
- if (ev->GetEventID() == "cap_list")
- {
- CapData *data = (CapData *) ev->GetData();
+ std::vector<std::string>::iterator it;
+ if ((it = std::find(data->wanted.begin(), data->wanted.end(), cap)) != data->wanted.end())
+ {
+ // we can handle this, so ACK it, and remove it from the wanted list
+ data->ack.push_back(*it);
+ data->wanted.erase(it);
+ ext.set(data->user, 1);
+ }
+ }
- if (data->user->GetExt(extname))
+ if (ev->GetEventID() == "cap_ls")
+ {
+ CapData *data = (CapData *) ev->GetData();
data->wanted.push_back(cap);
- }
+ }
- if (ev->GetEventID() == "cap_clear")
- {
- CapData *data = (CapData *) ev->GetData();
- data->ack.push_back("-" + cap);
- data->user->Shrink(extname);
+ if (ev->GetEventID() == "cap_list")
+ {
+ CapData *data = (CapData *) ev->GetData();
+
+ if (ext.get(data->user))
+ data->wanted.push_back(cap);
+ }
+
+ if (ev->GetEventID() == "cap_clear")
+ {
+ CapData *data = (CapData *) ev->GetData();
+ data->ack.push_back("-" + cap);
+ ext.set(data->user, 0);
+ }
}
-}
+};
#endif
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index 41c2154cc..c72e18390 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -53,11 +53,18 @@ typedef std::vector<CGIhost> CGIHostlist;
*/
class CommandWebirc : public Command
{
- bool notify;
- public:
- CGIHostlist Hosts;
- CommandWebirc(InspIRCd* Instance, Module* Creator, bool bnotify)
- : Command(Instance, Creator, "WEBIRC", 0, 4, true), notify(bnotify)
+ bool notify;
+ public:
+ StringExtItem realhost;
+ StringExtItem realip;
+ LocalStringExt webirc_hostname;
+ LocalStringExt webirc_ip;
+
+ CGIHostlist Hosts;
+ CommandWebirc(InspIRCd* Instance, Module* Creator, bool bnotify)
+ : Command(Instance, Creator, "WEBIRC", 0, 4, true), notify(bnotify),
+ realhost("cgiirc_realhost", Creator), realip("cgiirc_realip", Creator),
+ webirc_hostname("cgiirc_webirc_hostname", Creator), webirc_ip("cgiirc_webirc_ip", Creator)
{
this->syntax = "password client hostname ip";
}
@@ -72,12 +79,12 @@ class CommandWebirc : public Command
{
if(iter->type == WEBIRC && parameters[0] == iter->password)
{
- user->Extend("cgiirc_realhost", new std::string(user->host));
- user->Extend("cgiirc_realip", new std::string(user->GetIPString()));
+ realhost.set(user, user->host);
+ realip.set(user, user->GetIPString());
if (notify)
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", user->nick.c_str(), user->host.c_str(), parameters[2].c_str(), user->host.c_str());
- user->Extend("cgiirc_webirc_hostname", new std::string(parameters[2]));
- user->Extend("cgiirc_webirc_ip", new std::string(parameters[3]));
+ webirc_hostname.set(user, parameters[2]);
+ webirc_ip.set(user, parameters[3]);
return CMD_SUCCESS;
}
}
@@ -142,6 +149,10 @@ public:
{
OnRehash(NULL);
ServerInstance->AddCommand(&cmd);
+ Extensible::Register(&cmd.realhost);
+ Extensible::Register(&cmd.realip);
+ Extensible::Register(&cmd.webirc_hostname);
+ Extensible::Register(&cmd.webirc_ip);
Implementation eventlist[] = { I_OnRehash, I_OnUserRegister, I_OnCleanup, I_OnSyncUser, I_OnDecodeMetaData, I_OnUserDisconnect, I_OnUserConnect };
ServerInstance->Modules->Attach(eventlist, this, 7);
@@ -202,53 +213,6 @@ public:
}
}
- virtual void OnCleanup(int target_type, void* item)
- {
- if(target_type == TYPE_USER)
- {
- User* user = (User*)item;
- std::string* realhost;
- std::string* realip;
-
- if(user->GetExt("cgiirc_realhost", realhost))
- {
- delete realhost;
- user->Shrink("cgiirc_realhost");
- }
-
- if(user->GetExt("cgiirc_realip", realip))
- {
- delete realip;
- user->Shrink("cgiirc_realip");
- }
- }
- }
-
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- std::string* data;
- if (user->GetExt("cgiirc_realhost", data))
- proto->ProtoSendMetaData(opaque, user, "cgiirc_realhost", *data);
- if (user->GetExt("cgiirc_realip", data))
- proto->ProtoSendMetaData(opaque, user, "cgiirc_realip", *data);
- }
-
- virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
- {
- User* dest = dynamic_cast<User*>(target);
- std::string* bleh;
- if(dest && ((extname == "cgiirc_realhost") || (extname == "cgiirc_realip")) && (!dest->GetExt(extname, bleh)))
- {
- dest->Extend(extname, new std::string(extdata));
- }
- }
-
- virtual void OnUserDisconnect(User* user)
- {
- OnCleanup(TYPE_USER, user);
- }
-
-
virtual ModResult OnUserRegister(User* user)
{
for(CGIHostlist::iterator iter = cmd.Hosts.begin(); iter != cmd.Hosts.end(); iter++)
@@ -290,22 +254,21 @@ public:
virtual void OnUserConnect(User* user)
{
- std::string *webirc_hostname, *webirc_ip;
- if(user->GetExt("cgiirc_webirc_hostname", webirc_hostname))
+ std::string *webirc_hostname = cmd.webirc_hostname.get(user);
+ std::string *webirc_ip = cmd.webirc_ip.get(user);
+ if (webirc_hostname)
{
user->host.assign(*webirc_hostname, 0, 64);
user->dhost.assign(*webirc_hostname, 0, 64);
- delete webirc_hostname;
user->InvalidateCache();
- user->Shrink("cgiirc_webirc_hostname");
+ cmd.webirc_hostname.unset(user);
}
- if(user->GetExt("cgiirc_webirc_ip", webirc_ip))
+ if (webirc_ip)
{
ServerInstance->Users->RemoveCloneCounts(user);
user->SetClientIP(webirc_ip->c_str());
- delete webirc_ip;
user->InvalidateCache();
- user->Shrink("cgiirc_webirc_ip");
+ cmd.webirc_ip.unset(user);
ServerInstance->Users->AddLocalClone(user);
ServerInstance->Users->AddGlobalClone(user);
user->CheckClass();
@@ -317,8 +280,8 @@ public:
{
if(IsValidHost(user->password))
{
- user->Extend("cgiirc_realhost", new std::string(user->host));
- user->Extend("cgiirc_realip", new std::string(user->GetIPString()));
+ cmd.realhost.set(user, user->host);
+ cmd.realip.set(user, user->GetIPString());
user->host.assign(user->password, 0, 64);
user->dhost.assign(user->password, 0, 64);
user->InvalidateCache();
@@ -380,8 +343,8 @@ public:
newip.s_addr = htonl(ipaddr);
char* newipstr = inet_ntoa(newip);
- user->Extend("cgiirc_realhost", new std::string(user->host));
- user->Extend("cgiirc_realip", new std::string(user->GetIPString()));
+ cmd.realhost.set(user, user->host);
+ cmd.realip.set(user, user->GetIPString());
ServerInstance->Users->RemoveCloneCounts(user);
user->SetClientIP(newipstr);
ServerInstance->Users->AddLocalClone(user);
diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp
index 4f6ebf22a..4636d2372 100644
--- a/src/modules/m_chanfilter.cpp
+++ b/src/modules/m_chanfilter.cpp
@@ -76,11 +76,6 @@ class ModuleChanFilter : public Module
ServerInstance->Modules->PublishInterface("ChannelBanList", this);
}
- virtual void OnChannelDelete(Channel* chan)
- {
- cf.DoChannelDelete(chan);
- }
-
virtual void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
@@ -93,8 +88,7 @@ class ModuleChanFilter : public Module
if (!IS_LOCAL(user) || (CHANOPS_EXEMPT(ServerInstance, 'g') && chan->GetStatus(user) == STATUS_OP))
return MOD_RES_PASSTHRU;
- modelist* list;
- chan->GetExt(cf.GetInfoKey(), list);
+ modelist* list = cf.extItem.get(chan);
if (list)
{
diff --git a/src/modules/m_channelban.cpp b/src/modules/m_channelban.cpp
index 8167b8aae..fd5d5d401 100644
--- a/src/modules/m_channelban.cpp
+++ b/src/modules/m_channelban.cpp
@@ -25,16 +25,16 @@ class ModuleBadChannelExtban : public Module
ServerInstance->Modules->Attach(eventlist, this, 2);
}
- virtual ~ModuleBadChannelExtban()
+ ~ModuleBadChannelExtban()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON|VF_VENDOR,API_VERSION);
}
- virtual ModResult OnCheckBan(User *user, Channel *c)
+ ModResult OnCheckBan(User *user, Channel *c)
{
ModResult rv;
for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
@@ -45,7 +45,7 @@ class ModuleBadChannelExtban : public Module
return rv;
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
ServerInstance->AddExtBanChar('j');
}
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 7f85b1869..964a8c075 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -20,7 +20,6 @@
class CommandCheck : public Command
{
public:
- std::set<std::string> meta_seen;
CommandCheck (InspIRCd* Instance, Module* parent) : Command(Instance,parent,"CHECK", "o", 1)
{
syntax = "<nickname>|<ip>|<hostmask>|<channel> <server>";
@@ -34,17 +33,20 @@ class CommandCheck : public Command
return std::string(timebuf);
}
- void dumpExtra(User* user, std::string checkstr, Extensible* ext)
+ void dumpExt(User* user, std::string checkstr, Extensible* ext)
{
- std::deque<std::string> extlist;
- ext->GetExtList(extlist);
std::stringstream dumpkeys;
- for(std::deque<std::string>::iterator i = extlist.begin(); i != extlist.end(); i++)
+ for(ExtensibleStore::const_iterator i = ext->GetExtList().begin(); i != ext->GetExtList().end(); i++)
{
- if (meta_seen.find(*i) == meta_seen.end())
- dumpkeys << " " << *i;
+ ExtensionItem* item = Extensible::GetItem(i->first);
+ std::string value;
+ if (item)
+ value = item->serialize(creator, ext, i->second);
+ if (value.empty())
+ dumpkeys << " " << i->first;
+ else
+ ServerInstance->DumpText(user, checkstr + " meta:" + i->first + " " + value);
}
- meta_seen.clear();
if (!dumpkeys.str().empty())
ServerInstance->DumpText(user,checkstr + " metadata", dumpkeys);
}
@@ -118,8 +120,7 @@ class CommandCheck : public Command
ServerInstance->DumpText(user,checkstr + " onchans", dump);
- FOREACH_MOD_I(ServerInstance,I_OnSyncUser,OnSyncUser(targuser,creator,(void*)user));
- dumpExtra(user, checkstr, targuser);
+ dumpExt(user, checkstr, targuser);
}
else if (targchan)
{
@@ -152,8 +153,7 @@ class CommandCheck : public Command
ServerInstance->DumpText(user, checkstr + " member " + tmpbuf);
}
- FOREACH_MOD_I(ServerInstance,I_OnSyncChannel,OnSyncChannel(targchan,creator,(void*)user));
- dumpExtra(user, checkstr, targchan);
+ dumpExt(user, checkstr, targchan);
}
else
{
@@ -203,24 +203,16 @@ class ModuleCheck : public Module
ServerInstance->AddCommand(&mycommand);
}
- virtual ~ModuleCheck()
- {
- }
-
- virtual Version GetVersion()
+ ~ModuleCheck()
{
- return Version("$Id$", VF_VENDOR|VF_OPTCOMMON, API_VERSION);
}
- virtual void ProtoSendMetaData(void* opaque, Extensible* target, const std::string& name, const std::string& value)
+ Version GetVersion()
{
- User* user = static_cast<User*>(opaque);
- ServerInstance->DumpText(user, std::string(":") + ServerInstance->Config->ServerName + " 304 " + std::string(user->nick)
- + " :CHECK meta:" + name + " " + value);
- mycommand.meta_seen.insert(name);
+ return Version("CHECK command, view user/channel details", VF_VENDOR|VF_OPTCOMMON);
}
- virtual std::string ProtoTranslate(Extensible* item)
+ std::string ProtoTranslate(Extensible* item)
{
User* u = dynamic_cast<User*>(item);
Channel* c = dynamic_cast<Channel*>(item);
diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp
index 2fa3b9e63..2a348ba8b 100644
--- a/src/modules/m_cloaking.cpp
+++ b/src/modules/m_cloaking.cpp
@@ -30,6 +30,7 @@ class CloakUser : public ModeHandler
bool ipalways;
Module* HashProvider;
const char *xtab[4];
+ LocalStringExt ext;
/** This function takes a domain name string and returns just the last two domain parts,
* or the last domain part if only two are available. Failing that it just returns what it was given.
@@ -63,7 +64,8 @@ class CloakUser : public ModeHandler
}
CloakUser(InspIRCd* Instance, Module* source, Module* Hash)
- : ModeHandler(Instance, source, 'x', 0, 0, false, MODETYPE_USER, false), HashProvider(Hash)
+ : ModeHandler(Instance, source, 'x', 0, 0, false, MODETYPE_USER, false), HashProvider(Hash),
+ ext("cloaked_host", source)
{
}
@@ -95,14 +97,15 @@ class CloakUser : public ModeHandler
* are connecting via localhost) -- this doesnt matter much.
*/
- std::string* cloak;
+ std::string* cloak = ext.get(dest);
- if (!dest->GetExt("cloaked_host", cloak))
+ if (!cloak)
{
/* Force creation of missing cloak */
creator->OnUserConnect(dest);
+ cloak = ext.get(dest);
}
- if (dest->GetExt("cloaked_host", cloak))
+ if (cloak)
{
dest->ChangeDisplayedHost(cloak->c_str());
dest->SetMode('x',true);
@@ -281,40 +284,35 @@ class ModuleCloaking : public Module
}
ServerInstance->Modules->UseInterface("HashRequest");
+ Extensible::Register(&cu->ext);
- Implementation eventlist[] = { I_OnRehash, I_OnUserDisconnect, I_OnCleanup, I_OnCheckBan, I_OnUserConnect, I_OnSyncUser, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 6);
+ Implementation eventlist[] = { I_OnRehash, I_OnCheckBan, I_OnUserConnect };
+ ServerInstance->Modules->Attach(eventlist, this, 3);
CloakExistingUsers();
}
- void OnSyncUser(User* user, Module* proto,void* opaque)
- {
- std::string* cloak;
- if (user->GetExt("cloaked_host", cloak) && proto->ProtoTranslate(NULL) == "?")
- proto->ProtoSendMetaData(opaque, user, "cloaked_host", *cloak);
- }
-
void CloakExistingUsers()
{
std::string* cloak;
for (std::vector<User*>::iterator u = ServerInstance->Users->local_users.begin(); u != ServerInstance->Users->local_users.end(); u++)
{
- if (!(*u)->GetExt("cloaked_host", cloak))
+ cloak = cu->ext.get(*u);
+ if (!cloak)
{
OnUserConnect(*u);
}
}
}
- virtual ModResult OnCheckBan(User* user, Channel* chan)
+ ModResult OnCheckBan(User* user, Channel* chan)
{
char mask[MAXBUF];
- std::string* tofree;
+ std::string* cloak = cu->ext.get(user);
/* Check if they have a cloaked host, but are not using it */
- if (user->GetExt("cloaked_host", tofree) && *tofree != user->dhost)
+ if (cloak && *cloak != user->dhost)
{
- snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), tofree->c_str());
+ snprintf(mask, MAXBUF, "%s!%s@%s", user->nick.c_str(), user->ident.c_str(), cloak->c_str());
for (BanList::iterator i = chan->bans.begin(); i != chan->bans.end(); i++)
{
if (InspIRCd::Match(mask,i->data))
@@ -334,45 +332,29 @@ class ModuleCloaking : public Module
ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIORITY_AFTER, &um);
}
- virtual void OnUserDisconnect(User* user)
- {
- std::string* tofree;
- if (user->GetExt("cloaked_host", tofree))
- {
- delete tofree;
- user->Shrink("cloaked_host");
- }
- }
-
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type == TYPE_USER)
- OnUserDisconnect((User*)item);
- }
-
- virtual ~ModuleCloaking()
+ ~ModuleCloaking()
{
ServerInstance->Modes->DelMode(cu);
delete cu;
ServerInstance->Modules->DoneWithInterface("HashRequest");
}
- virtual Version GetVersion()
+ Version GetVersion()
{
// returns the version number of the module to be
// listed in /MODULES
return Version("$Id$", VF_COMMON|VF_VENDOR,API_VERSION);
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
cu->DoRehash();
}
- virtual void OnUserConnect(User* dest)
+ void OnUserConnect(User* dest)
{
- std::string* tofree;
- if (dest->GetExt("cloaked_host", tofree))
+ std::string* cloak = cu->ext.get(dest);
+ if (cloak)
return;
if (dest->host.find('.') != std::string::npos || dest->host.find(':') != std::string::npos)
@@ -423,7 +405,7 @@ class ModuleCloaking : public Module
b = cu->Cloak4(dest->GetIPString());
}
- dest->Extend("cloaked_host", new std::string(b));
+ cu->ext.set(dest,b);
}
}
diff --git a/src/modules/m_conn_waitpong.cpp b/src/modules/m_conn_waitpong.cpp
index 4da240138..b77116410 100644
--- a/src/modules/m_conn_waitpong.cpp
+++ b/src/modules/m_conn_waitpong.cpp
@@ -19,18 +19,18 @@ class ModuleWaitPong : public Module
{
bool sendsnotice;
bool killonbadreply;
- const char* extenstr;
+ LocalStringExt ext;
public:
ModuleWaitPong(InspIRCd* Me)
- : Module(Me), extenstr("waitpong_pingstr")
+ : Module(Me), ext("waitpong_pingstr", this)
{
OnRehash(NULL);
- Implementation eventlist[] = { I_OnUserRegister, I_OnCheckReady, I_OnPreCommand, I_OnRehash, I_OnUserDisconnect, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 6);
+ Implementation eventlist[] = { I_OnUserRegister, I_OnCheckReady, I_OnPreCommand, I_OnRehash };
+ ServerInstance->Modules->Attach(eventlist, this, 4);
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
@@ -45,43 +45,40 @@ class ModuleWaitPong : public Module
killonbadreply = true;
}
-
- char* RandString(unsigned int length)
+ std::string RandString()
{
- unsigned char* out = new unsigned char[length+1];
- for(unsigned int i = 0; i < length; i++)
+ char out[11];
+ for(unsigned int i = 0; i < 10; i++)
out[i] = ((rand() % 26) + 65);
- out[length] = '\0';
+ out[10] = '\0';
- return (char*)out;
+ return out;
}
- virtual ModResult OnUserRegister(User* user)
+ ModResult OnUserRegister(User* user)
{
- char* pingrpl = RandString(10);
+ std::string pingrpl = RandString();
- user->Write("PING :%s", pingrpl);
+ user->Write("PING :%s", pingrpl.c_str());
if(sendsnotice)
- user->WriteServ("NOTICE %s :*** If you are having problems connecting due to ping timeouts, please type /quote PONG %s or /raw PONG %s now.", user->nick.c_str(), pingrpl, pingrpl);
+ user->WriteServ("NOTICE %s :*** If you are having problems connecting due to ping timeouts, please type /quote PONG %s or /raw PONG %s now.", user->nick.c_str(), pingrpl.c_str(), pingrpl.c_str());
- user->Extend(extenstr, pingrpl);
+ ext.set(user, pingrpl);
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User* user, bool validated, const std::string &original_line)
+ ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User* user, bool validated, const std::string &original_line)
{
if (command == "PONG")
{
- char* pingrpl;
- user->GetExt(extenstr, pingrpl);
+ std::string* pingrpl = ext.get(user);
if (pingrpl)
{
- if (!parameters.empty() && (strcmp(pingrpl, parameters[0].c_str()) == 0))
+ if (!parameters.empty() && *pingrpl == parameters[0])
{
- delete[] pingrpl;
- user->Shrink(extenstr);
+ ext.unset(user);
return MOD_RES_DENY;
}
else
@@ -95,47 +92,18 @@ class ModuleWaitPong : public Module
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnCheckReady(User* user)
- {
- char* pingrpl;
- return user->GetExt(extenstr, pingrpl) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
- }
-
- virtual void OnUserDisconnect(User* user)
- {
- char* pingrpl;
- user->GetExt(extenstr, pingrpl);
-
- if (pingrpl)
- {
- delete[] pingrpl;
- user->Shrink(extenstr);
- }
- }
-
- virtual void OnCleanup(int target_type, void* item)
+ ModResult OnCheckReady(User* user)
{
- if (target_type == TYPE_USER)
- {
- User* user = (User*)item;
- char* pingrpl;
- user->GetExt(extenstr, pingrpl);
-
- if (pingrpl)
- {
- delete[] pingrpl;
- user->Shrink(extenstr);
- }
- }
+ return ext.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
}
- virtual ~ModuleWaitPong()
+ ~ModuleWaitPong()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$", VF_VENDOR, API_VERSION);
+ return Version("Require pong prior to registration", VF_VENDOR);
}
};
diff --git a/src/modules/m_customtitle.cpp b/src/modules/m_customtitle.cpp
index b2933aa54..fc99cd29f 100644
--- a/src/modules/m_customtitle.cpp
+++ b/src/modules/m_customtitle.cpp
@@ -20,7 +20,9 @@
class CommandTitle : public Command
{
public:
- CommandTitle (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"TITLE",0,2)
+ StringExtItem ctitle;
+ CommandTitle (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"TITLE",0,2),
+ ctitle("ctitle", Creator)
{
syntax = "<user> <password>";
TRANSLATE3(TR_NICK, TR_TEXT, TR_END);
@@ -60,17 +62,9 @@ class CommandTitle : public Command
if (!strcmp(name.c_str(),parameters[0].c_str()) && !ServerInstance->PassCompare(user, pass.c_str(), parameters[1].c_str(), hash.c_str()) && OneOfMatches(TheHost,TheIP,host.c_str()) && !title.empty())
{
- std::string* text;
- if (user->GetExt("ctitle", text))
- {
- user->Shrink("ctitle");
- delete text;
- }
+ ctitle.set(user, title);
- text = new std::string(title);
- user->Extend("ctitle", text);
-
- ServerInstance->PI->SendMetaData(user, "ctitle", *text);
+ ServerInstance->PI->SendMetaData(user, "ctitle", title);
if (!vhost.empty())
user->ChangeDisplayedHost(vhost.c_str());
@@ -95,11 +89,10 @@ class ModuleCustomTitle : public Module
ModuleCustomTitle(InspIRCd* Me) : Module(Me), cmd(Me, this)
{
ServerInstance->AddCommand(&cmd);
- Implementation eventlist[] = { I_OnDecodeMetaData, I_OnWhoisLine, I_OnSyncUser, I_OnUserQuit, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 5);
+ Extensible::Register(&cmd.ctitle);
+ ServerInstance->Modules->Attach(I_OnWhoisLine, this);
}
-
// :kenny.chatspike.net 320 Brain Azhrarn :is getting paid to play games.
ModResult OnWhoisLine(User* user, User* dest, int &numeric, std::string &text)
{
@@ -107,89 +100,23 @@ class ModuleCustomTitle : public Module
if (numeric == 312)
{
/* Insert our numeric before 312 */
- std::string* ctitle;
- if (dest->GetExt("ctitle", ctitle))
+ const std::string* ctitle = cmd.ctitle.get(dest);
+ if (ctitle)
{
ServerInstance->SendWhoisLine(user, dest, 320, "%s %s :%s",user->nick.c_str(), dest->nick.c_str(), ctitle->c_str());
}
}
- /* Dont block anything */
+ /* Don't block anything */
return MOD_RES_PASSTHRU;
}
- // Whenever the linking module wants to send out data, but doesnt know what the data
- // represents (e.g. it is metadata, added to a User or Channel by a module) then
- // this method is called. We should use the ProtoSendMetaData function after we've
- // corrected decided how the data should look, to send the metadata on its way if
- // it is ours.
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- // check if this user has an ctitle field to send
- std::string* ctitle;
- if (user->GetExt("ctitle", ctitle))
- proto->ProtoSendMetaData(opaque,user,"ctitle",*ctitle);
- }
-
- // when a user quits, tidy up their metadata
- virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message)
- {
- std::string* ctitle;
- if (user->GetExt("ctitle", ctitle))
- {
- user->Shrink("ctitle");
- delete ctitle;
- }
- }
-
- // if the module is unloaded, tidy up all our dangling metadata
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type == TYPE_USER)
- {
- User* user = (User*)item;
- std::string* ctitle;
- if (user->GetExt("ctitle", ctitle))
- {
- user->Shrink("ctitle");
- delete ctitle;
- }
- }
- }
-
- // Whenever the linking module receives metadata from another server and doesnt know what
- // to do with it (of course, hence the 'meta') it calls this method, and it is up to each
- // module in turn to figure out if this metadata key belongs to them, and what they want
- // to do with it.
- // In our case we're only sending a single string around, so we just construct a std::string.
- // Some modules will probably get much more complex and format more detailed structs and classes
- // in a textual way for sending over the link.
- virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
- {
- User* dest = dynamic_cast<User*>(target);
- // check if its our metadata key, and its associated with a user
- if (dest && (extname == "ctitle"))
- {
- std::string* text;
- if (dest->GetExt("ctitle", text))
- {
- dest->Shrink("ctitle");
- delete text;
- }
- if (!extdata.empty())
- {
- text = new std::string(extdata);
- dest->Extend("ctitle", text);
- }
- }
- }
-
- virtual ~ModuleCustomTitle()
+ ~ModuleCustomTitle()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+ return Version("Custom Title for users", VF_COMMON | VF_VENDOR);
}
};
diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp
index 690d7b15c..e5c8940ec 100644
--- a/src/modules/m_ident.cpp
+++ b/src/modules/m_ident.cpp
@@ -280,11 +280,11 @@ class IdentRequestSocket : public EventHandler
class ModuleIdent : public Module
{
- private:
int RequestTimeout;
ConfigReader *Conf;
+ SimpleExtItem<IdentRequestSocket> ext;
public:
- ModuleIdent(InspIRCd *Me) : Module(Me)
+ ModuleIdent(InspIRCd *Me) : Module(Me), ext("ident_socket", this)
{
Conf = new ConfigReader(ServerInstance);
OnRehash(NULL);
@@ -338,7 +338,7 @@ class ModuleIdent : public Module
try
{
IdentRequestSocket *isock = new IdentRequestSocket(ServerInstance, user);
- user->Extend("ident_socket", isock);
+ ext.set(user, isock);
}
catch (ModuleException &e)
{
@@ -355,8 +355,8 @@ class ModuleIdent : public Module
virtual ModResult OnCheckReady(User *user)
{
/* Does user have an ident socket attached at all? */
- IdentRequestSocket *isock = NULL;
- if (!user->GetExt("ident_socket", isock))
+ IdentRequestSocket *isock = ext.get(user);
+ if (!isock)
{
ServerInstance->Logs->Log("m_ident",DEBUG, "No ident socket :(");
return MOD_RES_PASSTHRU;
@@ -413,12 +413,11 @@ class ModuleIdent : public Module
virtual void OnUserDisconnect(User *user)
{
/* User disconnect (generic socket detatch event) */
- IdentRequestSocket *isock = NULL;
- if (user->GetExt("ident_socket", isock))
+ IdentRequestSocket *isock = ext.get(user);
+ if (isock)
{
isock->Close();
- delete isock;
- user->Shrink("ident_socket");
+ ext.unset(user);
}
}
};
diff --git a/src/modules/m_inviteexception.cpp b/src/modules/m_inviteexception.cpp
index 29d7eb5d5..0b3621af7 100644
--- a/src/modules/m_inviteexception.cpp
+++ b/src/modules/m_inviteexception.cpp
@@ -52,17 +52,16 @@ public:
ServerInstance->Modules->Attach(eventlist, this, 3);
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
output.append(" INVEX=I");
}
- virtual ModResult OnCheckInvite(User* user, Channel* chan)
+ ModResult OnCheckInvite(User* user, Channel* chan)
{
if(chan != NULL)
{
- modelist* list;
- chan->GetExt(ie.GetInfoKey(), list);
+ modelist* list = ie.extItem.get(chan);
if (list)
{
std::string mask = std::string(user->nick) + "!" + user->ident + "@" + user->GetIPString();
@@ -81,32 +80,27 @@ public:
return MOD_RES_PASSTHRU;
}
- virtual const char* OnRequest(Request* request)
+ const char* OnRequest(Request* request)
{
return ie.DoOnRequest(request);
}
- virtual void OnCleanup(int target_type, void* item)
+ void OnCleanup(int target_type, void* item)
{
ie.DoCleanup(target_type, item);
}
- virtual void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
+ void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
{
ie.DoSyncChannel(chan, proto, opaque);
}
- virtual void OnChannelDelete(Channel* chan)
- {
- ie.DoChannelDelete(chan);
- }
-
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ie.DoRehash();
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_VENDOR | VF_COMMON, API_VERSION);
}
diff --git a/src/modules/m_joinflood.cpp b/src/modules/m_joinflood.cpp
index 180d58376..853ddee75 100644
--- a/src/modules/m_joinflood.cpp
+++ b/src/modules/m_joinflood.cpp
@@ -86,12 +86,14 @@ class joinfloodsettings : public classbase
class JoinFlood : public ModeHandler
{
public:
- JoinFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'j', 1, 0, false, MODETYPE_CHANNEL, false) { }
+ SimpleExtItem<joinfloodsettings> ext;
+ JoinFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'j', 1, 0, false, MODETYPE_CHANNEL, false),
+ ext("joinflood", Creator) { }
ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
{
- joinfloodsettings* x;
- if (channel->GetExt("joinflood",x))
+ joinfloodsettings* x = ext.get(channel);
+ if (x)
return std::make_pair(true, ConvToStr(x->joins)+":"+ConvToStr(x->secs));
else
return std::make_pair(false, parameter);
@@ -99,8 +101,6 @@ class JoinFlood : public ModeHandler
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
{
- joinfloodsettings* dummy;
-
if (adding)
{
char ndata[MAXBUF];
@@ -133,11 +133,12 @@ class JoinFlood : public ModeHandler
}
else
{
- if (!channel->GetExt("joinflood", dummy))
+ joinfloodsettings* f = ext.get(channel);
+ if (!f)
{
parameter = ConvToStr(njoins) + ":" +ConvToStr(nsecs);
- joinfloodsettings *f = new joinfloodsettings(ServerInstance, nsecs, njoins);
- channel->Extend("joinflood", f);
+ f = new joinfloodsettings(ServerInstance, nsecs, njoins);
+ ext.set(channel, f);
channel->SetModeParam('j', parameter);
return MODEACTION_ALLOW;
}
@@ -155,12 +156,8 @@ class JoinFlood : public ModeHandler
// new mode param, replace old with new
if ((nsecs > 0) && (njoins > 0))
{
- joinfloodsettings* f;
- channel->GetExt("joinflood", f);
- delete f;
f = new joinfloodsettings(ServerInstance, nsecs, njoins);
- channel->Shrink("joinflood");
- channel->Extend("joinflood", f);
+ ext.set(channel, f);
channel->SetModeParam('j', parameter);
return MODEACTION_ALLOW;
}
@@ -180,12 +177,10 @@ class JoinFlood : public ModeHandler
}
else
{
- if (channel->GetExt("joinflood", dummy))
+ joinfloodsettings* f = ext.get(channel);
+ if (f)
{
- joinfloodsettings *f;
- channel->GetExt("joinflood", f);
- delete f;
- channel->Shrink("joinflood");
+ ext.unset(channel);
channel->SetModeParam('j', "");
return MODEACTION_ALLOW;
}
@@ -207,37 +202,35 @@ class ModuleJoinFlood : public Module
if (!ServerInstance->Modes->AddMode(&jf))
throw ModuleException("Could not add new modes!");
+ Extensible::Register(&jf.ext);
Implementation eventlist[] = { I_OnChannelDelete, I_OnUserPreJoin, I_OnUserJoin };
ServerInstance->Modules->Attach(eventlist, this, 3);
}
- virtual ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
+ ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
{
if (chan)
{
- joinfloodsettings *f;
- if (chan->GetExt("joinflood", f))
+ joinfloodsettings *f = jf.ext.get(chan);
+ if (f && f->islocked())
{
- if (f->islocked())
- {
- user->WriteNumeric(609, "%s %s :This channel is temporarily unavailable (+j). Please try again later.",user->nick.c_str(),chan->name.c_str());
- return MOD_RES_DENY;
- }
+ user->WriteNumeric(609, "%s %s :This channel is temporarily unavailable (+j). Please try again later.",user->nick.c_str(),chan->name.c_str());
+ return MOD_RES_DENY;
}
}
return MOD_RES_PASSTHRU;
}
- virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
+ void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created)
{
- joinfloodsettings *f;
-
/* We arent interested in JOIN events caused by a network burst */
if (sync)
return;
+ joinfloodsettings *f = jf.ext.get(channel);
+
/* But all others are OK */
- if (channel->GetExt("joinflood",f))
+ if (f)
{
f->addjoin();
if (f->shouldlock())
@@ -249,23 +242,12 @@ class ModuleJoinFlood : public Module
}
}
- void OnChannelDelete(Channel* chan)
- {
- joinfloodsettings *f;
- if (chan->GetExt("joinflood",f))
- {
- delete f;
- chan->Shrink("joinflood");
- }
- }
-
-
- virtual ~ModuleJoinFlood()
+ ~ModuleJoinFlood()
{
ServerInstance->Modes->DelMode(&jf);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
diff --git a/src/modules/m_kicknorejoin.cpp b/src/modules/m_kicknorejoin.cpp
index 04ecfffd7..47dec1803 100644
--- a/src/modules/m_kicknorejoin.cpp
+++ b/src/modules/m_kicknorejoin.cpp
@@ -15,7 +15,7 @@
/* $ModDesc: Provides channel mode +J (delay rejoin after kick) */
-inline int strtoint(const std::string &str)
+static inline int strtoint(const std::string &str)
{
std::istringstream ss(str);
int result;
@@ -30,7 +30,9 @@ typedef std::map<User*, time_t> delaylist;
class KickRejoin : public ModeHandler
{
public:
- KickRejoin(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'J', 1, 0, false, MODETYPE_CHANNEL, false) { }
+ SimpleExtItem<delaylist> ext;
+ KickRejoin(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'J', 1, 0, false, MODETYPE_CHANNEL, false),
+ ext("norejoinusers", Creator) { }
ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
{
@@ -44,14 +46,7 @@ class KickRejoin : public ModeHandler
{
if (!adding)
{
- // Taking the mode off, we need to clean up.
- delaylist* dl;
-
- if (channel->GetExt("norejoinusers", dl))
- {
- delete dl;
- channel->Shrink("norejoinusers");
- }
+ ext.unset(channel);
if (!channel->IsModeSet('J'))
{
@@ -105,7 +100,6 @@ class KickRejoin : public ModeHandler
class ModuleKickNoRejoin : public Module
{
-
KickRejoin kr;
public:
@@ -115,16 +109,17 @@ public:
{
if (!ServerInstance->Modes->AddMode(&kr))
throw ModuleException("Could not add new modes!");
- Implementation eventlist[] = { I_OnCleanup, I_OnChannelDelete, I_OnUserPreJoin, I_OnUserKick };
- ServerInstance->Modules->Attach(eventlist, this, 4);
+ Extensible::Register(&kr.ext);
+ Implementation eventlist[] = { I_OnUserPreJoin, I_OnUserKick };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
}
- virtual ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
+ ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
{
if (chan)
{
- delaylist* dl;
- if (chan->GetExt("norejoinusers", dl))
+ delaylist* dl = kr.ext.get(chan);
+ if (dl)
{
std::vector<User*> itemstoremove;
@@ -149,56 +144,34 @@ public:
dl->erase(itemstoremove[i]);
if (!dl->size())
- {
- // Now it's empty..
- delete dl;
- chan->Shrink("norejoinusers");
- }
+ kr.ext.unset(chan);
}
}
return MOD_RES_PASSTHRU;
}
- virtual void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
+ void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
{
if (chan->IsModeSet('J') && (source != user))
{
- delaylist* dl;
- if (!chan->GetExt("norejoinusers", dl))
+ delaylist* dl = kr.ext.get(chan);
+ if (dl)
{
dl = new delaylist;
- chan->Extend("norejoinusers", dl);
+ kr.ext.set(chan, dl);
}
(*dl)[user] = ServerInstance->Time() + strtoint(chan->GetModeParameter('J'));
}
}
- virtual void OnChannelDelete(Channel* chan)
- {
- delaylist* dl;
-
- if (chan->GetExt("norejoinusers", dl))
- {
- delete dl;
- chan->Shrink("norejoinusers");
- }
- }
-
- virtual void OnCleanup(int target_type, void* item)
- {
- if(target_type == TYPE_CHANNEL)
- OnChannelDelete((Channel*)item);
- }
-
-
- virtual ~ModuleKickNoRejoin()
+ ~ModuleKickNoRejoin()
{
ServerInstance->Modes->DelMode(&kr);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+ return Version("Channel mode J, kick-no-rejoin", VF_COMMON | VF_VENDOR);
}
};
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index da1038512..7d0f59481 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -76,12 +76,14 @@ class floodsettings : public classbase
class MsgFlood : public ModeHandler
{
public:
- MsgFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'f', 1, 0, false, MODETYPE_CHANNEL, false) { }
+ SimpleExtItem<floodsettings> ext;
+ MsgFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'f', 1, 0, false, MODETYPE_CHANNEL, false),
+ ext("messageflood", Creator) { }
ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
{
- floodsettings* x;
- if (channel->GetExt("flood",x))
+ floodsettings* x = ext.get(channel);
+ if (x)
return std::make_pair(true, (x->ban ? "*" : "")+ConvToStr(x->lines)+":"+ConvToStr(x->secs));
else
return std::make_pair(false, parameter);
@@ -89,7 +91,7 @@ class MsgFlood : public ModeHandler
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
{
- floodsettings *f;
+ floodsettings *f = ext.get(channel);
if (adding)
{
@@ -132,11 +134,11 @@ class MsgFlood : public ModeHandler
}
else
{
- if (!channel->GetExt("flood", f))
+ if (!f)
{
parameter = std::string(ban ? "*" : "") + ConvToStr(nlines) + ":" +ConvToStr(nsecs);
- floodsettings *fs = new floodsettings(ServerInstance,ban,nsecs,nlines);
- channel->Extend("flood",fs);
+ f = new floodsettings(ServerInstance,ban,nsecs,nlines);
+ ext.set(channel, f);
channel->SetModeParam('f', parameter);
return MODEACTION_ALLOW;
}
@@ -153,10 +155,8 @@ class MsgFlood : public ModeHandler
{
if ((((nlines != f->lines) || (nsecs != f->secs) || (ban != f->ban))) && (((nsecs > 0) && (nlines > 0))))
{
- delete f;
floodsettings *fs = new floodsettings(ServerInstance,ban,nsecs,nlines);
- channel->Shrink("flood");
- channel->Extend("flood",fs);
+ ext.set(channel, fs);
channel->SetModeParam('f', parameter);
return MODEACTION_ALLOW;
}
@@ -177,10 +177,9 @@ class MsgFlood : public ModeHandler
}
else
{
- if (channel->GetExt("flood", f))
+ if (f)
{
- delete f;
- channel->Shrink("flood");
+ ext.unset(channel);
channel->SetModeParam('f', "");
return MODEACTION_ALLOW;
}
@@ -201,8 +200,9 @@ class ModuleMsgFlood : public Module
{
if (!ServerInstance->Modes->AddMode(&mf))
throw ModuleException("Could not add new modes!");
- Implementation eventlist[] = { I_OnChannelDelete, I_OnUserPreNotice, I_OnUserPreMessage };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ Extensible::Register(&mf.ext);
+ Implementation eventlist[] = { I_OnUserPreNotice, I_OnUserPreMessage };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
}
ModResult ProcessMessages(User* user,Channel* dest, const std::string &text)
@@ -212,8 +212,8 @@ class ModuleMsgFlood : public Module
return MOD_RES_PASSTHRU;
}
- floodsettings *f;
- if (dest->GetExt("flood", f))
+ floodsettings *f = mf.ext.get(dest);
+ if (f)
{
f->addmessage(user);
if (f->shouldkick(user))
@@ -246,7 +246,7 @@ class ModuleMsgFlood : public Module
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnUserPreMessage(User *user, void *dest, int target_type, std::string &text, char status, CUList &exempt_list)
+ ModResult OnUserPreMessage(User *user, void *dest, int target_type, std::string &text, char status, CUList &exempt_list)
{
if (target_type == TYPE_CHANNEL)
return ProcessMessages(user,(Channel*)dest,text);
@@ -254,7 +254,7 @@ class ModuleMsgFlood : public Module
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnUserPreNotice(User *user, void *dest, int target_type, std::string &text, char status, CUList &exempt_list)
+ ModResult OnUserPreNotice(User *user, void *dest, int target_type, std::string &text, char status, CUList &exempt_list)
{
if (target_type == TYPE_CHANNEL)
return ProcessMessages(user,(Channel*)dest,text);
@@ -262,23 +262,12 @@ class ModuleMsgFlood : public Module
return MOD_RES_PASSTHRU;
}
- void OnChannelDelete(Channel* chan)
- {
- floodsettings* f;
- if (chan->GetExt("flood", f))
- {
- delete f;
- chan->Shrink("flood");
- }
- }
-
-
- virtual ~ModuleMsgFlood()
+ ~ModuleMsgFlood()
{
ServerInstance->Modes->DelMode(&mf);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp
index 3aa8ec355..d0970ef9c 100644
--- a/src/modules/m_namesx.cpp
+++ b/src/modules/m_namesx.cpp
@@ -19,36 +19,29 @@
class ModuleNamesX : public Module
{
public:
-
- ModuleNamesX(InspIRCd* Me)
- : Module(Me)
+ GenericCap cap;
+ ModuleNamesX(InspIRCd* Me) : Module(Me), cap(this, "multi-prefix")
{
- Implementation eventlist[] = { I_OnSyncUser, I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent };
- ServerInstance->Modules->Attach(eventlist, this, 5);
+ Implementation eventlist[] = { I_OnPreCommand, I_OnNamesListItem, I_On005Numeric, I_OnEvent };
+ ServerInstance->Modules->Attach(eventlist, this, 4);
}
- virtual ~ModuleNamesX()
- {
- }
-
- void OnSyncUser(User* user, Module* proto,void* opaque)
+ ~ModuleNamesX()
{
- if (proto->ProtoTranslate(NULL) == "?" && user->GetExt("NAMESX"))
- proto->ProtoSendMetaData(opaque, user, "NAMESX", "Enabled");
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$",VF_VENDOR,API_VERSION);
+ return Version("$Id$",VF_VENDOR);
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
output.append(" NAMESX");
}
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
+ ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
{
irc::string c = command.c_str();
/* We don't actually create a proper command handler class for PROTOCTL,
@@ -60,16 +53,16 @@ class ModuleNamesX : public Module
{
if ((parameters.size()) && (!strcasecmp(parameters[0].c_str(),"NAMESX")))
{
- user->Extend("NAMESX");
+ cap.ext.set(user, 1);
return MOD_RES_DENY;
}
}
return MOD_RES_PASSTHRU;
}
- virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+ void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
{
- if (!issuer->GetExt("NAMESX"))
+ if (!cap.ext.get(issuer))
return;
/* Some module hid this from being displayed, dont bother */
@@ -79,9 +72,9 @@ class ModuleNamesX : public Module
prefixes = channel->GetAllPrefixChars(user);
}
- virtual void OnEvent(Event *ev)
+ void OnEvent(Event *ev)
{
- GenericCapHandler(ev, "NAMESX", "multi-prefix");
+ cap.HandleEvent(ev);
}
};
diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp
index 17f3a35f0..898c7358d 100644
--- a/src/modules/m_nickflood.cpp
+++ b/src/modules/m_nickflood.cpp
@@ -90,12 +90,14 @@ class nickfloodsettings : public classbase
class NickFlood : public ModeHandler
{
public:
- NickFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'F', 1, 0, false, MODETYPE_CHANNEL, false) { }
+ SimpleExtItem<nickfloodsettings> ext;
+ NickFlood(InspIRCd* Instance, Module* Creator) : ModeHandler(Instance, Creator, 'F', 1, 0, false, MODETYPE_CHANNEL, false),
+ ext("nickflood", Creator) { }
ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
{
- nickfloodsettings* x;
- if (channel->GetExt("nickflood",x))
+ nickfloodsettings* x = ext.get(channel);
+ if (x)
return std::make_pair(true, ConvToStr(x->nicks)+":"+ConvToStr(x->secs));
else
return std::make_pair(false, parameter);
@@ -103,8 +105,7 @@ class NickFlood : public ModeHandler
ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
{
- nickfloodsettings* dummy;
-
+ nickfloodsettings *f = ext.get(channel);
if (adding)
{
char ndata[MAXBUF];
@@ -124,7 +125,6 @@ class NickFlood : public ModeHandler
else data++;
}
if (secs)
-
{
/* Set up the flood parameters for this channel */
int nnicks = atoi(nicks);
@@ -137,11 +137,11 @@ class NickFlood : public ModeHandler
}
else
{
- if (!channel->GetExt("nickflood", dummy))
+ if (!f)
{
parameter = ConvToStr(nnicks) + ":" +ConvToStr(nsecs);
- nickfloodsettings *f = new nickfloodsettings(ServerInstance, nsecs, nnicks);
- channel->Extend("nickflood", f);
+ f = new nickfloodsettings(ServerInstance, nsecs, nnicks);
+ ext.set(channel, f);
channel->SetModeParam('F', parameter);
return MODEACTION_ALLOW;
}
@@ -159,12 +159,8 @@ class NickFlood : public ModeHandler
// new mode param, replace old with new
if ((nsecs > 0) && (nnicks > 0))
{
- nickfloodsettings* f;
- channel->GetExt("nickflood", f);
- delete f;
f = new nickfloodsettings(ServerInstance, nsecs, nnicks);
- channel->Shrink("nickflood");
- channel->Extend("nickflood", f);
+ ext.set(channel, f);
channel->SetModeParam('F', parameter);
return MODEACTION_ALLOW;
}
@@ -184,12 +180,9 @@ class NickFlood : public ModeHandler
}
else
{
- if (channel->GetExt("nickflood", dummy))
+ if (f)
{
- nickfloodsettings *f;
- channel->GetExt("nickflood", f);
- delete f;
- channel->Shrink("nickflood");
+ ext.unset(channel);
channel->SetModeParam('F', "");
return MODEACTION_ALLOW;
}
@@ -200,20 +193,21 @@ class NickFlood : public ModeHandler
class ModuleNickFlood : public Module
{
- NickFlood jf;
+ NickFlood nf;
public:
ModuleNickFlood(InspIRCd* Me)
- : Module(Me), jf(Me, this)
+ : Module(Me), nf(Me, this)
{
- if (!ServerInstance->Modes->AddMode(&jf))
+ if (!ServerInstance->Modes->AddMode(&nf))
throw ModuleException("Could not add new modes!");
- Implementation eventlist[] = { I_OnChannelDelete, I_OnUserPreNick, I_OnUserPostNick };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ Extensible::Register(&nf.ext);
+ Implementation eventlist[] = { I_OnUserPreNick, I_OnUserPostNick };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
}
- virtual ModResult OnUserPreNick(User* user, const std::string &newnick)
+ ModResult OnUserPreNick(User* user, const std::string &newnick)
{
if (isdigit(newnick[0])) /* allow switches to UID */
return MOD_RES_PASSTHRU;
@@ -222,8 +216,8 @@ class ModuleNickFlood : public Module
{
Channel *channel = i->first;
- nickfloodsettings *f;
- if (channel->GetExt("nickflood", f))
+ nickfloodsettings *f = nf.ext.get(channel);
+ if (f)
{
if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetStatus(user) == STATUS_OP)
continue;
@@ -250,7 +244,7 @@ class ModuleNickFlood : public Module
/*
* XXX: HACK: We do the increment on the *POST* event here (instead of all together) because we have no way of knowing whether other modules would block a nickchange.
*/
- virtual void OnUserPostNick(User* user, const std::string &oldnick)
+ void OnUserPostNick(User* user, const std::string &oldnick)
{
if (isdigit(user->nick[0])) /* allow switches to UID */
return;
@@ -259,8 +253,8 @@ class ModuleNickFlood : public Module
{
Channel *channel = i->first;
- nickfloodsettings *f;
- if (channel->GetExt("nickflood", f))
+ nickfloodsettings *f = nf.ext.get(channel);
+ if (f)
{
if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetStatus(user) == STATUS_OP)
return;
@@ -275,25 +269,14 @@ class ModuleNickFlood : public Module
return;
}
- void OnChannelDelete(Channel* chan)
- {
- nickfloodsettings *f;
- if (chan->GetExt("nickflood",f))
- {
- delete f;
- chan->Shrink("nickflood");
- }
- }
-
-
- virtual ~ModuleNickFlood()
+ ~ModuleNickFlood()
{
- ServerInstance->Modes->DelMode(&jf);
+ ServerInstance->Modes->DelMode(&nf);
}
- virtual Version GetVersion()
+ Version GetVersion()
{
- return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+ return Version("Channel mode F - nick flood protection", VF_COMMON | VF_VENDOR);
}
};
diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp
index e7c9e0199..ddfc47455 100644
--- a/src/modules/m_nicklock.cpp
+++ b/src/modules/m_nicklock.cpp
@@ -19,9 +19,10 @@
*/
class CommandNicklock : public Command
{
-
public:
- CommandNicklock (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"NICKLOCK", "o", 2)
+ LocalIntExt& locked;
+ CommandNicklock (Module* Creator, LocalIntExt& ext) : Command(Creator->ServerInstance, Creator,"NICKLOCK", "o", 2),
+ locked(ext)
{
syntax = "<oldnick> <newnick>";
TRANSLATE3(TR_NICK, TR_TEXT, TR_END);
@@ -58,11 +59,7 @@ class CommandNicklock : public Command
/* If we made it this far, extend the user */
if (target && IS_LOCAL(target))
{
- // This has to be done *here*, because this metadata must be stored netwide.
- target->Extend("nick_locked", "ON");
-
- /* Only send out nick from local server */
- target->Extend("nick_locked");
+ locked.set(target, 1);
std::string oldnick = target->nick;
if (target->ForceNickChange(parameters[1].c_str()))
@@ -91,7 +88,9 @@ class CommandNicklock : public Command
class CommandNickunlock : public Command
{
public:
- CommandNickunlock (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"NICKUNLOCK", "o", 1)
+ LocalIntExt& locked;
+ CommandNickunlock (Module* Creator, LocalIntExt& ext) : Command(Creator->ServerInstance, Creator,"NICKUNLOCK", "o", 1),
+ locked(ext)
{
syntax = "<locked-nick>";
TRANSLATE2(TR_NICK, TR_END);
@@ -119,7 +118,7 @@ class CommandNickunlock : public Command
if (target && IS_LOCAL(target))
{
- if (target->Shrink("nick_locked"))
+ if (locked.set(target, 0))
{
ServerInstance->SNO->WriteGlobalSno('a', std::string(user->nick)+" used NICKUNLOCK on "+parameters[0]);
user->WriteNumeric(945, "%s %s :Nickname now unlocked.",user->nick.c_str(),target->nick.c_str());
@@ -146,29 +145,30 @@ class CommandNickunlock : public Command
class ModuleNickLock : public Module
{
+ LocalIntExt locked;
CommandNicklock cmd1;
CommandNickunlock cmd2;
public:
ModuleNickLock(InspIRCd* Me)
- : Module(Me), cmd1(Me, this), cmd2(Me, this)
+ : Module(Me), locked("nick_locked", this), cmd1(this, locked), cmd2(this, locked)
{
ServerInstance->AddCommand(&cmd1);
ServerInstance->AddCommand(&cmd2);
- Implementation eventlist[] = { I_OnUserPreNick, I_OnUserQuit, I_OnCleanup };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ Extensible::Register(&locked);
+ ServerInstance->Modules->Attach(I_OnUserPreNick, this);
}
- virtual ~ModuleNickLock()
+ ~ModuleNickLock()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
- virtual ModResult OnUserPreNick(User* user, const std::string &newnick)
+ ModResult OnUserPreNick(User* user, const std::string &newnick)
{
if (!IS_LOCAL(user))
return MOD_RES_PASSTHRU;
@@ -176,10 +176,10 @@ class ModuleNickLock : public Module
if (isdigit(newnick[0])) /* Allow a switch to a UID */
return MOD_RES_PASSTHRU;
- if (user->GetExt("NICKForced")) /* Allow forced nick changes */
+ if (User::NICKForced.get(user)) /* Allow forced nick changes */
return MOD_RES_PASSTHRU;
- if (user->GetExt("nick_locked"))
+ if (locked.get(user))
{
user->WriteNumeric(447, "%s :You cannot change your nickname (your nick is locked)",user->nick.c_str());
return MOD_RES_DENY;
@@ -187,25 +187,11 @@ class ModuleNickLock : public Module
return MOD_RES_PASSTHRU;
}
- virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message)
- {
- user->Shrink("nick_locked");
- }
-
void Prioritize()
{
Module *nflood = ServerInstance->Modules->Find("m_nickflood.so");
ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_BEFORE, &nflood);
}
-
- virtual void OnCleanup(int target_type, void* item)
- {
- if(target_type == TYPE_USER)
- {
- User* user = (User*)item;
- user->Shrink("nick_locked");
- }
- }
};
MODULE_INIT(ModuleNickLock)
diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp
index 769097ca0..029ae9d2e 100644
--- a/src/modules/m_nonicks.cpp
+++ b/src/modules/m_nonicks.cpp
@@ -79,7 +79,7 @@ class ModuleNoNickChange : public Module
return MOD_RES_PASSTHRU;
// Allow forced nick changes.
- if (user->GetExt("NICKForced"))
+ if (User::NICKForced.get(user))
return MOD_RES_PASSTHRU;
for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
diff --git a/src/modules/m_regonlycreate.cpp b/src/modules/m_regonlycreate.cpp
index 5be303148..c3ecef202 100644
--- a/src/modules/m_regonlycreate.cpp
+++ b/src/modules/m_regonlycreate.cpp
@@ -34,7 +34,7 @@ class ModuleRegOnlyCreate : public Module
if (IS_OPER(user))
return MOD_RES_PASSTHRU;
- if ((!user->IsModeSet('r')) && (!user->GetExt("accountname")))
+ if (user->GetExtList().find("accountname") == user->GetExtList().end() && !user->IsModeSet('r'))
{
// XXX. there may be a better numeric for this..
user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have a registered nickname to create a new channel", user->nick.c_str(), cname);
diff --git a/src/modules/m_safelist.cpp b/src/modules/m_safelist.cpp
index bd1a54110..127b5f304 100644
--- a/src/modules/m_safelist.cpp
+++ b/src/modules/m_safelist.cpp
@@ -37,19 +37,23 @@ class ModuleSafeList : public Module
size_t ServerNameSize;
int global_listing;
int LimitList;
+ SimpleExtItem<ListData> listData;
+ LocalIntExt listTime;
public:
- ModuleSafeList(InspIRCd* Me) : Module(Me)
+ ModuleSafeList(InspIRCd* Me) : Module(Me), listData("safelist_data", this), listTime("safelist_last", this)
{
OnRehash(NULL);
- Implementation eventlist[] = { I_OnBufferFlushed, I_OnPreCommand, I_OnCleanup, I_OnUserQuit, I_On005Numeric, I_OnRehash };
- ServerInstance->Modules->Attach(eventlist, this, 6);
+ Extensible::Register(&listData);
+ Extensible::Register(&listTime);
+ Implementation eventlist[] = { I_OnBufferFlushed, I_OnPreCommand, I_On005Numeric, I_OnRehash };
+ ServerInstance->Modules->Attach(eventlist, this, 4);
}
- virtual ~ModuleSafeList()
+ ~ModuleSafeList()
{
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader MyConf(ServerInstance);
ThrottleSecs = MyConf.ReadInteger("safelist", "throttle", "60", 0, true);
@@ -58,7 +62,7 @@ class ModuleSafeList : public Module
global_listing = 0;
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$",VF_VENDOR,API_VERSION);
}
@@ -68,7 +72,7 @@ class ModuleSafeList : public Module
* OnPreCommand()
* Intercept the LIST command.
*/
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
+ ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
{
/* If the command doesnt appear to be valid, we dont want to mess with it. */
if (!validated)
@@ -99,8 +103,7 @@ class ModuleSafeList : public Module
}
/* First, let's check if the user is currently /list'ing */
- ListData *ld;
- user->GetExt("safelist_cache", ld);
+ ListData *ld = listData.get(user);
if (ld)
{
@@ -125,32 +128,21 @@ class ModuleSafeList : public Module
}
}
- time_t* last_list_time;
- user->GetExt("safelist_last", last_list_time);
- if (last_list_time)
+ time_t last_list_time = listTime.get(user);
+ if (last_list_time && ServerInstance->Time() < last_list_time + ThrottleSecs)
{
- if (ServerInstance->Time() < (*last_list_time)+ThrottleSecs)
- {
- user->WriteServ("NOTICE %s :*** Woah there, slow down a little, you can't /LIST so often!",user->nick.c_str());
- user->WriteNumeric(321, "%s Channel :Users Name",user->nick.c_str());
- user->WriteNumeric(323, "%s :End of channel list.",user->nick.c_str());
- return MOD_RES_DENY;
- }
-
- delete last_list_time;
- user->Shrink("safelist_last");
+ user->WriteServ("NOTICE %s :*** Woah there, slow down a little, you can't /LIST so often!",user->nick.c_str());
+ user->WriteNumeric(321, "%s Channel :Users Name",user->nick.c_str());
+ user->WriteNumeric(323, "%s :End of channel list.",user->nick.c_str());
+ return MOD_RES_DENY;
}
-
/*
* start at channel 0! ;)
*/
ld = new ListData(0,ServerInstance->Time(), (pcnt && (parameters[0][0] != '<' && parameters[0][0] != '>')) ? parameters[0] : "*", minusers, maxusers);
- user->Extend("safelist_cache", ld);
-
- time_t* llt = new time_t;
- *llt = ServerInstance->Time();
- user->Extend("safelist_last", llt);
+ listData.set(user, ld);
+ listTime.set(user, ServerInstance->Time());
user->WriteNumeric(321, "%s Channel :Users Name",user->nick.c_str());
@@ -159,11 +151,11 @@ class ModuleSafeList : public Module
return MOD_RES_DENY;
}
- virtual void OnBufferFlushed(User* user)
+ void OnBufferFlushed(User* user)
{
char buffer[MAXBUF];
- ListData* ld;
- if (user->GetExt("safelist_cache", ld))
+ ListData* ld = listData.get(user);
+ if (ld)
{
Channel* chan = NULL;
unsigned long amount_sent = 0;
@@ -228,46 +220,17 @@ class ModuleSafeList : public Module
while ((chan != NULL) && (amount_sent < (user->MyClass->GetSendqMax() / 4)));
if (ld->list_ended)
{
- user->Shrink("safelist_cache");
- delete ld;
- global_listing--;
- }
- }
- }
-
- virtual void OnCleanup(int target_type, void* item)
- {
- if(target_type == TYPE_USER)
- {
- User* u = (User*)item;
- ListData* ld;
- u->GetExt("safelist_cache", ld);
- if (ld)
- {
- u->Shrink("safelist_cache");
- delete ld;
+ listData.unset(user);
global_listing--;
}
- time_t* last_list_time;
- u->GetExt("safelist_last", last_list_time);
- if (last_list_time)
- {
- delete last_list_time;
- u->Shrink("safelist_last");
- }
}
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
output.append(" SAFELIST");
}
- virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message)
- {
- this->OnCleanup(TYPE_USER,user);
- }
-
};
MODULE_INIT(ModuleSafeList)
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp
index 1436afa3d..069fbdec8 100644
--- a/src/modules/m_sasl.cpp
+++ b/src/modules/m_sasl.cpp
@@ -37,8 +37,6 @@ class SaslAuthenticator : public classbase
SaslAuthenticator(User *user_, std::string method, InspIRCd *instance, Module *ctor)
: ServerInstance(instance), user(user_), state(SASL_INIT), state_announced(false)
{
- this->user->Extend("sasl_authenticator", this);
-
parameterlist params;
params.push_back("*");
params.push_back("SASL");
@@ -147,18 +145,15 @@ class SaslAuthenticator : public classbase
this->state_announced = true;
}
-
- ~SaslAuthenticator()
- {
- this->user->Shrink("sasl_authenticator");
- this->AnnounceState();
- }
};
class CommandAuthenticate : public Command
{
public:
- CommandAuthenticate (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "AUTHENTICATE", 0, 1, true)
+ SimpleExtItem<SaslAuthenticator>& authExt;
+ GenericCap& cap;
+ CommandAuthenticate (InspIRCd* Instance, Module* Creator, SimpleExtItem<SaslAuthenticator>& ext, GenericCap& Cap)
+ : Command(Instance, Creator, "AUTHENTICATE", 0, 1, true), authExt(ext), cap(Cap)
{
}
@@ -167,14 +162,17 @@ class CommandAuthenticate : public Command
/* Only allow AUTHENTICATE on unregistered clients */
if (user->registered != REG_ALL)
{
- if (!user->GetExt("sasl"))
+ if (!cap.ext.get(user))
return CMD_FAILURE;
- SaslAuthenticator *sasl;
- if (!(user->GetExt("sasl_authenticator", sasl)))
- sasl = new SaslAuthenticator(user, parameters[0], ServerInstance, creator);
+ SaslAuthenticator *sasl = authExt.get(user);
+ if (!sasl)
+ authExt.set(user, new SaslAuthenticator(user, parameters[0], ServerInstance, creator));
else if (sasl->SendClientMessage(parameters) == false) // IAL abort extension --nenolod
- delete sasl;
+ {
+ sasl->AnnounceState();
+ authExt.unset(user);
+ }
}
return CMD_FAILURE;
}
@@ -183,7 +181,9 @@ class CommandAuthenticate : public Command
class CommandSASL : public Command
{
public:
- CommandSASL(InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "SASL", 0, 2)
+ SimpleExtItem<SaslAuthenticator>& authExt;
+ CommandSASL(InspIRCd* Instance, Module* Creator, SimpleExtItem<SaslAuthenticator>& ext)
+ : Command(Instance, Creator, "SASL", 0, 2), authExt(ext)
{
this->disabled = true; // should not be called by users
}
@@ -197,15 +197,15 @@ class CommandSASL : public Command
return CMD_FAILURE;
}
- SaslAuthenticator *sasl;
- if (!target->GetExt("sasl_authenticator", sasl))
+ SaslAuthenticator *sasl = authExt.get(target);
+ if (!sasl)
return CMD_FAILURE;
SaslState state = sasl->ProcessInboundMessage(parameters);
if (state == SASL_DONE)
{
- delete sasl;
- target->Shrink("sasl");
+ sasl->AnnounceState();
+ authExt.unset(target);
}
return CMD_SUCCESS;
}
@@ -218,12 +218,13 @@ class CommandSASL : public Command
class ModuleSASL : public Module
{
+ SimpleExtItem<SaslAuthenticator> authExt;
+ GenericCap cap;
CommandAuthenticate auth;
CommandSASL sasl;
public:
-
ModuleSASL(InspIRCd* Me)
- : Module(Me), auth(Me, this), sasl(Me, this)
+ : Module(Me), authExt("sasl_auth", this), cap(this, "sasl"), auth(Me, this, authExt, cap), sasl(Me, this, authExt)
{
Implementation eventlist[] = { I_OnEvent, I_OnUserRegister, I_OnPostConnect, I_OnUserDisconnect, I_OnCleanup };
ServerInstance->Modules->Attach(eventlist, this, 5);
@@ -235,60 +236,30 @@ class ModuleSASL : public Module
ServerInstance->Logs->Log("m_sasl", DEFAULT, "WARNING: m_services_account.so and m_cap.so are not loaded! m_sasl.so will NOT function correctly until these two modules are loaded!");
}
- virtual ModResult OnUserRegister(User *user)
+ ModResult OnUserRegister(User *user)
{
- SaslAuthenticator *sasl_;
- if (user->GetExt("sasl_authenticator", sasl_))
+ SaslAuthenticator *sasl_ = authExt.get(user);
+ if (sasl_)
{
sasl_->Abort();
- delete sasl_;
- user->Shrink("sasl_authenticator");
+ authExt.unset(user);
}
return MOD_RES_PASSTHRU;
}
- virtual void OnCleanup(int target_type, void *item)
- {
- if (target_type == TYPE_USER)
- OnUserDisconnect((User*)item);
- }
-
- virtual void OnUserDisconnect(User *user)
- {
- SaslAuthenticator *sasl_;
- if (user->GetExt("sasl_authenticator", sasl_))
- {
- delete sasl_;
- user->Shrink("sasl_authenticator");
- }
- }
-
- virtual void OnPostConnect(User* user)
- {
- if (!IS_LOCAL(user))
- return;
-
- std::string* str = NULL;
-
- if (user->GetExt("accountname", str))
- ServerInstance->PI->SendMetaData(user, "accountname", *str);
-
- return;
- }
-
- virtual ~ModuleSASL()
+ ~ModuleSASL()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$",VF_VENDOR,API_VERSION);
}
- virtual void OnEvent(Event *ev)
+ void OnEvent(Event *ev)
{
- GenericCapHandler(ev, "sasl", "sasl");
+ cap.HandleEvent(ev);
}
};
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index cc65038d1..cbbfac0a4 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -104,9 +104,11 @@ class ModuleServicesAccount : public Module
AUser_R m3;
Channel_r m4;
User_r m5;
+ StringExtItem accountname;
public:
ModuleServicesAccount(InspIRCd* Me) : Module(Me),
- m1(Me, this), m2(Me, this), m3(Me, this), m4(Me, this), m5(Me, this)
+ m1(Me, this), m2(Me, this), m3(Me, this), m4(Me, this), m5(Me, this),
+ accountname("accountname", this)
{
if (!ServerInstance->Modes->AddMode(&m1) || !ServerInstance->Modes->AddMode(&m2) ||
@@ -129,8 +131,7 @@ class ModuleServicesAccount : public Module
/* <- :twisted.oscnet.org 330 w00t2 w00t2 w00t :is logged in as */
virtual void OnWhois(User* source, User* dest)
{
- std::string *account;
- dest->GetExt("accountname", account);
+ std::string *account = accountname.get(dest);
if (account)
{
@@ -161,9 +162,8 @@ class ModuleServicesAccount : public Module
if (!IS_LOCAL(user))
return MOD_RES_PASSTHRU;
- std::string *account;
- bool is_registered = user->GetExt("accountname", account);
- is_registered = is_registered && !account->empty();
+ std::string *account = accountname.get(user);
+ bool is_registered = account && !account->empty();
if ((ServerInstance->ULine(user->nick.c_str())) || (ServerInstance->ULine(user->server)))
{
@@ -208,8 +208,8 @@ class ModuleServicesAccount : public Module
virtual ModResult OnCheckBan(User* user, Channel* chan)
{
- std::string* account;
- if (!user->GetExt("accountname", account))
+ std::string *account = accountname.get(user);
+ if (!account)
return MOD_RES_PASSTHRU;
return chan->GetExtBanStatus(*account, 'R');
}
@@ -224,9 +224,8 @@ class ModuleServicesAccount : public Module
if (!IS_LOCAL(user))
return MOD_RES_PASSTHRU;
- std::string *account;
- bool is_registered = user->GetExt("accountname", account);
- is_registered = is_registered && !account->empty();
+ std::string *account = accountname.get(user);
+ bool is_registered = account && !account->empty();
if (chan)
{
@@ -249,55 +248,6 @@ class ModuleServicesAccount : public Module
return MOD_RES_PASSTHRU;
}
- // Whenever the linking module wants to send out data, but doesnt know what the data
- // represents (e.g. it is metadata, added to a User or Channel by a module) then
- // this method is called. We should use the ProtoSendMetaData function after we've
- // corrected decided how the data should look, to send the metadata on its way if
- // it is ours.
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- // check if this user has an swhois field to send
- std::string* account;
- user->GetExt("accountname", account);
- if (account)
- {
- // remove any accidental leading/trailing spaces
- trim(*account);
-
- // call this function in the linking module, let it format the data how it
- // sees fit, and send it on its way. We dont need or want to know how.
- proto->ProtoSendMetaData(opaque,user,"accountname",*account);
- }
- }
-
- // when a user quits, tidy up their metadata
- virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message)
- {
- std::string* account;
- user->GetExt("accountname", account);
- if (account)
- {
- user->Shrink("accountname");
- delete account;
- }
- }
-
- // if the module is unloaded, tidy up all our dangling metadata
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type == TYPE_USER)
- {
- User* user = (User*)item;
- std::string* account;
- user->GetExt("accountname", account);
- if (account)
- {
- user->Shrink("accountname");
- delete account;
- }
- }
- }
-
// Whenever the linking module receives metadata from another server and doesnt know what
// to do with it (of course, hence the 'meta') it calls this method, and it is up to each
// module in turn to figure out if this metadata key belongs to them, and what they want
@@ -311,19 +261,10 @@ class ModuleServicesAccount : public Module
// check if its our metadata key, and its associated with a user
if (dest && (extname == "accountname"))
{
- std::string* account;
- if (dest->GetExt("accountname", account)) {
- // remove old account so that we can set new (or leave unset)
- dest->Shrink("accountname");
- delete account;
- }
-
if (!extdata.empty())
{
- account = new std::string(extdata);
- // remove any accidental leading/trailing spaces
+ std::string *account = accountname.get(dest);
trim(*account);
- dest->Extend("accountname", account);
if (IS_LOCAL(dest))
dest->WriteNumeric(900, "%s %s %s :You are now logged in as %s",
diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp
index 9cf9f6d4e..779cb541e 100644
--- a/src/modules/m_silence.cpp
+++ b/src/modules/m_silence.cpp
@@ -93,7 +93,9 @@ class CommandSilence : public Command
{
unsigned int& maxsilence;
public:
- CommandSilence (InspIRCd* Instance, Module* Creator, unsigned int &max) : Command(Instance, Creator, "SILENCE", 0, 0), maxsilence(max)
+ SimpleExtItem<silencelist> ext;
+ CommandSilence (InspIRCd* Instance, Module* Creator, unsigned int &max) : Command(Instance, Creator, "SILENCE", 0, 0),
+ maxsilence(max), ext("silence_list", Creator)
{
syntax = "{[+|-]<mask> <p|c|i|n|t|a|x>}";
TRANSLATE3(TR_TEXT, TR_TEXT, TR_END);
@@ -104,9 +106,7 @@ class CommandSilence : public Command
if (!parameters.size())
{
// no parameters, show the current silence list.
- // Use Extensible::GetExt to fetch the silence list
- silencelist* sl;
- user->GetExt("silence_list", sl);
+ silencelist* sl = ext.get(user);
// if the user has a silence list associated with their user record, show it
if (sl)
{
@@ -143,8 +143,7 @@ class CommandSilence : public Command
if (action == '-')
{
// fetch their silence list
- silencelist* sl;
- user->GetExt("silence_list", sl);
+ silencelist* sl = ext.get(user);
// does it contain any entries and does it exist?
if (sl)
{
@@ -158,8 +157,7 @@ class CommandSilence : public Command
user->WriteNumeric(950, "%s %s :Removed %s %s from silence list",user->nick.c_str(), user->nick.c_str(), mask.c_str(), DecompPattern(pattern).c_str());
if (!sl->size())
{
- delete sl;
- user->Shrink("silence_list");
+ ext.unset(user);
}
return CMD_SUCCESS;
}
@@ -170,13 +168,11 @@ class CommandSilence : public Command
else if (action == '+')
{
// fetch the user's current silence list
- silencelist* sl;
- user->GetExt("silence_list", sl);
- // what, they dont have one??? WE'RE ALL GONNA DIE! ...no, we just create an empty one.
+ silencelist* sl = ext.get(user);
if (!sl)
{
sl = new silencelist;
- user->Extend("silence_list", sl);
+ ext.set(user, sl);
}
if (sl->size() > maxsilence)
{
@@ -281,11 +277,11 @@ class ModuleSilence : public Module
ServerInstance->AddCommand(&cmdsilence);
ServerInstance->AddCommand(&cmdsvssilence);
- Implementation eventlist[] = { I_OnRehash, I_OnBuildExemptList, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage, I_OnUserPreInvite };
- ServerInstance->Modules->Attach(eventlist, this, 7);
+ Implementation eventlist[] = { I_OnRehash, I_OnBuildExemptList, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage, I_OnUserPreInvite };
+ ServerInstance->Modules->Attach(eventlist, this, 6);
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
maxsilence = Conf.ReadInteger("silence", "maxentries", 0, true);
@@ -293,26 +289,13 @@ class ModuleSilence : public Module
maxsilence = 32;
}
-
- virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message)
- {
- // when the user quits tidy up any silence list they might have just to keep things tidy
- silencelist* sl;
- user->GetExt("silence_list", sl);
- if (sl)
- {
- delete sl;
- user->Shrink("silence_list");
- }
- }
-
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
// we don't really have a limit...
output = output + " ESILENCE SILENCE=" + ConvToStr(maxsilence);
}
- virtual void OnBuildExemptList(MessageType message_type, Channel* chan, User* sender, char status, CUList &exempt_list, const std::string &text)
+ void OnBuildExemptList(MessageType message_type, Channel* chan, User* sender, char status, CUList &exempt_list, const std::string &text)
{
int public_silence = (message_type == MSG_PRIVMSG ? SILENCE_CHANNEL : SILENCE_CNOTICE);
CUList *ulist;
@@ -344,7 +327,7 @@ class ModuleSilence : public Module
}
}
- virtual ModResult PreText(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list, int silence_type)
+ ModResult PreText(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list, int silence_type)
{
if (target_type == TYPE_USER && IS_LOCAL(((User*)dest)))
{
@@ -361,17 +344,17 @@ class ModuleSilence : public Module
return MOD_RES_PASSTHRU;
}
- virtual ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
+ ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
{
return PreText(user, dest, target_type, text, status, exempt_list, SILENCE_PRIVATE);
}
- virtual ModResult OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
+ ModResult OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
{
return PreText(user, dest, target_type, text, status, exempt_list, SILENCE_NOTICE);
}
- virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout)
+ ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout)
{
return MatchPattern(dest, source, SILENCE_INVITE);
}
@@ -382,8 +365,7 @@ class ModuleSilence : public Module
if (!source || !dest)
return MOD_RES_ALLOW;
- silencelist* sl;
- dest->GetExt("silence_list", sl);
+ silencelist* sl = cmdsilence.ext.get(dest);
if (sl)
{
for (silencelist::const_iterator c = sl->begin(); c != sl->end(); c++)
@@ -395,11 +377,11 @@ class ModuleSilence : public Module
return MOD_RES_PASSTHRU;
}
- virtual ~ModuleSilence()
+ ~ModuleSilence()
{
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp
index 332e47585..348a453a6 100644
--- a/src/modules/m_spanningtree/hmac.cpp
+++ b/src/modules/m_spanningtree/hmac.cpp
@@ -128,17 +128,22 @@ bool TreeSocket::ComparePass(const Link& link, const std::string &theirs)
this->auth_fingerprint = !link.Fingerprint.empty();
this->auth_challenge = !ourchallenge.empty() && !theirchallenge.empty();
- const char* fp = NULL;
+ std::string fp;
if (GetHook())
- fp = BufferedSocketFingerprintRequest(this, Utils->Creator, GetHook()).Send();
-
- if (fp)
- ServerInstance->Logs->Log("m_spanningtree", DEFAULT, std::string("Server SSL fingerprint ") + fp);
+ {
+ BufferedSocketCertificateRequest req(this, Utils->Creator, GetHook());
+ req.Send();
+ if (req.cert)
+ {
+ fp = req.cert->GetFingerprint();
+ ServerInstance->Logs->Log("m_spanningtree", DEFAULT, std::string("Server SSL fingerprint ") + fp);
+ }
+ }
if (auth_fingerprint)
{
/* Require fingerprint to exist and match */
- if (!fp || link.Fingerprint != std::string(fp))
+ if (link.Fingerprint != fp)
return false;
}
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 726b0713e..5e30ced35 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -731,7 +731,7 @@ void ModuleSpanningTree::OnRemoteKill(User* source, User* dest, const std::strin
if (!IS_LOCAL(source))
return; // Only start routing if we're origin.
- dest->Extend("operquit", new std::string(operreason));
+ User::OperQuit.set(dest, operreason);
parameterlist params;
params.push_back(":"+operreason);
Utils->DoOneToMany(dest->uuid,"OPERQUIT",params);
diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp
index 951d019ef..abefad728 100644
--- a/src/modules/m_spanningtree/netburst.cpp
+++ b/src/modules/m_spanningtree/netburst.cpp
@@ -17,6 +17,7 @@
#include "treesocket.h"
#include "treeserver.h"
#include "utils.h"
+#include "main.h"
/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */
@@ -46,7 +47,7 @@ void TreeSocket::DoBurst(TreeServer* s)
/* Send everything else (channel modes, xlines etc) */
this->SendChannelModes(s);
this->SendXLines(s);
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncNetwork,OnSyncNetwork((Module*)Utils->Creator,(void*)this));
+ FOREACH_MOD_I(this->ServerInstance,I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this));
this->WriteLine(endburst);
this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2.");
}
@@ -218,7 +219,18 @@ void TreeSocket::SendChannelModes(TreeServer* Current)
snprintf(data,MAXBUF,":%s FTOPIC %s %lu %s :%s", sn, c->second->name.c_str(), (unsigned long)c->second->topicset, c->second->setby.c_str(), c->second->topic.c_str());
this->WriteLine(data);
}
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,(Module*)Utils->Creator,(void*)this));
+
+ for(ExtensibleStore::const_iterator i = c->second->GetExtList().begin(); i != c->second->GetExtList().end(); i++)
+ {
+ ExtensionItem* item = Extensible::GetItem(i->first);
+ std::string value;
+ if (item)
+ value = item->serialize(Utils->Creator, c->second, i->second);
+ if (!value.empty())
+ Utils->Creator->ProtoSendMetaData(this, c->second, i->first, value);
+ }
+
+ FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this));
}
}
@@ -259,7 +271,17 @@ void TreeSocket::SendUsers(TreeServer* Current)
}
}
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this));
+ for(ExtensibleStore::const_iterator i = u->second->GetExtList().begin(); i != u->second->GetExtList().end(); i++)
+ {
+ ExtensionItem* item = Extensible::GetItem(i->first);
+ std::string value;
+ if (item)
+ value = item->serialize(Utils->Creator, u->second, i->second);
+ if (!value.empty())
+ Utils->Creator->ProtoSendMetaData(this, u->second, i->first, value);
+ }
+
+ FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,Utils->Creator,this));
}
}
}
diff --git a/src/modules/m_spanningtree/operquit.cpp b/src/modules/m_spanningtree/operquit.cpp
index 5260cd990..5cdee3bc6 100644
--- a/src/modules/m_spanningtree/operquit.cpp
+++ b/src/modules/m_spanningtree/operquit.cpp
@@ -30,7 +30,7 @@ bool TreeSocket::OperQuit(const std::string &prefix, parameterlist &params)
if (u)
{
- u->Extend("operquit", new std::string(params[0]));
+ User::OperQuit.set(u, params[0]);
params[0] = ":" + params[0];
Utils->DoOneToAllButSender(prefix,"OPERQUIT",params,prefix);
}
diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp
index 715d9110a..bf02ed879 100644
--- a/src/modules/m_sslinfo.cpp
+++ b/src/modules/m_sslinfo.cpp
@@ -16,12 +16,63 @@
/* $ModDesc: Provides SSL metadata, including /WHOIS information and /SSLINFO command */
+class SSLCertExt : public ExtensionItem {
+ public:
+ SSLCertExt(Module* parent) : ExtensionItem("ssl_cert", parent) {}
+ ssl_cert* get(const Extensible* item)
+ {
+ return static_cast<ssl_cert*>(get_raw(item));
+ }
+ void set(Extensible* item, ssl_cert* value)
+ {
+ ssl_cert* old = static_cast<ssl_cert*>(set_raw(item, value));
+ delete old;
+ }
+
+ std::string serialize(Module* requestor, const Extensible* container, void* item)
+ {
+ return static_cast<ssl_cert*>(item)->GetMetaLine();
+ }
+
+ void unserialize(Module* requestor, Extensible* container, const std::string& value)
+ {
+ ssl_cert* cert = new ssl_cert;
+ set(container, cert);
+
+ std::stringstream s(value);
+ std::string v;
+ getline(s,v,' ');
+
+ cert->invalid = (v.find('v') != std::string::npos);
+ cert->trusted = (v.find('T') != std::string::npos);
+ cert->revoked = (v.find('R') != std::string::npos);
+ cert->unknownsigner = (v.find('s') != std::string::npos);
+ if (v.find('E') != std::string::npos)
+ {
+ getline(s,cert->error,'\n');
+ }
+ else
+ {
+ getline(s,cert->fingerprint,' ');
+ getline(s,cert->dn,' ');
+ getline(s,cert->issuer,'\n');
+ }
+ }
+
+ void free(void* item)
+ {
+ delete static_cast<ssl_cert*>(item);
+ }
+};
+
/** Handle /SSLINFO
*/
class CommandSSLInfo : public Command
{
public:
- CommandSSLInfo(InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "SSLINFO", 0, 1)
+ SSLCertExt CertExt;
+
+ CommandSSLInfo(InspIRCd* Instance, Module* Creator) : Command(Instance, Creator, "SSLINFO", 0, 1), CertExt(Creator)
{
this->syntax = "<nick>";
}
@@ -29,11 +80,11 @@ class CommandSSLInfo : public Command
CmdResult Handle (const std::vector<std::string> &parameters, User *user)
{
User* target = ServerInstance->FindNick(parameters[0]);
- ssl_cert* cert;
if (target)
{
- if (target->GetExt("ssl_cert", cert))
+ ssl_cert* cert = CertExt.get(target);
+ if (cert)
{
if (cert->GetError().length())
{
@@ -63,93 +114,36 @@ class CommandSSLInfo : public Command
class ModuleSSLInfo : public Module
{
CommandSSLInfo cmd;
+
public:
ModuleSSLInfo(InspIRCd* Me)
: Module(Me), cmd(Me, this)
{
ServerInstance->AddCommand(&cmd);
+ Extensible::Register(&cmd.CertExt);
+
Implementation eventlist[] = { I_OnSyncUser, I_OnDecodeMetaData, I_OnWhois, I_OnPreCommand };
ServerInstance->Modules->Attach(eventlist, this, 4);
}
-
virtual ~ModuleSSLInfo()
{
}
virtual Version GetVersion()
{
- return Version("$Id$", VF_VENDOR, API_VERSION);
- }
-
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type != TYPE_USER)
- return;
- User* user = static_cast<User*>(item);
- user->Shrink("ssl_cert");
+ return Version("SSL Certificate Utilities", VF_VENDOR);
}
virtual void OnWhois(User* source, User* dest)
{
- if(dest->GetExt("ssl"))
+ if (cmd.CertExt.get(dest))
{
ServerInstance->SendWhoisLine(source, dest, 320, "%s %s :is using a secure connection", source->nick.c_str(), dest->nick.c_str());
}
}
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- if (user->GetExt("ssl"))
- proto->ProtoSendMetaData(opaque, user, "ssl", "ON");
-
- ssl_cert* cert;
- if (user->GetExt("ssl_cert", cert))
- proto->ProtoSendMetaData(opaque, user, "ssl_cert", cert->GetMetaLine().c_str());
- }
-
- virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
- {
- User* dest = dynamic_cast<User*>(target);
- // check if its our metadata key, and its associated with a user
- if (dest && (extname == "ssl"))
- {
- // if they dont already have an ssl flag, accept the remote server's
- if (!dest->GetExt(extname))
- {
- dest->Extend(extname);
- }
- }
- else if (dest && (extname == "ssl_cert"))
- {
- if (dest->GetExt(extname))
- return;
-
- ssl_cert* cert = new ssl_cert;
- dest->Extend(extname, cert);
-
- std::stringstream s(extdata);
- std::string v;
- getline(s,v,' ');
-
- cert->invalid = (v.find('v') != std::string::npos);
- cert->trusted = (v.find('T') != std::string::npos);
- cert->revoked = (v.find('R') != std::string::npos);
- cert->unknownsigner = (v.find('s') != std::string::npos);
- if (v.find('E') != std::string::npos)
- {
- getline(s,cert->error,'\n');
- }
- else
- {
- getline(s,cert->fingerprint,' ');
- getline(s,cert->dn,' ');
- getline(s,cert->issuer,'\n');
- }
- }
- }
-
bool OneOfMatches(const char* host, const char* ip, const char* hostlist)
{
std::stringstream hl(hostlist);
@@ -180,13 +174,11 @@ class ModuleSSLInfo : public Module
std::string HashType;
std::string FingerPrint;
bool SSLOnly;
- ssl_cert* cert = NULL;
+ ssl_cert* cert = cmd.CertExt.get(user);
snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(),user->host.c_str());
snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(),user->GetIPString());
- user->GetExt("ssl_cert",cert);
-
for (int i = 0; i < cf.Enumerate("oper"); i++)
{
LoginName = cf.ReadValue("oper", "name", i);
@@ -209,7 +201,7 @@ class ModuleSSLInfo : public Module
if (Password.length() && ServerInstance->PassCompare(user, Password.c_str(),parameters[1].c_str(), HashType.c_str()))
continue;
- if (SSLOnly && !user->GetExt("ssl"))
+ if (SSLOnly && !cert)
{
user->WriteNumeric(491, "%s :This oper login name requires an SSL connection.", user->nick.c_str());
return MOD_RES_DENY;
@@ -232,7 +224,20 @@ class ModuleSSLInfo : public Module
return MOD_RES_PASSTHRU;
}
-
+ const char* OnRequest(Request* request)
+ {
+ if (strcmp("GET_CERT", request->GetId()) == 0)
+ {
+ BufferedSocketCertificateRequest* req = static_cast<BufferedSocketCertificateRequest*>(request);
+ req->cert = cmd.CertExt.get(req->item);
+ }
+ else if (strcmp("SET_CERT", request->GetId()) == 0)
+ {
+ BufferedSocketFingerprintSubmission* req = static_cast<BufferedSocketFingerprintSubmission*>(request);
+ cmd.CertExt.set(req->item, req->cert);
+ }
+ return NULL;
+ }
};
MODULE_INIT(ModuleSSLInfo)
diff --git a/src/modules/m_sslmodes.cpp b/src/modules/m_sslmodes.cpp
index b19347ea7..a07252069 100644
--- a/src/modules/m_sslmodes.cpp
+++ b/src/modules/m_sslmodes.cpp
@@ -12,11 +12,10 @@
*/
#include "inspircd.h"
+#include "transport.h"
/* $ModDesc: Provides support for unreal-style channel mode +z */
-static char* dummy;
-
/** Handle channel mode +z
*/
class SSLMode : public ModeHandler
@@ -35,7 +34,9 @@ class SSLMode : public ModeHandler
CUList* userlist = channel->GetUsers();
for(CUList::iterator i = userlist->begin(); i != userlist->end(); i++)
{
- if(!i->first->GetExt("ssl", dummy) && !ServerInstance->ULine(i->first->server))
+ BufferedSocketCertificateRequest req(i->first, creator, i->first->GetIOHook());
+ req.Send();
+ if(!req.cert && !ServerInstance->ULine(i->first->server))
{
source->WriteNumeric(ERR_ALLMUSTSSL, "%s %s :all members of the channel must be connected via SSL", source->nick.c_str(), channel->name.c_str());
return MODEACTION_DENY;
@@ -74,16 +75,17 @@ class ModuleSSLModes : public Module
{
if (!ServerInstance->Modes->AddMode(&sslm))
throw ModuleException("Could not add new modes!");
- Implementation eventlist[] = { I_OnUserPreJoin };
- ServerInstance->Modules->Attach(eventlist, this, 1);
+ Implementation eventlist[] = { I_OnUserPreJoin, I_OnCheckBan, I_On005Numeric };
+ ServerInstance->Modules->Attach(eventlist, this, 3);
}
-
- virtual ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
+ ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
{
if(chan && chan->IsModeSet('z'))
{
- if(user->GetExt("ssl", dummy))
+ BufferedSocketCertificateRequest req(user, this, user->GetIOHook());
+ req.Send();
+ if (req.cert)
{
// Let them in
return MOD_RES_PASSTHRU;
@@ -99,12 +101,26 @@ class ModuleSSLModes : public Module
return MOD_RES_PASSTHRU;
}
- virtual ~ModuleSSLModes()
+ ModResult OnCheckBan(User *user, Channel *c)
+ {
+ BufferedSocketCertificateRequest req(user, this, user->GetIOHook());
+ req.Send();
+ if (req.cert)
+ return c->GetExtBanStatus(req.cert->GetFingerprint(), 'z');
+ return MOD_RES_PASSTHRU;
+ }
+
+ ~ModuleSSLModes()
{
ServerInstance->Modes->DelMode(&sslm);
}
- virtual Version GetVersion()
+ void On005Numeric(std::string &output)
+ {
+ ServerInstance->AddExtBanChar('z');
+ }
+
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
diff --git a/src/modules/m_swhois.cpp b/src/modules/m_swhois.cpp
index ebff25cb8..bd2447c2a 100644
--- a/src/modules/m_swhois.cpp
+++ b/src/modules/m_swhois.cpp
@@ -19,9 +19,9 @@
*/
class CommandSwhois : public Command
{
-
public:
- CommandSwhois (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"SWHOIS","o",2, 2)
+ StringExtItem swhois;
+ CommandSwhois (InspIRCd* Instance, Module* Creator) : Command(Instance, Creator,"SWHOIS","o",2,2), swhois("swhois", Creator)
{
syntax = "<nick> :<swhois>";
TRANSLATE3(TR_NICK, TR_TEXT, TR_END);
@@ -37,16 +37,13 @@ class CommandSwhois : public Command
return CMD_FAILURE;
}
- std::string* text;
- if (dest->GetExt("swhois", text))
+ std::string* text = swhois.get(dest);
+ if (text)
{
// We already had it set...
if (!ServerInstance->ULine(user->server))
// Ulines set SWHOISes silently
ServerInstance->SNO->WriteGlobalSno('a', "%s used SWHOIS to set %s's extra whois from '%s' to '%s'", user->nick.c_str(), dest->nick.c_str(), text->c_str(), parameters[1].c_str());
-
- dest->Shrink("swhois");
- delete text;
}
else if (!ServerInstance->ULine(user->server))
{
@@ -54,8 +51,10 @@ class CommandSwhois : public Command
ServerInstance->SNO->WriteGlobalSno('a', "%s used SWHOIS to set %s's extra whois to '%s'", user->nick.c_str(), dest->nick.c_str(), parameters[1].c_str());
}
- text = new std::string(parameters[1]);
- dest->Extend("swhois", text);
+ if (parameters[1].empty())
+ swhois.unset(dest);
+ else
+ swhois.set(dest, parameters[1]);
/* Bug #376 - feature request -
* To cut down on the amount of commands services etc have to recognise, this only sends METADATA across the network now
@@ -63,14 +62,7 @@ class CommandSwhois : public Command
* Sorry w00t i know this was your fix, but i got bored and wanted to clear down the tracker :)
* -- Brain
*/
- ServerInstance->PI->SendMetaData(dest, "swhois", *text);
-
- // If it's an empty swhois, unset it (not ideal, but ok)
- if (text->empty())
- {
- dest->Shrink("swhois");
- delete text;
- }
+ ServerInstance->PI->SendMetaData(dest, "swhois", parameters[1]);
return CMD_SUCCESS;
}
@@ -81,25 +73,14 @@ class ModuleSWhois : public Module
{
CommandSwhois cmd;
- ConfigReader* Conf;
-
public:
ModuleSWhois(InspIRCd* Me) : Module(Me), cmd(Me, this)
{
-
- Conf = new ConfigReader(ServerInstance);
ServerInstance->AddCommand(&cmd);
- Implementation eventlist[] = { I_OnDecodeMetaData, I_OnWhoisLine, I_OnSyncUser, I_OnUserQuit, I_OnCleanup, I_OnRehash, I_OnPostCommand };
- ServerInstance->Modules->Attach(eventlist, this, 7);
- }
-
- void OnRehash(User* user)
- {
- delete Conf;
- Conf = new ConfigReader(ServerInstance);
+ Implementation eventlist[] = { I_OnWhoisLine, I_OnPostCommand };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
}
-
// :kenny.chatspike.net 320 Brain Azhrarn :is getting paid to play games.
ModResult OnWhoisLine(User* user, User* dest, int &numeric, std::string &text)
{
@@ -107,8 +88,8 @@ class ModuleSWhois : public Module
if (numeric == 312)
{
/* Insert our numeric before 312 */
- std::string* swhois;
- if (dest->GetExt("swhois", swhois))
+ std::string* swhois = cmd.swhois.get(dest);
+ if (swhois)
{
ServerInstance->SendWhoisLine(user, dest, 320, "%s %s :%s",user->nick.c_str(), dest->nick.c_str(), swhois->c_str());
}
@@ -118,125 +99,51 @@ class ModuleSWhois : public Module
return MOD_RES_PASSTHRU;
}
- // Whenever the linking module wants to send out data, but doesnt know what the data
- // represents (e.g. it is metadata, added to a User or Channel by a module) then
- // this method is called. We should use the ProtoSendMetaData function after we've
- // corrected decided how the data should look, to send the metadata on its way if
- // it is ours.
- virtual void OnSyncUser(User* user, Module* proto, void* opaque)
- {
- // check if this user has an swhois field to send
- std::string* swhois;
- if (user->GetExt("swhois", swhois))
- proto->ProtoSendMetaData(opaque,user,"swhois",*swhois);
- }
-
- // when a user quits, tidy up their metadata
- virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message)
- {
- std::string* swhois;
- if (user->GetExt("swhois", swhois))
- {
- user->Shrink("swhois");
- delete swhois;
- }
- }
-
- // if the module is unloaded, tidy up all our dangling metadata
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type != TYPE_USER) return;
- User* user = static_cast<User*>(item);
- std::string* swhois;
- if (user && user->GetExt("swhois", swhois))
- {
- user->Shrink("swhois");
- delete swhois;
- }
- }
-
- // Whenever the linking module receives metadata from another server and doesnt know what
- // to do with it (of course, hence the 'meta') it calls this method, and it is up to each
- // module in turn to figure out if this metadata key belongs to them, and what they want
- // to do with it.
- // In our case we're only sending a single string around, so we just construct a std::string.
- // Some modules will probably get much more complex and format more detailed structs and classes
- // in a textual way for sending over the link.
- virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata)
- {
- User* dest = dynamic_cast<User*>(target);
- // check if its our metadata key, and its associated with a user
- if (extname != "swhois" || !dest)
- return;
-
- // if they already have an swhois field, trash it and replace it with the remote one.
- std::string* text;
- if (dest->GetExt("swhois", text))
- {
- dest->Shrink("swhois");
- delete text;
- }
-
- if (extdata.empty())
- return;
-
- text = new std::string(extdata);
- dest->Extend("swhois", text);
- }
-
- virtual void OnPostCommand(const std::string &command, const std::vector<std::string> &params, User *user, CmdResult result, const std::string &original_line)
+ void OnPostCommand(const std::string &command, const std::vector<std::string> &params, User *user, CmdResult result, const std::string &original_line)
{
if ((command != "OPER") || (result != CMD_SUCCESS))
return;
+ ConfigReader Conf(ServerInstance);
std::string swhois;
- for (int i = 0; i < Conf->Enumerate("oper"); i++)
+ for (int i = 0; i < Conf.Enumerate("oper"); i++)
{
- std::string name = Conf->ReadValue("oper", "name", i);
+ std::string name = Conf.ReadValue("oper", "name", i);
if (name == params[0])
{
- swhois = Conf->ReadValue("oper", "swhois", i);
+ swhois = Conf.ReadValue("oper", "swhois", i);
break;
}
}
if (!swhois.length())
{
- for (int i = 0; i < Conf->Enumerate("type"); i++)
+ for (int i = 0; i < Conf.Enumerate("type"); i++)
{
- std::string type = Conf->ReadValue("type", "name", i);
+ std::string type = Conf.ReadValue("type", "name", i);
if (type == user->oper)
{
- swhois = Conf->ReadValue("type", "swhois", i);
+ swhois = Conf.ReadValue("type", "swhois", i);
break;
}
}
}
- std::string *old;
- if (user->GetExt("swhois", old))
- {
- user->Shrink("swhois");
- delete old;
- }
-
if (!swhois.length())
return;
- std::string *text = new std::string(swhois);
- user->Extend("swhois", text);
- ServerInstance->PI->SendMetaData(user, "swhois", *text);
+ cmd.swhois.set(user, swhois);
+ ServerInstance->PI->SendMetaData(user, "swhois", swhois);
}
- virtual ~ModuleSWhois()
+ ~ModuleSWhois()
{
- delete Conf;
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
}
diff --git a/src/modules/m_uhnames.cpp b/src/modules/m_uhnames.cpp
index c72c6f814..af8f0690f 100644
--- a/src/modules/m_uhnames.cpp
+++ b/src/modules/m_uhnames.cpp
@@ -18,37 +18,30 @@
class ModuleUHNames : public Module
{
- CUList nl;
public:
+ GenericCap cap;
- ModuleUHNames(InspIRCd* Me)
- : Module(Me)
+ ModuleUHNames(InspIRCd* Me) : Module(Me), cap(this, "userhost-in-names")
{
- Implementation eventlist[] = { I_OnEvent, I_OnSyncUser, I_OnPreCommand, I_OnNamesListItem, I_On005Numeric };
+ Implementation eventlist[] = { I_OnEvent, I_OnPreCommand, I_OnNamesListItem, I_On005Numeric };
ServerInstance->Modules->Attach(eventlist, this, 5);
}
- virtual ~ModuleUHNames()
+ ~ModuleUHNames()
{
}
- void OnSyncUser(User* user, Module* proto,void* opaque)
- {
- if (proto->ProtoTranslate(NULL) == "?" && user->GetExt("UHNAMES"))
- proto->ProtoSendMetaData(opaque, user, "UHNAMES", "Enabled");
- }
-
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$",VF_VENDOR,API_VERSION);
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
output.append(" UHNAMES");
}
- virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
+ ModResult OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
{
irc::string c = command.c_str();
/* We don't actually create a proper command handler class for PROTOCTL,
@@ -60,16 +53,16 @@ class ModuleUHNames : public Module
{
if ((parameters.size()) && (!strcasecmp(parameters[0].c_str(),"UHNAMES")))
{
- user->Extend("UHNAMES");
+ cap.ext.set(user, 1);
return MOD_RES_DENY;
}
}
return MOD_RES_PASSTHRU;
}
- virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
+ void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick)
{
- if (!issuer->GetExt("UHNAMES"))
+ if (!cap.ext.get(issuer))
return;
if (nick.empty())
@@ -78,9 +71,9 @@ class ModuleUHNames : public Module
nick = user->GetFullHost();
}
- virtual void OnEvent(Event* ev)
+ void OnEvent(Event* ev)
{
- GenericCapHandler(ev, "UHNAMES", "userhost-in-names");
+ cap.HandleEvent(ev);
}
};
diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp
index 31edcc0e2..ab32c6740 100644
--- a/src/modules/m_watch.cpp
+++ b/src/modules/m_watch.cpp
@@ -138,6 +138,7 @@ class CommandWatch : public Command
{
unsigned int& MAX_WATCH;
public:
+ SimpleExtItem<watchlist> ext;
CmdResult remove_watch(User* user, const char* nick)
{
// removing an item from the list
@@ -147,8 +148,8 @@ class CommandWatch : public Command
return CMD_FAILURE;
}
- watchlist* wl;
- if (user->GetExt("watchlist", wl))
+ watchlist* wl = ext.get(user);
+ if (wl)
{
/* Yup, is on my list */
watchlist::iterator n = wl->find(nick);
@@ -168,8 +169,7 @@ class CommandWatch : public Command
if (wl->empty())
{
- user->Shrink("watchlist");
- delete wl;
+ ext.unset(user);
}
watchentries::iterator x = whos_watching_me->find(nick);
@@ -198,11 +198,11 @@ class CommandWatch : public Command
return CMD_FAILURE;
}
- watchlist* wl;
- if (!user->GetExt("watchlist", wl))
+ watchlist* wl = ext.get(user);
+ if (!wl)
{
wl = new watchlist();
- user->Extend("watchlist", wl);
+ ext.set(user, wl);
}
if (wl->size() == MAX_WATCH)
@@ -248,7 +248,8 @@ class CommandWatch : public Command
return CMD_SUCCESS;
}
- CommandWatch (InspIRCd* Instance, Module* parent, unsigned int &maxwatch) : Command(Instance,parent,"WATCH",0,0), MAX_WATCH(maxwatch)
+ CommandWatch (InspIRCd* Instance, Module* parent, unsigned int &maxwatch)
+ : Command(Instance,parent,"WATCH",0,0), MAX_WATCH(maxwatch), ext("watchlist", parent)
{
syntax = "[C|L|S]|[+|-<nick>]";
TRANSLATE2(TR_TEXT, TR_END); /* we watch for a nick. not a UID. */
@@ -258,8 +259,8 @@ class CommandWatch : public Command
{
if (parameters.empty())
{
- watchlist* wl;
- if (user->GetExt("watchlist", wl))
+ watchlist* wl = ext.get(user);
+ if (wl)
{
for (watchlist::iterator q = wl->begin(); q != wl->end(); q++)
{
@@ -277,8 +278,8 @@ class CommandWatch : public Command
if (!strcasecmp(nick,"C"))
{
// watch clear
- watchlist* wl;
- if (user->GetExt("watchlist", wl))
+ watchlist* wl = ext.get(user);
+ if (wl)
{
for (watchlist::iterator i = wl->begin(); i != wl->end(); i++)
{
@@ -297,14 +298,13 @@ class CommandWatch : public Command
}
}
- delete wl;
- user->Shrink("watchlist");
+ ext.unset(user);
}
}
else if (!strcasecmp(nick,"L"))
{
- watchlist* wl;
- if (user->GetExt("watchlist", wl))
+ watchlist* wl = ext.get(user);
+ if (wl)
{
for (watchlist::iterator q = wl->begin(); q != wl->end(); q++)
{
@@ -325,12 +325,12 @@ class CommandWatch : public Command
}
else if (!strcasecmp(nick,"S"))
{
- watchlist* wl;
+ watchlist* wl = ext.get(user);
int you_have = 0;
int youre_on = 0;
std::string list;
- if (user->GetExt("watchlist", wl))
+ if (wl)
{
for (watchlist::iterator q = wl->begin(); q != wl->end(); q++)
list.append(q->first.c_str()).append(" ");
@@ -375,6 +375,7 @@ class Modulewatch : public Module
whos_watching_me = new watchentries();
ServerInstance->AddCommand(&cmdw);
ServerInstance->AddCommand(&sw);
+ Extensible::Register(&cmdw.ext);
Implementation eventlist[] = { I_OnRehash, I_OnGarbageCollect, I_OnCleanup, I_OnUserQuit, I_OnPostConnect, I_OnUserPostNick, I_On005Numeric, I_OnSetAway };
ServerInstance->Modules->Attach(eventlist, this, 8);
}
@@ -424,16 +425,16 @@ class Modulewatch : public Module
{
(*n)->WriteNumeric(601, "%s %s %s %s %lu :went offline", (*n)->nick.c_str() ,user->nick.c_str(), user->ident.c_str(), user->dhost.c_str(), (unsigned long) ServerInstance->Time());
- watchlist* wl;
- if ((*n)->GetExt("watchlist", wl))
+ watchlist* wl = cmdw.ext.get(*n);
+ if (wl)
/* We were on somebody's notify list, set ourselves offline */
(*wl)[user->nick.c_str()] = "";
}
}
/* Now im quitting, if i have a notify list, im no longer watching anyone */
- watchlist* wl;
- if (user->GetExt("watchlist", wl))
+ watchlist* wl = cmdw.ext.get(user);
+ if (wl)
{
/* Iterate every user on my watch list, and take me out of the whos_watching_me map for each one we're watching */
for (watchlist::iterator i = wl->begin(); i != wl->end(); i++)
@@ -452,10 +453,6 @@ class Modulewatch : public Module
whos_watching_me->erase(i2);
}
}
-
- /* User's quitting, we're done with this. */
- delete wl;
- user->Shrink("watchlist");
}
}
@@ -470,21 +467,6 @@ class Modulewatch : public Module
delete old_watch;
}
- virtual void OnCleanup(int target_type, void* item)
- {
- if (target_type == TYPE_USER)
- {
- watchlist* wl;
- User* user = (User*)item;
-
- if (user->GetExt("watchlist", wl))
- {
- user->Shrink("watchlist");
- delete wl;
- }
- }
- }
-
virtual void OnPostConnect(User* user)
{
watchentries::iterator x = whos_watching_me->find(user->nick.c_str());
@@ -494,8 +476,8 @@ class Modulewatch : public Module
{
(*n)->WriteNumeric(600, "%s %s %s %s %lu :arrived online", (*n)->nick.c_str(), user->nick.c_str(), user->ident.c_str(), user->dhost.c_str(), (unsigned long) user->age);
- watchlist* wl;
- if ((*n)->GetExt("watchlist", wl))
+ watchlist* wl = cmdw.ext.get(*n);
+ if (wl)
/* We were on somebody's notify list, set ourselves online */
(*wl)[user->nick.c_str()] = std::string(user->ident).append(" ").append(user->dhost).append(" ").append(ConvToStr(user->age));
}
@@ -511,8 +493,8 @@ class Modulewatch : public Module
{
for (std::deque<User*>::iterator n = new_offline->second.begin(); n != new_offline->second.end(); n++)
{
- watchlist* wl;
- if ((*n)->GetExt("watchlist", wl))
+ watchlist* wl = cmdw.ext.get(*n);
+ if (wl)
{
(*n)->WriteNumeric(601, "%s %s %s %s %lu :went offline", (*n)->nick.c_str(), oldnick.c_str(), user->ident.c_str(), user->dhost.c_str(), (unsigned long) user->age);
(*wl)[oldnick.c_str()] = "";
@@ -524,8 +506,8 @@ class Modulewatch : public Module
{
for (std::deque<User*>::iterator n = new_online->second.begin(); n != new_online->second.end(); n++)
{
- watchlist* wl;
- if ((*n)->GetExt("watchlist", wl))
+ watchlist* wl = cmdw.ext.get(*n);
+ if (wl)
{
(*wl)[user->nick.c_str()] = std::string(user->ident).append(" ").append(user->dhost).append(" ").append(ConvToStr(user->age));
(*n)->WriteNumeric(600, "%s %s %s :arrived online", (*n)->nick.c_str(), user->nick.c_str(), (*wl)[user->nick.c_str()].c_str());
diff --git a/src/modules/transport.h b/src/modules/transport.h
index 9f29ab3d8..ceb16cb73 100644
--- a/src/modules/transport.h
+++ b/src/modules/transport.h
@@ -23,8 +23,7 @@
* Because gnutls and openssl represent key information in
* wildly different ways, this class allows it to be accessed
* in a unified manner. These classes are attached to ssl-
- * connected local users using Extensible::Extend() and the
- * key 'ssl_cert'.
+ * connected local users using SSLCertExt
*/
class ssl_cert
{
@@ -184,11 +183,22 @@ class BufferedSocketNameRequest : public ISHRequest
}
};
-class BufferedSocketFingerprintRequest : public ISHRequest
+struct BufferedSocketCertificateRequest : public Request
{
- public:
- /** Initialize request as a fingerprint message */
- BufferedSocketFingerprintRequest(BufferedSocket* is, Module* Me, Module* Target) : ISHRequest(Me, Target, "GET_FP", is)
+ Extensible* const item;
+ ssl_cert* cert;
+ BufferedSocketCertificateRequest(Extensible* is, Module* Me, Module* Target)
+ : Request(Me, Target, "GET_CERT"), item(is), cert(NULL)
+ {
+ }
+};
+
+struct BufferedSocketFingerprintSubmission : public Request
+{
+ Extensible* const item;
+ ssl_cert* const cert;
+ BufferedSocketFingerprintSubmission(Extensible* is, Module* Me, Module* Target, ssl_cert* Cert)
+ : Request(Me, Target, "SET_CERT"), item(is), cert(Cert)
{
}
};
diff --git a/src/users.cpp b/src/users.cpp
index 63de155b7..4940df24e 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -25,14 +25,18 @@ unsigned long uniq_id = 1;
static unsigned long* already_sent = NULL;
+LocalIntExt User::NICKForced("NICKForced", NULL);
+LocalStringExt User::OperQuit("OperQuit", NULL);
+
+static bool dummy_init = Extensible::Register(&User::NICKForced) ^ Extensible::Register(&User::OperQuit);
void InitializeAlreadySent(SocketEngine* SE)
{
+ (void)dummy_init;
already_sent = new unsigned long[SE->GetMaxFds()];
memset(already_sent, 0, SE->GetMaxFds() * sizeof(unsigned long));
}
-
std::string User::ProcessNoticeMasks(const char *sm)
{
bool adding = true, oldadding = false;
@@ -1028,11 +1032,9 @@ bool User::ForceNickChange(const char* newnick)
this->InvalidateCache();
- this->Extend("NICKForced");
-
+ NICKForced.set(this, 1);
FIRST_MOD_RESULT(ServerInstance, OnUserPreNick, MOD_RESULT, (this, newnick));
-
- this->Shrink("NICKForced");
+ NICKForced.set(this, 0);
if (MOD_RESULT == MOD_RES_DENY)
{
@@ -1046,9 +1048,9 @@ bool User::ForceNickChange(const char* newnick)
{
std::vector<std::string> parameters;
parameters.push_back(newnick);
- this->Extend("NICKForced");
+ NICKForced.set(this, 1);
bool result = (ServerInstance->Parser->CallHandler("NICK", parameters, this) == CMD_SUCCESS);
- this->Shrink("NICKForced");
+ NICKForced.set(this, 0);
return result;
}