]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Change Extensible to use strongly typed entries
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 13 Sep 2009 20:30:25 +0000 (20:30 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 13 Sep 2009 20:30:25 +0000 (20:30 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11696 e03df62e-2008-0410-955e-edbf42e46eb7

54 files changed:
include/base.h
include/extensible.h [new file with mode: 0644]
include/inspircd.h
include/modules.h
include/u_listmode.h
include/users.h
src/base.cpp
src/commands/cmd_nick.cpp
src/commands/cmd_quit.cpp
src/commands/cmd_who.cpp
src/dns.cpp
src/inspsocket.cpp
src/modules.cpp
src/modules/extra/m_ssl_gnutls.cpp
src/modules/extra/m_ssl_openssl.cpp
src/modules/m_antibear.cpp
src/modules/m_banexception.cpp
src/modules/m_banredirect.cpp
src/modules/m_blockamsg.cpp
src/modules/m_callerid.cpp
src/modules/m_cap.cpp
src/modules/m_cap.h
src/modules/m_cgiirc.cpp
src/modules/m_chanfilter.cpp
src/modules/m_channelban.cpp
src/modules/m_check.cpp
src/modules/m_cloaking.cpp
src/modules/m_conn_waitpong.cpp
src/modules/m_customtitle.cpp
src/modules/m_ident.cpp
src/modules/m_inviteexception.cpp
src/modules/m_joinflood.cpp
src/modules/m_kicknorejoin.cpp
src/modules/m_messageflood.cpp
src/modules/m_namesx.cpp
src/modules/m_nickflood.cpp
src/modules/m_nicklock.cpp
src/modules/m_nonicks.cpp
src/modules/m_regonlycreate.cpp
src/modules/m_safelist.cpp
src/modules/m_sasl.cpp
src/modules/m_services_account.cpp
src/modules/m_silence.cpp
src/modules/m_spanningtree/hmac.cpp
src/modules/m_spanningtree/main.cpp
src/modules/m_spanningtree/netburst.cpp
src/modules/m_spanningtree/operquit.cpp
src/modules/m_sslinfo.cpp
src/modules/m_sslmodes.cpp
src/modules/m_swhois.cpp
src/modules/m_uhnames.cpp
src/modules/m_watch.cpp
src/modules/transport.h
src/users.cpp

index 6bcf7681711fdc1d2a16ea75dd8a35f43fc7604c..ab52545f9716992ddb8fa31f2f06828f48a45e17 100644 (file)
@@ -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 (file)
index 0000000..0a33470
--- /dev/null
@@ -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);
+};
index ae46569a01f9314591a5a10c5c137bb9b3653793..a7eed47ff53b1ffcac09a9e4ea7a0f450ebc1df6 100644 (file)
@@ -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"
index 3f779fe80ad69303136cdd0afcfb4772ec1af136..9e9686ad2aa327bf5a0cac0e768a5b815b46b1f7 100644 (file)
@@ -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;
index 773ca421f3d30c6fbc9e835d68124b75172a82a6..9d9b5f836b4c4e69bfad5af8afe2faec0cec7aa3 100644 (file)
@@ -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)
                        {
index 5338deb4c145e3d3a0eb93f4392bfde5706006fb..a6c36b7fda5985d9d84a86e91269ff15dcf0f78e 100644 (file)
@@ -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
index 7e0cf482a065797a2c72b4d9f438e382797d51cd..4d0c170776d9c7b4d1bfe47fd7878c669b71214c 100644 (file)
 
 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);
+}
index 3851b36e653be95e7939a48e6be12cce62be6f68..6a181bda04df0887b3f626e55e0d60ed53c8f782 100644 (file)
@@ -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;
                        }
 
index 968374dec77dba78b5f748dee229d770c9f1038b..46c7288812d54b922915deeb4c349d99b9f80d83 100644 (file)
@@ -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
        {
index 61b5a0f6032f19a0e56b03628f31c39e08a52401..329c0a2d50af23b843c2086658f48acf284a5c2b 100644 (file)
@@ -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)
index b2dbf40a7d3c3e8ac56dcda7ce0eb9d2e7c63905..94a01e64c9cedbf60bfa70c3dfaee096bf07adce 100644 (file)
@@ -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"
index 1ec32742e8fa8bdab8e7017eac3a66df4059d042..0350858e7ce693ad391825570d3237fe0c466f42 100644 (file)
  * ---------------------------------------------------
  */
 
