]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
added added "./configure -svnupdate rebuild"
[user/henk/code/inspircd.git] / src / users.cpp
index 50589dd6e2fe34c5f80c5265bda61056993af5b8..c7f74da0b95b0ac8f2ee0cd374778984adc5a23a 100644 (file)
@@ -49,16 +49,62 @@ extern time_t TIME;
 extern userrec* fd_ref_table[MAX_DESCRIPTORS];
 extern ServerConfig *Config;
 extern user_hash clientlist;
-extern whowas_hash whowas;
+
+whowas_users whowas;
+
 extern std::vector<userrec*> local_users;
 
 std::vector<userrec*> all_opers;
 
-template<typename T> inline string ConvToStr(const T &in)
+typedef std::map<irc::string,char*> opertype_t;
+typedef opertype_t operclass_t;
+
+opertype_t opertypes;
+operclass_t operclass;
+
+bool InitTypes(const char* tag)
+{
+       for (opertype_t::iterator n = opertypes.begin(); n != opertypes.end(); n++)
+       {
+               if (n->second)
+                       delete[] n->second;
+       }
+       opertypes.clear();
+       return true;
+}
+
+bool InitClasses(const char* tag)
+{
+       for (operclass_t::iterator n = operclass.begin(); n != operclass.end(); n++)
+       {
+               if (n->second)
+                       delete[] n->second;
+       }
+       operclass.clear();
+       return true;
+}
+
+bool DoType(const char* tag, char** entries, void** values, int* types)
 {
-        stringstream tmp;
-        if (!(tmp << in)) return string();
-        return tmp.str();
+       char* TypeName = (char*)values[0];
+       char* Classes = (char*)values[1];
+       opertypes[TypeName] = strdup(Classes);
+       log(DEBUG,"Read oper TYPE '%s' with classes '%s'",TypeName,Classes);
+       return true;
+}
+
+bool DoClass(const char* tag, char** entries, void** values, int* types)
+{
+       char* ClassName = (char*)values[0];
+       char* CommandList = (char*)values[1];
+       operclass[ClassName] = strdup(CommandList);
+       log(DEBUG,"Read oper CLASS '%s' with commands '%s'",ClassName,CommandList);
+       return true;
+}
+
+bool DoneClassesAndTypes(const char* tag)
+{
+       return true;
 }
 
 userrec::userrec()
@@ -68,16 +114,29 @@ userrec::userrec()
        server = (char*)FindServerNamePtr(Config->ServerName);
        reset_due = TIME;
        lines_in = fd = lastping = signon = idle_lastmsg = nping = registered = 0;
-       timeout = flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
+       modebits = timeout = flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
        haspassed = dns_done = false;
        recvq = "";
        sendq = "";
        chans.clear();
        invites.clear();
+        chans.resize(MAXCHANS);
+        for (unsigned int n = 0; n < MAXCHANS; n++)
+        {
+               ucrec* x = new ucrec();
+               chans[n] = x;
+               x->channel = NULL;
+               x->uc_modes = 0;
+        }
 }
 
 userrec::~userrec()
 {
+       for (std::vector<ucrec*>::iterator n = chans.begin(); n != chans.end(); n++)
+       {
+               ucrec* x = (ucrec*)*n;
+               delete x;
+       }
 }
 
 void userrec::MakeHost(char* nhost)
@@ -194,9 +253,8 @@ void userrec::RemoveInvite(irc::string &channel)
                }
 }
 
-bool userrec::HasPermission(std::string &command)
+bool userrec::HasPermission(const std::string &command)
 {
-       char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF];
        char* mycmd;
        char* savept;
        char* savept2;
