]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
This fixes a deletion error here, we were using new[] and not using delete[], but...
[user/henk/code/inspircd.git] / src / users.cpp
index 99377a22475d5c8ae69f0407360b486d6a6fea59..8ab475bd9e9278754cb80ee0ab9df05b42b2bdf9 100644 (file)
@@ -12,9 +12,6 @@
  */
 
 #include "inspircd.h"
-#include "configreader.h"
-#include "channels.h"
-#include "users.h"
 #include <stdarg.h>
 #include "socketengine.h"
 #include "wildcard.h"
@@ -312,13 +309,18 @@ const char* userrec::FormatModes()
 
 void userrec::DecrementModes()
 {
-       for (int n = 0; n < 64; n++)
+       ServerInstance->Log(DEBUG,"DecrementModes()");
+       for (unsigned char n = 'A'; n <= 'z'; n++)
        {
-               if (modes[n])
+               if (modes[n-65])
                {
-                       ModeHandler* mh = ServerInstance->Modes->FindMode(n+65, MODETYPE_USER);
+                       ServerInstance->Log(DEBUG,"DecrementModes() found mode %c", n);
+                       ModeHandler* mh = ServerInstance->Modes->FindMode(n, MODETYPE_USER);
                        if (mh)
+                       {
+                               ServerInstance->Log(DEBUG,"Found handler %c and call ChangeCount", n);
                                mh->ChangeCount(-1);
+                       }
                }
        }
 }
@@ -345,8 +347,19 @@ userrec::userrec(InspIRCd* Instance, const std::string &uid) : ServerInstance(In
        memset(snomasks,0,sizeof(snomasks));
        /* Invalidate cache */
        operquit = cached_fullhost = cached_hostip = cached_makehost = cached_fullrealhost = NULL;
-       if (!uid.empty())
+
+       if (uid.empty())
+               strlcpy(uuid, Instance->GetUID().c_str(), UUID_LENGTH);
+       else
                strlcpy(uuid, uid.c_str(), UUID_LENGTH);
+
+       ServerInstance->Log(DEBUG,"New UUID for user: %s (%s)", uuid, uid.empty() ? "allocated new" : "used remote");
+
+       user_hash::iterator finduuid = Instance->uuidlist->find(uuid);
+       if (finduuid == Instance->uuidlist->end())
+               (*Instance->uuidlist)[uuid] = this;
+       else
+               throw CoreException("Duplicate UUID "+std::string(uuid)+" in userrec constructor");
 }
 
 void userrec::RemoveCloneCounts()
@@ -393,6 +406,8 @@ userrec::~userrec()
                }
 #endif
        }
+
+       ServerInstance->uuidlist->erase(uuid);
 }
 
 char* userrec::MakeHost()
@@ -820,16 +835,9 @@ void userrec::UnOper()
                        // unset their oper type (what IS_OPER checks), and remove +o
                        *this->oper = 0;
                        this->modes[UM_OPERATOR] = 0;
-
-                       // remove them from the opers list.
-                       for (std::vector<userrec*>::iterator a = ServerInstance->all_opers.begin(); a < ServerInstance->all_opers.end(); a++)
-                       {
-                               if (*a == this)
-                               {
-                                       ServerInstance->all_opers.erase(a);
-                                       return;
-                               }
-                       }
+                       
+                       // remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404
+                       ServerInstance->all_opers.remove(this);
                }
        }
 
@@ -860,9 +868,25 @@ void userrec::AddToWhoWas()
 /* add a client connection to the sockets list */
 void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip)
 {
-       userrec* New = new userrec(Instance);
+       /* NOTE: Calling this one parameter constructor for userrec automatically
+        * allocates a new UUID and places it in the hash_map.
+        */
+       userrec* New = NULL;
+       try
+       {
+               New = new userrec(Instance);
+       }
+       catch (...)
+       {
+               Instance->Log(DEFAULT,"*** WTF *** Duplicated UUID! -- Crack smoking monkies have been unleashed.");
+               Instance->WriteOpers("*** WARNING *** Duplicate UUID allocated!");
+               return;
+       }
+
+       int j = 0;
+
+       Instance->unregistered_count++;
 
-       user_hash::iterator iter = Instance->clientlist->find(New->uuid);
        char ipaddr[MAXBUF];
 #ifdef IPV6
        if (socketfamily == AF_INET6)
@@ -870,13 +894,11 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached,
        else
 #endif
        inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr));
-       userrec* New;
-       int j = 0;
 
-       Instance->unregistered_count++;
+       (*(Instance->clientlist))[New->uuid] = New;
+       New->SetFd(socket);
 
-       (*(Instance->clientlist))[user->uuid] = New;
-       New->fd = socket;
+       /* The users default nick is their UUID */
        strlcpy(New->nick, New->uuid, NICKMAX - 1);
 
        New->server = Instance->FindServerNamePtr(Instance->Config->ServerName);
@@ -1361,7 +1383,7 @@ void userrec::Write(std::string text)
 
        try
        {
-               /* ServerInstance->Log(DEBUG,"C[%d] <- %s", this->GetFd(), text.c_str());
+               /* ServerInstance->Log(DEBUG,"C[%d] O %s", this->GetFd(), text.c_str());
                 * WARNING: The above debug line is VERY loud, do NOT
                 * enable it till we have a good way of filtering it
                 * out of the logs (e.g. 1.2 would be good).