]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
cmode(), cflags(), cstatus() -> chanrec::GetStatusChar(), chanrec::GetStatusFlags...
[user/henk/code/inspircd.git] / src / users.cpp
index e35c5cab8db1854bb6f8a2f430d56f8112fd01c4..ad358211dd777d4cd980b22bd3cccb445f2839b5 100644 (file)
@@ -132,7 +132,8 @@ void userrec::StartDNSLookup()
        log(DEBUG,"Commencing reverse lookup");
        try
        {
-               res_reverse = new UserResolver(ServerInstance, this, this->GetIPString(), false);
+               log(DEBUG,"Passing instance: %08x",this->ServerInstance);
+               res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), false);
                MyServer->AddResolver(res_reverse);
        }
        catch (ModuleException& e)
@@ -142,7 +143,7 @@ void userrec::StartDNSLookup()
 }
 
 UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, bool forward) :
-       Resolver(to_resolve, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE), bound_user(user), ServerInstance(Instance)
+       Resolver(Instance, to_resolve, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE), bound_user(user)
 {
        this->fwd = forward;
        this->bound_fd = user->fd;
@@ -256,6 +257,7 @@ const char* userrec::FormatModes()
 
 userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance)
 {
+       log(DEBUG,"userrec::userrec(): Instance: %08x",ServerInstance);
        // the PROPER way to do it, AVOID bzero at *ALL* costs
        *password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
        server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
@@ -495,7 +497,7 @@ bool userrec::AddBuffer(const std::string &a)
        if (recvq.length() > (unsigned)this->recvqmax)
        {
                this->SetWriteError("RecvQ exceeded");
-               WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
+               ServerInstance->WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
                return false;
        }
 
@@ -552,7 +554,7 @@ void userrec::AddWriteBuf(const std::string &data)
                 * to repeatedly add the text to the sendq!
                 */
                this->SetWriteError("SendQ exceeded");
-               WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
+               ServerInstance->WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
                return;
        }
        
@@ -662,7 +664,7 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user,const std::string &quit
 
        if (user->registered == REG_ALL)
        {
-               purge_empty_chans(user);
+               user->PurgeEmptyChannels();
                FOREACH_MOD_I(Instance,I_OnUserQuit,OnUserQuit(user,reason));
                user->WriteCommonExcept("QUIT :%s",reason.c_str());
        }