-/* $Core */
-
+#include "inspircd.h"
 #include "socket.h"
 #include "inspstring.h"
 #include "socketengine.h"
-#include "inspircd.h"
 
 bool BufferedSocket::Readable()
 {
index 59b52b5b1be29d03218e0313ff6fa33472747944..c7509fad9b7188db603a4fcd9c7bc3327698a94b 100644 (file)
@@ -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;
index f5133a1dc7a9a332cf12d42d5aba890fc7e231ce..97a5ebe0e8ef41d904c573532b504775debaf324 100644 (file)
@@ -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);
        }
 };
 
index a8043457bee22b461fd89759a43f65e244d90c34..a33cf6bc218228928c5aaedc96664af807b6f5c9 100644 (file)
@@ -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()
index 70a4a96fb0e09652c8745098ac9401c8e9cccd5d..8eab1359435a11963184d42e6abd972d61e9e711 100644 (file)
 
 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;
        }
 };
index dafa47d2c8d66f4be6da148bc31c8d204f7035bb..9137c09d9239583f7b268d42e7d53b724c312eba 100644 (file)
@@ -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();
index 1a486325a9941966f9bea694da53d2b983391d7f..da08d06fb485df031a3b3ceeb7b4b54f63961c80 100644 (file)
@@ -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 */
 
index 104086bfead5ab2db940eabe3553f6fe2080d44d..5ce32ea8ef56efd8987ea274a5b5041b7061904d 100644 (file)
@@ -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");
-                       }
-               }
-       }
 };
 
 
index 543f5d8a1e536cf754d777f2e03b3d59c91c65e9..2e508399b8ba464e450cc619dcc31dbb608943b2 100644 (file)
@@ -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);
index 626b4c23c33169ee728300424f6998e62588a3a5..160c7a9c92105903a119f7f054be018cbdf088ad 100644 (file)
@@ -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);
        }
 };
 
index ce5aec8ba4b506c62128de18726aeb4904177280..72c7a14a5b6b35bd4a30b8685bb1d27ed29cabdd 100644 (file)
@@ -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
index 41c2154cca250bbb8ccf8ea78a873bc308bea16d..c72e183906a5e5350a0705fe71569f84d16ef6bf 100644 (file)
@@ -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);
index 4f6ebf22a834cccd43e32c386427c8be84bed283..4636d2372a645175a21afa751ac099e97bb5ab56 100644 (file)
@@ -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)
                {
index 8167b8aae724aed831a1af1789a523cc93e03a12..fd5d5d40106bef4650be2753874c785deee8d20e 100644 (file)
@@ -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');
        }
index 7f85b186972a09245c693099b4a1307ffbbab70a..964a8c0756268a90128324bf0ae2512316ce9535 100644 (file)
@@ -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);
index 2fa3b9e6359618d294ea9b747ee97508c093e51a..2a348ba8b57e4c028625a4b738b4b33c21a03353 100644 (file)
@@ -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);
                }
        }
 
index 4da240138b93f0428c3047b1063842910076900f..b77116410ffcd8bc6198a8d302532ff67c586ddb 100644 (file)
@@ -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);
        }
 
 };
index b2933aa54dca8c9fd23e06a1fc78dd84b79af571..fc99cd29f24416302d1e5ffbe50f7a6b6f0a410f 100644 (file)
@@ -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);
        }
 };
 
index 690d7b15c58c88389441beef94a0bc94c514dbed..e5c8940ec29041fe1b4861f18689670c927e9b0f 100644 (file)
@@ -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);
                }
        }
 };
index 29d7eb5d5a2ad453e38b06c1fd90bfb61d89001f..0b3621af7606abff054dc85f3d4258044ef5dc04 100644 (file)
@@ -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);
        }
index 180d583769b864c30ec629f560022a4413c2f7bd..853ddee755dcfd86ae0c1a34c9e355def75e69ab 100644 (file)
@@ -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);
        }
