X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhelperfuncs.cpp;h=567806efcef407ded6176ab17e3514aac5ec8af7;hb=adb26a4e882d317de4e4135f414b7002cafe07a4;hp=a6df520c5d2d10fddb7a3306fd0ad35e9052d27e;hpb=ebdaf368e137fc933e648ee88a08a4f83e796f87;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index a6df520c5..567806efc 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -22,8 +22,6 @@ */ -/* $Core */ - #ifdef _WIN32 #define _CRT_RAND_S #include @@ -34,23 +32,6 @@ #include "exitcodes.h" #include -std::string InspIRCd::GetServerDescription(const std::string& servername) -{ - std::string description; - - FOREACH_MOD(I_OnGetServerDescription,OnGetServerDescription(servername,description)); - - if (!description.empty()) - { - return description; - } - else - { - // not a remote server that can be found, it must be me. - return Config->ServerDesc; - } -} - /* Find a user record by nickname and return a pointer to it */ User* InspIRCd::FindNick(const std::string &nick) { @@ -66,19 +47,6 @@ User* InspIRCd::FindNick(const std::string &nick) return iter->second; } -User* InspIRCd::FindNick(const char* nick) -{ - if (isdigit(*nick)) - return FindUUID(nick); - - user_hash::iterator iter = this->Users->clientlist->find(nick); - - if (iter == this->Users->clientlist->end()) - return NULL; - - return iter->second; -} - User* InspIRCd::FindNickOnly(const std::string &nick) { user_hash::iterator iter = this->Users->clientlist->find(nick); @@ -89,48 +57,22 @@ User* InspIRCd::FindNickOnly(const std::string &nick) return iter->second; } -User* InspIRCd::FindNickOnly(const char* nick) -{ - user_hash::iterator iter = this->Users->clientlist->find(nick); - - if (iter == this->Users->clientlist->end()) - return NULL; - - return iter->second; -} - User *InspIRCd::FindUUID(const std::string &uid) { - return FindUUID(uid.c_str()); -} + user_hash::iterator finduuid = this->Users->uuidlist.find(uid); -User *InspIRCd::FindUUID(const char *uid) -{ - user_hash::iterator finduuid = this->Users->uuidlist->find(uid); - - if (finduuid == this->Users->uuidlist->end()) + if (finduuid == this->Users->uuidlist.end()) return NULL; return finduuid->second; } - /* find a channel record by channel name and return a pointer to it */ -Channel* InspIRCd::FindChan(const char* chan) -{ - chan_hash::iterator iter = chanlist->find(chan); - - if (iter == chanlist->end()) - /* Couldn't find it */ - return NULL; - - return iter->second; -} Channel* InspIRCd::FindChan(const std::string &chan) { - chan_hash::iterator iter = chanlist->find(chan); + chan_hash::iterator iter = chanlist.find(chan); - if (iter == chanlist->end()) + if (iter == chanlist.end()) /* Couldn't find it */ return NULL; @@ -140,13 +82,13 @@ Channel* InspIRCd::FindChan(const std::string &chan) /* Send an error notice to all users, registered or not */ void InspIRCd::SendError(const std::string &s) { - for (std::vector::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++) + for (LocalUserList::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++) { User* u = *i; if (u->registered == REG_ALL) { - u->WriteServ("NOTICE %s :%s",u->nick.c_str(),s.c_str()); - } + u->WriteNotice(s); + } else { /* Unregistered connections receive ERROR, not a NOTICE */ @@ -155,12 +97,6 @@ void InspIRCd::SendError(const std::string &s) } } -/* return channel count */ -long InspIRCd::ChannelCount() -{ - return chanlist->size(); -} - bool InspIRCd::IsValidMask(const std::string &mask) { const char* dest = mask.c_str(); @@ -196,48 +132,120 @@ bool InspIRCd::IsValidMask(const std::string &mask) return true; } -/* true for valid channel name, false else */ -bool IsChannelHandler::Call(const char *chname, size_t max) +void InspIRCd::StripColor(std::string &sentence) { - const char *c = chname + 1; + /* refactor this completely due to SQUIT bug since the old code would strip last char and replace with \0 --peavey */ + int seq = 0; - /* check for no name - don't check for !*chname, as if it is empty, it won't be '#'! */ - if (!chname || *chname != '#') + for (std::string::iterator i = sentence.begin(); i != sentence.end();) { - return false; + if (*i == 3) + seq = 1; + else if (seq && (( ((*i >= '0') && (*i <= '9')) || (*i == ',') ) )) + { + seq++; + if ( (seq <= 4) && (*i == ',') ) + seq = 1; + else if (seq > 3) + seq = 0; + } + else + seq = 0; + + if (seq || ((*i == 2) || (*i == 15) || (*i == 22) || (*i == 21) || (*i == 31))) + i = sentence.erase(i); + else + ++i; } +} - while (*c) +void InspIRCd::ProcessColors(file_cache& input) +{ + /* + * Replace all color codes from the special[] array to actual + * color code chars using C++ style escape sequences. You + * can append other chars to replace if you like -- Justasic + */ + static struct special_chars { - switch (*c) + std::string character; + std::string replace; + special_chars(const std::string &c, const std::string &r) : character(c), replace(r) { } + } + + special[] = { + special_chars("\\002", "\002"), // Bold + special_chars("\\037", "\037"), // underline + special_chars("\\003", "\003"), // Color + special_chars("\\017", "\017"), // Stop colors + special_chars("\\u", "\037"), // Alias for underline + special_chars("\\b", "\002"), // Alias for Bold + special_chars("\\x", "\017"), // Alias for stop + special_chars("\\c", "\003"), // Alias for color + special_chars("", "") + }; + + for(file_cache::iterator it = input.begin(), it_end = input.end(); it != it_end; it++) + { + std::string ret = *it; + for(int i = 0; special[i].character.empty() == false; ++i) { - case ' ': - case ',': - case 7: - return false; + std::string::size_type pos = ret.find(special[i].character); + if(pos == std::string::npos) // Couldn't find the character, skip this line + continue; + + if((pos > 0) && (ret[pos-1] == '\\') && (ret[pos] == '\\')) + continue; // Skip double slashes. + + // Replace all our characters in the array + while(pos != std::string::npos) + { + ret = ret.substr(0, pos) + special[i].replace + ret.substr(pos + special[i].character.size()); + pos = ret.find(special[i].character, pos + special[i].replace.size()); + } } - c++; + // Replace double slashes with a single slash before we return + std::string::size_type pos = ret.find("\\\\"); + while(pos != std::string::npos) + { + ret = ret.substr(0, pos) + "\\" + ret.substr(pos + 2); + pos = ret.find("\\\\", pos + 1); + } + *it = ret; } +} + +/* true for valid channel name, false else */ +bool IsChannelHandler::Call(const std::string& chname) +{ + if (chname.empty() || chname.length() > ServerInstance->Config->Limits.ChanMax) + return false; + + if (chname[0] != '#') + return false; - size_t len = c - chname; - /* too long a name - note funky pointer arithmetic here. */ - if (len > max) + for (std::string::const_iterator i = chname.begin()+1; i != chname.end(); ++i) { - return false; + switch (*i) + { + case ' ': + case ',': + case 7: + return false; + } } return true; } /* true for valid nickname, false else */ -bool IsNickHandler::Call(const char* n, size_t max) +bool IsNickHandler::Call(const std::string& n) { - if (!n || !*n) + if (n.empty() || n.length() > ServerInstance->Config->Limits.NickMax) return false; - unsigned int p = 0; - for (const char* i = n; *i; i++, p++) + for (std::string::const_iterator i = n.begin(); i != n.end(); ++i) { if ((*i >= 'A') && (*i <= '}')) { @@ -245,7 +253,7 @@ bool IsNickHandler::Call(const char* n, size_t max) continue; } - if ((((*i >= '0') && (*i <= '9')) || (*i == '-')) && (i > n)) + if ((((*i >= '0') && (*i <= '9')) || (*i == '-')) && (i != n.begin())) { /* "0"-"9", "-" can occur anywhere BUT the first char of a nickname */ continue; @@ -255,17 +263,16 @@ bool IsNickHandler::Call(const char* n, size_t max) return false; } - /* too long? or not -- pointer arithmetic rocks */ - return (p < max); + return true; } /* return true for good ident, false else */ -bool IsIdentHandler::Call(const char* n) +bool IsIdentHandler::Call(const std::string& n) { - if (!n || !*n) + if (n.empty()) return false; - for (const char* i = n; *i; i++) + for (std::string::const_iterator i = n.begin(); i != n.end(); ++i) { if ((*i >= 'A') && (*i <= '}')) { @@ -283,7 +290,7 @@ bool IsIdentHandler::Call(const char* n) return true; } -bool IsSIDHandler::Call(const std::string &str) +bool InspIRCd::IsSID(const std::string &str) { /* Returns true if the string given is exactly 3 characters long, * starts with a digit, and the other two characters are A-Z or digits @@ -293,35 +300,13 @@ bool IsSIDHandler::Call(const std::string &str) ((str[2] >= 'A' && str[2] <= 'Z') || isdigit(str[2]))); } -/* open the proper logfile */ -bool InspIRCd::OpenLog(char**, int) -{ - if (!Config->cmdline.writelog) return true; // Skip opening default log if -nolog - - if (Config->cmdline.startup_log.empty()) - Config->cmdline.startup_log = LOG_PATH "/startup.log"; - FILE* startup = fopen(Config->cmdline.startup_log.c_str(), "a+"); - - if (!startup) - { - return false; - } - - FileWriter* fw = new FileWriter(startup); - FileLogStream *f = new FileLogStream((Config->cmdline.forcedebug ? DEBUG : DEFAULT), fw); - - this->Logs->AddLogType("*", f, true); - - return true; -} - void InspIRCd::CheckRoot() { #ifndef _WIN32 if (geteuid() == 0) { std::cout << "ERROR: You are running an irc server as root! DO NOT DO THIS!" << std::endl << std::endl; - this->Logs->Log("STARTUP",DEFAULT,"Can't start as root"); + this->Logs->Log("STARTUP", LOG_DEFAULT, "Can't start as root"); Exit(EXIT_STATUS_ROOT); } #endif @@ -335,24 +320,20 @@ void InspIRCd::SendWhoisLine(User* user, User* dest, int numeric, const std::str FIRST_MOD_RESULT(OnWhoisLine, MOD_RESULT, (user, dest, numeric, copy_text)); if (MOD_RESULT != MOD_RES_DENY) - user->WriteServ("%d %s", numeric, copy_text.c_str()); + user->WriteNumeric(numeric, copy_text); } void InspIRCd::SendWhoisLine(User* user, User* dest, int numeric, const char* format, ...) { - char textbuffer[MAXBUF]; - va_list argsPtr; - va_start (argsPtr, format); - vsnprintf(textbuffer, MAXBUF, format, argsPtr); - va_end(argsPtr); - - this->SendWhoisLine(user, dest, numeric, std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, format, format) + this->SendWhoisLine(user, dest, numeric, textbuffer); } /** Refactored by Brain, Jun 2009. Much faster with some clever O(1) array * lookups and pointer maths. */ -long InspIRCd::Duration(const std::string &str) +unsigned long InspIRCd::Duration(const std::string &str) { unsigned char multiplier = 0; long total = 0; @@ -392,46 +373,58 @@ long InspIRCd::Duration(const std::string &str) return total + subtotal; } -bool InspIRCd::ULine(const std::string& sserver) +const char* InspIRCd::Format(va_list &vaList, const char* formatString) { - if (sserver.empty()) - return true; + static std::vector formatBuffer(1024); - return (Config->ulines.find(sserver.c_str()) != Config->ulines.end()); -} + while (true) + { + va_list dst; + va_copy(dst, vaList); -bool InspIRCd::SilentULine(const std::string& sserver) -{ - std::map::iterator n = Config->ulines.find(sserver.c_str()); - if (n != Config->ulines.end()) - return n->second; - else - return false; + int vsnret = vsnprintf(&formatBuffer[0], formatBuffer.size(), formatString, dst); + va_end(dst); + + if (vsnret > 0 && static_cast(vsnret) < formatBuffer.size()) + { + break; + } + + formatBuffer.resize(formatBuffer.size() * 2); + } + + return &formatBuffer[0]; } -std::string InspIRCd::TimeString(time_t curtime) +const char* InspIRCd::Format(const char* formatString, ...) { - return std::string(ctime(&curtime),24); + const char* ret; + VAFORMAT(ret, formatString, formatString); + return ret; } -// You should only pass a single character to this. -void InspIRCd::AddExtBanChar(char c) +std::string InspIRCd::TimeString(time_t curtime) { - std::string &tok = Config->data005; - std::string::size_type ebpos = tok.find(" EXTBAN=,"); +#ifdef _WIN32 + if (curtime < 0) + curtime = 0; +#endif - if (ebpos == std::string::npos) - { - tok.append(" EXTBAN=,"); - tok.push_back(c); - } - else + struct tm* timeinfo = localtime(&curtime); + if (!timeinfo) { - ebpos += 9; - while (isalpha(tok[ebpos]) && tok[ebpos] < c) - ebpos++; - tok.insert(ebpos, 1, c); + curtime = 0; + timeinfo = localtime(&curtime); } + + // If the calculated year exceeds four digits or is less than the year 1000, + // the behavior of asctime() is undefined + if (timeinfo->tm_year + 1900 > 9999) + timeinfo->tm_year = 9999 - 1900; + else if (timeinfo->tm_year + 1900 < 1000) + timeinfo->tm_year = 0; + + return std::string(asctime(timeinfo),24); } std::string InspIRCd::GenRandomStr(int length, bool printable) @@ -489,7 +482,7 @@ ModResult OnCheckExemptionHandler::Call(User* user, Channel* chan, const std::st minmode = current[pos+1]; } - ModeHandler* mh = ServerInstance->Modes->FindMode(minmode, MODETYPE_CHANNEL); + PrefixMode* mh = ServerInstance->Modes->FindPrefixMode(minmode); if (mh && mypfx >= mh->GetPrefixRank()) return MOD_RES_ALLOW; if (mh || minmode == '*')