@@ -691,7 +693,7 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user,const std::string &quit
        }
 
        /*
-        * this must come before the WriteOpers so that it doesnt try to fill their buffer with anything
+        * this must come before the ServerInstance->WriteOpers so that it doesnt try to fill their buffer with anything
         * if they were an oper with +s.
         *
         * XXX -
@@ -701,7 +703,7 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user,const std::string &quit
        if (user->registered == REG_ALL)
        {
                if (IS_LOCAL(user))
-                       WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,reason.c_str());
+                       Instance->WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,reason.c_str());
                user->AddToWhoWas();
        }
 
@@ -968,7 +970,7 @@ void userrec::FullConnect(CullList* Goners)
        ServerInstance->stats->statsConnects++;
        this->idle_lastmsg = TIME;
 
-       ConnectClass a = GetClass(this);
+       ConnectClass a = this->GetClass();
 
        if (a.type == CC_DENY)
        {
@@ -985,13 +987,13 @@ void userrec::FullConnect(CullList* Goners)
        if (this->LocalCloneCount() > a.maxlocal)
        {
                Goners->AddItem(this, "No more connections allowed from your host via this connect class (local)");
-               WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a.maxlocal, this->GetIPString());
+               ServerInstance->WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a.maxlocal, this->GetIPString());
                return;
        }
        else if (this->GlobalCloneCount() > a.maxglobal)
        {
                Goners->AddItem(this, "No more connections allowed from your host via this connect class (global)");
-               WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a.maxglobal, this->GetIPString());
+               ServerInstance->WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a.maxglobal, this->GetIPString());
                return;
        }
 
@@ -1059,7 +1061,7 @@ void userrec::FullConnect(CullList* Goners)
        FOREACH_MOD(I_OnUserConnect,OnUserConnect(this));
        FOREACH_MOD(I_OnGlobalConnect,OnGlobalConnect(this));
        this->registered = REG_ALL;
-       WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]", this->GetPort(), this->nick, this->ident, this->host, this->GetIPString());
+       ServerInstance->WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]", this->GetPort(), this->nick, this->ident, this->host, this->GetIPString());
 }
 
 /** userrec::UpdateNick()
@@ -1651,3 +1653,113 @@ void userrec::NoticeAll(char* text, ...)
        }
 }
 
+
+std::string userrec::ChannelList(userrec* source)
+{
+       std::string list;
+       for (std::vector<ucrec*>::const_iterator i = this->chans.begin(); i != this->chans.end(); i++)
+       {
+               ucrec* rec = *i;
+
+               if(rec->channel && rec->channel->name)
+               {
+                       /* If the target is the same as the sender, let them see all their channels.
+                        * If the channel is NOT private/secret OR the user shares a common channel
+                        * If the user is an oper, and the <options:operspywhois> option is set.
+                        */
+                       if ((source == this) || (*source->oper && ServerInstance->Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET])) || (rec->channel->HasUser(source))))
+                       {
+                               list.append(rec->channel->GetStatusChar(this)).append(rec->channel->name).append(" ");
+                       }
+               }
+       }
+       return list;
+}
+
+void userrec::SplitChanList(userrec* dest, const std::string &cl)
+{
+       std::string line;
+       std::ostringstream prefix;
+       std::string::size_type start, pos, length;
+
+       prefix << ":" << ServerInstance->Config->ServerName << " 319 " << this->nick << " " << dest->nick << " :";
+       line = prefix.str();
+
+       for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
+       {
+               length = (pos == std::string::npos) ? cl.length() : pos;
+
+               if (line.length() + length - start > 510)
+               {
+                       this->Write(line);
+                       line = prefix.str();
+               }
+
+               if(pos == std::string::npos)
+               {
+                       line += cl.substr(start, length - start);
+                       break;
+               }
+               else
+               {
+                       line += cl.substr(start, length - start + 1);
+               }
+       }
+
+       if (line.length())
+       {
+               this->Write(line);
+       }
+}
+
+
+/* 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,
+ * then their ip will be taken as 'priority' anyway, so for example,
+ * <connect allow="127.0.0.1"> will match joe!bloggs@localhost
+ */
+ConnectClass& userrec::GetClass()
+{
+        for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
+        {
+                if ((match(this->GetIPString(),i->host.c_str(),true)) || (match(this->host,i->host.c_str())))
+                        return *i;
+        }
+
+        return *(ServerInstance->Config->Classes.begin());
+}
+
+void userrec::PurgeEmptyChannels()
+{
+        std::vector<chanrec*> to_delete;
+
+        // firstly decrement the count on each channel
+        for (std::vector<ucrec*>::iterator f = this->chans.begin(); f != this->chans.end(); f++)
+        {
+                ucrec* uc = *f;
+                if (uc->channel)
+                {
+                        if (uc->channel->DelUser(this) == 0)
+                        {
+                                /* No users left in here, mark it for deletion */
+                                to_delete.push_back(uc->channel);
+                                uc->channel = NULL;
+                        }
+                }
+        }
+
+        for (std::vector<chanrec*>::iterator n = to_delete.begin(); n != to_delete.end(); n++)
+        {
+                chanrec* thischan = *n;
+                chan_hash::iterator i2 = ServerInstance->chanlist.find(thischan->name);
+                if (i2 != ServerInstance->chanlist.end())
+                {
+                        FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
+                        DELETE(i2->second);
+                        ServerInstance->chanlist.erase(i2);
+                }
+        }
+
+        this->UnOper();
+}
+