@@ -211,47 +269,48 @@ bool userrec::HasPermission(std::string &command)
        // are they even an oper at all?
        if (*this->oper)
        {
-               for (int j =0; j < Config->ConfValueEnum("type",&Config->config_f); j++)
+               opertype_t::iterator iter_opertype = opertypes.find(this->oper);
+               if (iter_opertype != opertypes.end())
                {
-                       Config->ConfValue("type","name",j,TypeName,&Config->config_f);
-                       if (!strcmp(TypeName,this->oper))
+                       char* Classes = strdup(iter_opertype->second);
+                       char* myclass = strtok_r(Classes," ",&savept);
+                       while (myclass)
                        {
-                               Config->ConfValue("type","classes",j,Classes,&Config->config_f);
-                               char* myclass = strtok_r(Classes," ",&savept);
-                               while (myclass)
+                               operclass_t::iterator iter_operclass = operclass.find(myclass);
+                               if (iter_operclass != operclass.end())
                                {
-                                       for (int k =0; k < Config->ConfValueEnum("class",&Config->config_f); k++)
+                                       char* CommandList = strdup(iter_operclass->second);
+                                       mycmd = strtok_r(CommandList," ",&savept2);
+                                       while (mycmd)
                                        {
-                                               Config->ConfValue("class","name",k,ClassName,&Config->config_f);
-                                               if (!strcmp(ClassName,myclass))
+                                               if ((!strcasecmp(mycmd,command.c_str())) || (*mycmd == '*'))
                                                {
-                                                       Config->ConfValue("class","commands",k,CommandList,&Config->config_f);
-                                                       mycmd = strtok_r(CommandList," ",&savept2);
-                                                       while (mycmd)
-                                                       {
-                                                               if ((!strcasecmp(mycmd,command.c_str())) || (*mycmd == '*'))
-                                                               {
-                                                                       return true;
-                                                               }
-                                                               mycmd = strtok_r(NULL," ",&savept2);
-                                                       }
+                                                       free(Classes);
+                                                       free(CommandList);
+                                                       return true;
                                                }
+                                               mycmd = strtok_r(NULL," ",&savept2);
                                        }
-                                       myclass = strtok_r(NULL," ",&savept);
+                                       free(CommandList);
                                }
+                               myclass = strtok_r(NULL," ",&savept);
                        }
+                       free(Classes);
                }
        }
        return false;
 }
 
 
-bool userrec::AddBuffer(std::string a)
+bool userrec::AddBuffer(const std::string &a)
 {
         std::string b = "";
-        for (unsigned int i = 0; i < a.length(); i++)
-                if ((a[i] != '\r') && (a[i] != '\0') && (a[i] != 7))
-                        b = b + a[i];
+       char* n = (char*)a.c_str();
+        for (char* i = n; *i; i++)
+       {
+                if ((*i != '\r') && (*i != '\0') && (*i != 7))
+                        b = b + *i;
+       }
         std::stringstream stream(recvq);
         stream << b;
         recvq = stream.str();
@@ -303,9 +362,9 @@ std::string userrec::GetBuffer()
         return ret;
 }
 
-void userrec::AddWriteBuf(std::string data)
+void userrec::AddWriteBuf(const std::string &data)
 {
-       if (this->GetWriteError() != "")
+       if (*this->GetWriteError())
                return;
        if (sendq.length() + data.length() > (unsigned)this->sendqmax)
        {
@@ -345,7 +404,7 @@ void userrec::FlushWriteBuf()
        }
 }
 
-void userrec::SetWriteError(std::string error)
+void userrec::SetWriteError(const std::string &error)
 {
        log(DEBUG,"Setting error string for %s to '%s'",this->nick,error.c_str());
        // don't try to set the error twice, its already set take the first string.
@@ -353,9 +412,9 @@ void userrec::SetWriteError(std::string error)
                this->WriteError = error;
 }
 
-std::string userrec::GetWriteError()
+const char* userrec::GetWriteError()
 {
-       return this->WriteError;
+       return this->WriteError.c_str();
 }
 
 void AddOper(userrec* user)
@@ -383,12 +442,7 @@ void kill_link(userrec *user,const char* r)
 
         char reason[MAXBUF];
 
-        strlcpy(reason,r,MAXBUF-1);
-
-        if (strlen(reason)>MAXQUIT)
-        {
-                reason[MAXQUIT-1] = '\0';
-        }
+        strlcpy(reason,r,MAXQUIT-1);
 
         log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
         Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
@@ -447,58 +501,68 @@ void kill_link(userrec *user,const char* r)
         delete user;
 }
 
