X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspircd.cpp;h=527eb95b08bf865429908033b93124b2281e9ef3;hb=93b0661ddaebc82df76e0268ebe0ab0c17f7cbc7;hp=c0391b6793ec0eb4a369e26af4f8db1f43ea2cbe;hpb=78f26492a65b438f5b87f1574ed7785fd77ae2f0;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspircd.cpp b/src/inspircd.cpp index c0391b679..527eb95b0 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -54,6 +54,14 @@ InspIRCd* SI = NULL; int* mysig = NULL; +/** Seperate from the other casemap tables so that code *can* still exclusively rely on RFC casemapping + * if it must. + * + * This is provided as a pointer so that modules can change it to their custom mapping tables, + * e.g. for national character support. + */ +unsigned const char *national_case_insensitive_map = rfc_case_insensitive_map; + /* Moved from exitcodes.h -- due to duplicate symbols -- Burlex * XXX this is a bit ugly. -- w00t @@ -82,6 +90,15 @@ const char* ExitCodes[] = "CreateEvent failed" /* 19 */ }; +template void DeleteZero(T* n) +{ + if (n != NULL) + { + delete n; + n = NULL; + } +} + void InspIRCd::Cleanup() { if (Config) @@ -124,102 +141,27 @@ void InspIRCd::Cleanup() for(servernamelist::iterator itr = servernames.begin(); itr != servernames.end(); ++itr) delete (*itr); - /* Delete objects dynamically allocated in constructor - * (destructor would be more appropriate, but we're likely exiting) - */ - - // Must be deleted before modes as it decrements modelines - if (this->Users) - { - delete this->Users; - this->Users = 0; - } - - if (this->Modes) - { - delete this->Modes; - this->Modes = 0; - } - - if (this->XLines) - { - delete this->XLines; - this->XLines = 0; - } - - if (this->Parser) - { - delete this->Parser; - this->Parser = 0; - - if (this->stats) - { - delete this->stats; - this->stats = 0; - } - - if (this->Modules) - { - delete this->Modules; - this->Modules = 0; - } - - if (this->BanCache) - delete this->BanCache; - this->BanCache = 0; - } - - if (this->SNO) - { - delete this->SNO; - this->SNO = 0; - } - - if (this->Config) - { - delete this->Config; - this->Config = 0; - } - - if (this->Res) - { - delete this->Res; - this->Res = 0; - } - - if (this->chanlist) - { - delete chanlist; - chanlist = 0; - } - - if (this->PI) - { - delete this->PI; - this->PI = 0; - } - - if (this->Threads) - { - delete this->Threads; - this->Threads = 0; - } - - /* Needs to be deleted after Res, DNS has a timer */ - if (this->Timers) - { - delete this->Timers; - this->Timers = 0; - } - + /* Delete objects dynamically allocated in constructor (destructor would be more appropriate, but we're likely exiting) */ + /* Must be deleted before modes as it decrements modelines */ + DeleteZero(this->Users); + DeleteZero(this->Modes); + DeleteZero(this->XLines); + DeleteZero(this->Parser); + DeleteZero(this->stats); + DeleteZero(this->Modules); + DeleteZero(this->BanCache); + DeleteZero(this->SNO); + DeleteZero(this->Config); + DeleteZero(this->Res); + DeleteZero(this->chanlist); + DeleteZero(this->PI); + DeleteZero(this->Threads); + DeleteZero(this->Timers); /* Close logging */ this->Logs->CloseLogs(); + DeleteZero(this->Logs); - if (this->Logs) - { - delete this->Logs; - this->Logs = 0; - } + delete RehashFinishMutex; } void InspIRCd::Restart(const std::string &reason) @@ -579,9 +521,19 @@ InspIRCd::InspIRCd(int argc, char** argv) if (!ServerConfig::FileExists(this->ConfigFileName)) { - printf("ERROR: Cannot open config file: %s\nExiting...\n", this->ConfigFileName); - this->Logs->Log("STARTUP",DEFAULT,"Unable to open config file %s", this->ConfigFileName); - Exit(EXIT_STATUS_CONFIG); +#ifdef WIN32 + /* Windows can (and defaults to) hide file extensions, so let's play a bit nice for windows users. */ + if (ServerConfig::FileExists(this->ConfigFileName + ".txt")) + { + strlcat(this->ConfigFileName, ".txt", MAXBUF); + } + else +#endif + { + printf("ERROR: Cannot open config file: %s\nExiting...\n", this->ConfigFileName); + this->Logs->Log("STARTUP",DEFAULT,"Unable to open config file %s", this->ConfigFileName); + Exit(EXIT_STATUS_CONFIG); + } } printf_c("\033[1;32mInspire Internet Relay Chat Server, compiled %s at %s\n",__DATE__,__TIME__); @@ -631,6 +583,11 @@ InspIRCd::InspIRCd(int argc, char** argv) ConfigThread->Run(); delete ConfigThread; this->ConfigThread = NULL; + /* Switch over logfiles */ + Logs->OpenFileLogs(); + + /** Note: This is safe, the method checks for user == NULL */ + this->Parser->SetupCommandTable(); this->Res = new DNS(this); @@ -803,6 +760,8 @@ int InspIRCd::Run() Exit(0); } + RehashFinishMutex = Mutexes->CreateMutex(); + while (true) { #ifndef WIN32 @@ -814,21 +773,22 @@ int InspIRCd::Run() #endif /* Check if there is a config thread which has finished executing but has not yet been freed */ + RehashFinishMutex->Lock(); if (this->ConfigThread && this->ConfigThread->GetExitFlag()) { /* Rehash has completed */ - this->Logs->Log("CONFIG",DEBUG,"Detected ConfigThread exiting, tidying up..."); - /* IMPORTANT: This delete may hang if you fuck up your thread syncronization. - * It will hang waiting for the ConfigThread to 'join' to avoid race conditons, - * until the other thread is completed. - */ - delete ConfigThread; - ConfigThread = NULL; + /* Switch over logfiles */ + Logs->CloseLogs(); + Logs->OpenFileLogs(); + + this->Logs->Log("CONFIG",DEBUG,"Detected ConfigThread exiting, tidying up..."); /* These are currently not known to be threadsafe, so they are executed outside * of the thread. It would be pretty simple to move them to the thread Run method - * once they are known threadsafe with all the correct mutexes in place. + * once they are known threadsafe with all the correct mutexes in place. This might + * not be worth the effort however as these functions execute relatively quickly + * and would not benefit from being within the config read thread. * * XXX: The order of these is IMPORTANT, do not reorder them without testing * thoroughly!!! @@ -841,7 +801,15 @@ int InspIRCd::Run() User* user = !Config->RehashUserUID.empty() ? FindNick(Config->RehashUserUID) : NULL; FOREACH_MOD_I(this, I_OnRehash, OnRehash(user, Config->RehashParameter)); this->BuildISupport(); + + /* IMPORTANT: This delete may hang if you fuck up your thread syncronization. + * It will hang waiting for the ConfigThread to 'join' to avoid race conditons, + * until the other thread is completed. + */ + delete ConfigThread; + ConfigThread = NULL; } + RehashFinishMutex->Unlock(); /* time() seems to be a pretty expensive syscall, so avoid calling it too much. * Once per loop iteration is pleanty.