From 4927edc5fb5be69ff745044f087b8e3f1fc539d8 Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 2 Mar 2006 17:19:49 +0000 Subject: *UNTESTED* speeding up HasPermission by factor of hundreds, avoid using EnumConf and ConfValue outside of rehash *AT ALL* git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3430 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/users.h | 1 + src/inspircd_io.cpp | 1 + src/users.cpp | 74 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/include/users.h b/include/users.h index 3b1ff5003..631704f99 100644 --- a/include/users.h +++ b/include/users.h @@ -363,5 +363,6 @@ void AddClient(int socket, int port, bool iscached, in_addr ip4); void FullConnectUser(userrec* user, CullList* Goners); userrec* ReHashNick(char* Old, char* New); void force_nickchange(userrec* user,const char* newnick); +void ReadClassesAndTypes(); #endif diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp index 5488b025f..9195399a4 100644 --- a/src/inspircd_io.cpp +++ b/src/inspircd_io.cpp @@ -417,6 +417,7 @@ void ServerConfig::Read(bool bail, userrec* user) Config->ulines.push_back(ServName); } } + ReadClassesAndTypes(); log(DEFAULT,"Reading K lines,Q lines and Z lines from config..."); read_xline_defaults(); log(DEFAULT,"Applying K lines, Q lines and Z lines..."); diff --git a/src/users.cpp b/src/users.cpp index 50589dd6e..2d53ea374 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -54,6 +54,43 @@ extern std::vector local_users; std::vector all_opers; +typedef std::map opertype_t; +typedef opertype_t operclass_t; + +opertype_t opertypes; +operclass_t operclass; + +void ReadClassesAndTypes() +{ + char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF]; + for (opertype_t::iterator n = opertypes.begin(); n != opertypes.end(); n++) + { + if (n->second) + delete[] n->second; + } + for (operclass_t::iterator n = operclass.begin(); n != operclass.end(); n++) + { + if (n->second) + delete[] n->second; + } + opertypes.clear(); + operclass.clear(); + for (int j =0; j < Config->ConfValueEnum("type",&Config->config_f); j++) + { + Config->ConfValue("type","name",j,TypeName,&Config->config_f); + Config->ConfValue("type","classes",j,Classes,&Config->config_f); + opertypes[TypeName] = sstrdup(Classes); + log(DEBUG,"Read oper TYPE '%s' with classes '%s'",TypeName,Classes); + } + for (int k =0; k < Config->ConfValueEnum("class",&Config->config_f); k++) + { + Config->ConfValue("class","name",k,ClassName,&Config->config_f); + Config->ConfValue("class","commands",k,CommandList,&Config->config_f); + operclass[ClassName] = sstrdup(CommandList); + log(DEBUG,"Read oper CLASS '%s' with commands '%s'",ClassName,CommandList); + } +} + template inline string ConvToStr(const T &in) { stringstream tmp; @@ -196,10 +233,11 @@ void userrec::RemoveInvite(irc::string &channel) bool userrec::HasPermission(std::string &command) { - char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF]; + char* CommandList; char* mycmd; char* savept; char* savept2; + char* Classes; // users on remote servers can completely bypass // all permissions based checks. @@ -211,34 +249,28 @@ 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)) + Classes = 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 = 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); - } + return true; } + mycmd = strtok_r(NULL," ",&savept2); } - myclass = strtok_r(NULL," ",&savept); } + myclass = strtok_r(NULL," ",&savept); } } } -- cgit v1.2.3