index 04ecfffd7ff28979a62a8bc5227aebeabcfd1edb..47dec1803bb7cca6d756f959246094662b352b14 100644 (file)
@@ -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);
        }
 };
 
index da1038512ccbb63d4ed159553ceb49eab9d6fe53..7d0f594818ae72eb26ec70075a05631ac805e739 100644 (file)
@@ -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);
        }
index 3aa8ec35544869a1c9eaa4ab24d6e0bfb9ca3bec..d0970ef9c09c2dcb8e46a4a7ed5893802b4e7efb 100644 (file)
 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);
        }
 };
 
index 17f3a35f09d01b0ed94fc2cc24d9729e2765b185..898c7358dec9f86cf9c1d646a7bbc8df73e9f3cd 100644 (file)
@@ -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);
        }
 };
 
index e7c9e01994cd85d2d2a8c4f38f2ecba406c26cd6..ddfc4745597257c61ed7a5bf04a77ad5f942ef70 100644 (file)
  */
 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)
index 769097ca0e11a4508bb660ceaee90332c03d9fd4..029ae9d2e32b85abdd8d1c32eed425fcc001ff64 100644 (file)
@@ -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++)
index 5be3031488f98fdec7b1548844fede667d8a51da..c3ecef202a20950e7246b850958e6def965f9655 100644 (file)
@@ -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);
index bd1a541103dcd0f7af4dadeec0331aadef90e489..127b5f304ce217555f67f589880b16ce5b349057 100644 (file)
@@ -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)
index 1436afa3d0e35ae927c62010675630e5dbb321af..069fbdec8076dcabaf5c723d64f0e84f507f1a99 100644 (file)
@@ -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);
        }
 };
 
index cc65038d1b28a72b729631b4f290607bda51012a..cbbfac0a4200648ac358366c234b5b5b2f861ce2 100644 (file)
@@ -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",
index 9cf9f6d4ef6e501951ddcb7ce4609a3952cd26cf..779cb541ebaf18a028224e1d718d8f9b6a1f315c 100644 (file)
@@ -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);
        }
index 332e475858c9980d0834b62b9ff80862ad309290..348a453a6bdbd7eb910839f2b14cdade4a945e24 100644 (file)
@@ -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;
        }
 
index 726b0713e79a13d99968b19efcf736f5b2965ca4..5e30ced35b7413620262d2bc5bcc91d27a799b87 100644 (file)
@@ -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);
index 951d019ef71c6a6527a95fe756facd637f74a91e..abefad728ac9d3b861ec26d0a90305ca6c12206f 100644 (file)
@@ -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));
                }
        }
 }
index 5260cd990d372d2292a00ef61c61574386d41013..5cdee3bc6f7d647136f04797a8576c5c6b581203 100644 (file)
@@ -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);
        }
index 715d9110a87a006cce7acd953dc5a82ea606e521..bf02ed87918686e8613c4b41aa6107d37b5456d5 100644 (file)
 
 /* $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)
index b19347ea7c8b43e6d24c4bd36bca5493a4471de7..a0725206930d44e77106932d17f03e4f63b3c57d 100644 (file)
  */
 
 #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);
        }
index ebff25cb838ace4ad742134d54e06c07d7b269da..bd2447c2afaf8c8a317e80fc9a41923a46a5f06f 100644 (file)
@@ -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);
        }
index c72c6f814597b5a396d0c99542528fedd4449111..af8f0690fb9d2d0fed399159a179a6357472317c 100644 (file)
 
 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);
        }
 };
 
index 31edcc0e21d773944f75ae4576641d1157dc89e4..ab32c674047ba31f5ccc2bb58019e9d019d0f16d 100644 (file)
@@ -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());
index 9f29ab3d8b7646d3696fca4dbd1337a19e83f3e6..ceb16cb731fa4fee090e107484292375dbc96070 100644 (file)
@@ -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)
        {
        }
 };
index 63de155b7dc532db6d4bda15b876da3e0f7ca253..4940df24ebd2d90a03d4543f98a8a27f39225e3d 100644 (file)
@@ -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;
        }