]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Add a metric assload of TRANSLATE macros to modules.
[user/henk/code/inspircd.git] / src / users.cpp
index eb676b06a69c3c32958056880be25a921fa917d0..35a0e716fe50ecb88639e4078a25a61a65dc9227 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"
@@ -323,10 +320,9 @@ void userrec::DecrementModes()
        }
 }
 
-userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance)
+userrec::userrec(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance)
 {
-       // the PROPER way to do it, AVOID bzero at *ALL* costs
-       *password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
+       *password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = *uuid = 0;
        server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
        reset_due = ServerInstance->Time();
        age = ServerInstance->Time(true);
@@ -346,6 +342,19 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance)
        memset(snomasks,0,sizeof(snomasks));
        /* Invalidate cache */
        operquit = cached_fullhost = cached_hostip = cached_makehost = cached_fullrealhost = NULL;
+
+       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()
@@ -392,6 +401,8 @@ userrec::~userrec()
                }
 #endif
        }
+
+       ServerInstance->uuidlist->erase(uuid);
 }
 
 char* userrec::MakeHost()
@@ -436,8 +447,8 @@ char* userrec::MakeHostIP()
 
 void userrec::CloseSocket()
 {
-       shutdown(this->fd,2);
-       close(this->fd);
+       ServerInstance->SE->Shutdown(this, 2);
+       ServerInstance->SE->Close(this);
 }
 
 char* userrec::GetFullHost()
@@ -727,11 +738,8 @@ void userrec::FlushWriteBuf()
                if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
                {
                        int old_sendq_length = sendq.length();
-#ifndef WIN32
-               int n_sent = write(this->fd, this->sendq.data(), this->sendq.length());
-#else
-               int n_sent = send(this->fd, (const char*)this->sendq.data(), this->sendq.length(), 0);
-#endif
+                       int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0);
+
                        if (n_sent == -1)
                        {
                                if (errno == EAGAIN)
@@ -862,8 +870,14 @@ 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)
 {
-       std::string tempnick = ConvToStr(socket) + "-unknown";
-       user_hash::iterator iter = Instance->clientlist->find(tempnick);
+       /* NOTE: Calling this one parameter constructor for userrec automatically
+        * allocates a new UUID and places it in the hash_map.
+        */
+       userrec* New = new userrec(Instance);
+       int j = 0;
+
+       Instance->unregistered_count++;
+
        char ipaddr[MAXBUF];
 #ifdef IPV6
        if (socketfamily == AF_INET6)
@@ -871,31 +885,12 @@ 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++;
 
-       /*
-        * fix by brain.
-        * as these nicknames are 'RFC impossible', we can be sure nobody is going to be
-        * using one as a registered connection. As they are per fd, we can also safely assume
-        * that we wont have collisions. Therefore, if the nick exists in the list, its only
-        * used by a dead socket, erase the iterator so that the new client may reclaim it.
-        * this was probably the cause of 'server ignores me when i hammer it with reconnects'
-        * issue in earlier alphas/betas
-        */
-       if (iter != Instance->clientlist->end())
-       {
-               userrec* goner = iter->second;
-               DELETE(goner);
-               Instance->clientlist->erase(iter);
-       }
+       (*(Instance->clientlist))[New->uuid] = New;
+       New->SetFd(socket);
 
-       New = new userrec(Instance);
-       (*(Instance->clientlist))[tempnick] = New;
-       New->fd = socket;
-       strlcpy(New->nick,tempnick.c_str(),NICKMAX-1);
+       /* The users default nick is their UUID */
+       strlcpy(New->nick, New->uuid, NICKMAX - 1);
 
        New->server = Instance->FindServerNamePtr(Instance->Config->ServerName);
        /* We don't need range checking here, we KNOW 'unknown\0' will fit into the ident field. */
@@ -1040,6 +1035,7 @@ void userrec::CheckClass(const std::string &explicit_class)
        this->threshold = a->GetThreshold();
        this->sendqmax = a->GetSendqMax();
        this->recvqmax = a->GetRecvqMax();
+       this->MaxChans = a->GetMaxChans();
 }
 
 void userrec::FullConnect()
@@ -1101,6 +1097,9 @@ void userrec::FullConnect()
 
        ServerInstance->Config->Send005(this);
 
+       this->WriteServ("042 %s %s :your unique ID", this->nick, this->uuid);
+
+
        this->ShowMOTD();
 
        /* Now registered */
@@ -1194,7 +1193,15 @@ bool userrec::ForceNickChange(const char* newnick)
 
                if (this->registered == REG_ALL)
                {
-                       return (ServerInstance->Parser->CallHandler("NICK", &newnick, 1, this) == CMD_SUCCESS);
+                       std::deque<classbase*> dummy;
+                       command_t* nickhandler = ServerInstance->Parser->GetHandler("NICK");
+                       if (nickhandler)
+                       {
+                               nickhandler->HandleInternal(1, dummy);
+                               bool result = (ServerInstance->Parser->CallHandler("NICK", &newnick, 1, this) == CMD_SUCCESS);
+                               nickhandler->HandleInternal(0, dummy);
+                               return result;
+                       }
                }
                return false;
        }
@@ -1853,6 +1860,10 @@ void userrec::SplitChanList(userrec* dest, const std::string &cl)
        }
 }
 
+unsigned int userrec::GetMaxChans()
+{
+       return this->MaxChans;
+}
 
 /* looks up a users password for their connection class (<ALLOW>/<DENY> tags)
  * NOTE: If the <ALLOW> or <DENY> tag specifies an ip, and this user resolves,