+WhoWasGroup::WhoWasGroup(userrec* user) : host(NULL), dhost(NULL), ident(NULL), server(NULL), gecos(NULL), signon(user->signon)
+{
+       this->host = strdup(user->host);
+       this->dhost = strdup(user->dhost);
+       this->ident = strdup(user->ident);
+       this->server = user->server;
+       this->gecos = strdup(user->fullname);
+}
+
+WhoWasGroup::~WhoWasGroup()
+{
+       if (host)
+               free(host);
+       if (dhost)
+               free(dhost);
+       if (ident)
+               free(ident);
+       if (gecos)
+               free(gecos);
+}
+
 /* adds or updates an entry in the whowas list */
 void AddWhoWas(userrec* u)
 {
-        whowas_hash::iterator iter = whowas.find(u->nick);
-        WhoWasUser *a = new WhoWasUser();
-        strlcpy(a->nick,u->nick,NICKMAX-1);
-        strlcpy(a->ident,u->ident,IDENTMAX);
-        strlcpy(a->dhost,u->dhost,63);
-        strlcpy(a->host,u->host,63);
-        strlcpy(a->fullname,u->fullname,MAXGECOS);
-       if (u->server)
-               strlcpy(a->server,u->server,256);
-        a->signon = u->signon;
-
-        /* MAX_WHOWAS:   max number of /WHOWAS items
-         * WHOWAS_STALE: number of hours before a WHOWAS item is marked as stale and
-         *               can be replaced by a newer one
-         */
-
-        if (iter == whowas.end())
-        {
-                if (whowas.size() >= (unsigned)WHOWAS_MAX)
-                {
-                        for (whowas_hash::iterator i = whowas.begin(); i != whowas.end(); i++)
-                        {
-                                // 3600 seconds in an hour ;)
-                                if ((i->second->signon)<(TIME-(WHOWAS_STALE*3600)))
-                                {
-                                        // delete an old one
-                                        if (i->second) delete i->second;
-                                       whowas.erase(i);
-                                        // replace with new one
-                                        whowas[a->nick] = a;
-                                        log(DEBUG,"added WHOWAS entry, purged an old record");
-                                        return;
-                                }
-                        }
-                        // no space left and user doesnt exist. Don't leave ram in use!
-                        delete a;
-                }
-                else
-                {
-                        log(DEBUG,"added fresh WHOWAS entry");
-                        whowas[a->nick] = a;
-                }
-        }
-        else
-        {
-                log(DEBUG,"updated WHOWAS entry");
-                if (iter->second) delete iter->second;
-                iter->second = a;
-        }
+        whowas_users::iterator iter = whowas.find(u->nick);
+       if (iter == whowas.end())
+       {
+               whowas_set* n = new whowas_set;
+               WhoWasGroup *a = new WhoWasGroup(u);
+               n->push_back(a);
+               whowas[u->nick] = n;
+       }
+       else
+       {
+               whowas_set* group = (whowas_set*)iter->second;
+               if (group->size() > 10)
+               {
+                       WhoWasGroup *a = (WhoWasGroup*)*(group->begin());
+                       delete a;
+                       group->pop_front();
+               }
+               WhoWasGroup *a = new WhoWasGroup(u);
+               group->push_back(a);
+       }
+}
+
+/* every hour, run this function which removes all entries over 3 days */
+void MaintainWhoWas(time_t TIME)
+{
+       for (whowas_users::iterator iter = whowas.begin(); iter != whowas.end(); iter++)
+       {
+               whowas_set* n = (whowas_set*)iter->second;
+               if (n->size())
+               {
+                       while ((n->begin() != n->end()) && ((*n->begin())->signon < TIME - 259200)) // 3 days
+                       {
+                               WhoWasGroup *a = *(n->begin());
+                               delete a;
+                               n->erase(n->begin());
+                       }
+               }
+       }
 }
 
 /* add a client connection to the sockets list */
@@ -572,12 +636,6 @@ void AddClient(int socket, int port, bool iscached, in_addr ip4)
         clientlist[tempnick]->sendqmax = class_sqmax;
         clientlist[tempnick]->recvqmax = class_rqmax;
 
-        ucrec a;
-        a.channel = NULL;
-        a.uc_modes = 0;
-        for (int i = 0; i < MAXCHANS; i++)
-                clientlist[tempnick]->chans.push_back(a);
-
        fd_ref_table[socket] = clientlist[tempnick];
        local_users.push_back(clientlist[tempnick]);
 
@@ -798,4 +856,3 @@ void force_nickchange(userrec* user,const char* newnick)
                 }
         }
 }
-