/* $Install: src/inspircd $(BINPATH) */
+
#include "inspircd.h"
#include <signal.h>
int* mysig = NULL;
-/* Burlex: Moved from exitcodes.h -- due to duplicate symbols */
+/* Moved from exitcodes.h -- due to duplicate symbols -- Burlex
+ * XXX this is a bit ugly. -- w00t
+ */
const char* ExitCodes[] =
{
"No error", /* 0 */
/* We do this more than once, so that any service providers get a
* chance to be unhooked by the modules using them, but then get
* a chance to be removed themsleves.
+ *
+ * XXX there may be a better way to do this with 1.2
*/
for (int tries = 0; tries < 3; tries++)
{
rlimit rl;
if (getrlimit(RLIMIT_CORE, &rl) == -1)
{
- this->Log(DEFAULT,"Failed to getrlimit()!");
+ this->Logs->Log("STARTUP",DEFAULT,"Failed to getrlimit()!");
return false;
}
else
{
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_CORE, &rl) == -1)
- this->Log(DEFAULT,"setrlimit() failed, cannot increase coredump size.");
+ this->Logs->Log("STARTUP",DEFAULT,"setrlimit() failed, cannot increase coredump size.");
}
return true;
else
{
printf("Failed to write PID-file '%s', exiting.\n",fname.c_str());
- this->Log(DEFAULT,"Failed to write PID-file '%s', exiting.",fname.c_str());
+ this->Logs->Log("STARTUP",DEFAULT,"Failed to write PID-file '%s', exiting.",fname.c_str());
Exit(EXIT_STATUS_PID);
}
}
SE = SEF->Create(this);
delete SEF;
+ ThreadEngineFactory* tef = new ThreadEngineFactory();
+ this->Threads = tef->Create(this);
+ delete tef;
+
+ /* Default implementation does nothing */
+ this->PI = new ProtocolInterface(this);
+
this->s_signal = 0;
// Create base manager classes early, so nothing breaks
if (!ServerConfig::FileExists(this->ConfigFileName))
{
printf("ERROR: Cannot open config file: %s\nExiting...\n", this->ConfigFileName);
- this->Log(DEFAULT,"Unable to open config file %s", this->ConfigFileName);
+ this->Logs->Log("STARTUP",DEFAULT,"Unable to open config file %s", this->ConfigFileName);
Exit(EXIT_STATUS_CONFIG);
}
this->Modes = new ModeParser(this);
- /* set up fake client (uid is incorrect at this point,
- * until after config is read. we set up the user again
- * at that point
- */
- this->FakeClient = new User(this);
- this->FakeClient->SetFd(FD_MAGIC_NUMBER);
-
if (!do_root)
this->CheckRoot();
else
SE->RecoverFromFork();
- /* Read config, pass 0. At the end if this pass,
- * the Config->IncludeFiles is populated, we call
- * Config->StartDownloads to initialize the downlaods of all
- * these files.
+ /* During startup we don't actually initialize this
+ * in the thread engine.
*/
- Config->Read(true, NULL, 0);
- Config->DoDownloads();
- /* We have all the files we can get, initiate pass 1 */
- Config->Read(true, NULL, 1);
+ this->ConfigThread = new ConfigReaderThread(this, true, NULL);
+ ConfigThread->Run();
+ delete ConfigThread;
+ this->ConfigThread = NULL;
+
+ this->Res = new DNS(this);
this->AddServerName(Config->ServerName);
* For an explanation as to exactly how this works, and why it works this way, see GetUID().
* -- w00t
*/
- if (*Config->sid)
- {
- }
- else
+ if (!*Config->sid)
{
// Generate one
size_t sid = 0;
Config->sid[2] = (char)(sid % 10 + 48);
}
- this->InitialiseUID();
-
/* set up fake client again this time with the correct uid */
- delete FakeClient;
- this->FakeClient = new User(this);
+ this->FakeClient = new User(this, "#INVALID");
this->FakeClient->SetFd(FD_MAGIC_NUMBER);
// Get XLine to do it's thing.
this->XLines->CheckELines();
this->XLines->ApplyLines();
-
CheckDie();
int bounditems = BindPorts(true, found_ports, pl);
printf("\n");
- /*this->Modules->LoadAll();*/
+ this->Modules->LoadAll();
/* Just in case no modules were loaded - fix for bug #101 */
this->BuildISupport();
InitializeDisabledCommands(Config->DisabledCommands, this);
- if ((Config->ports.size() == 0) && (found_ports > 0))
+ /*if ((Config->ports.size() == 0) && (found_ports > 0))
{
printf("\nERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
Logs->Log("STARTUP", DEFAULT,"ERROR: I couldn't bind any ports! Something else is bound to those ports!");
Exit(EXIT_STATUS_BIND);
- }
+ }*/
if (Config->ports.size() != (unsigned int)found_ports)
{
printf("%d.\tIP: %s\tPort: %lu\n", j, i->first.empty() ? "<all>" : i->first.c_str(), (unsigned long)i->second);
}
}
+
+ printf("\nInspIRCd is now running as '%s'[%s] with %d max open sockets\n", Config->ServerName,Config->GetSID().c_str(), SE->GetMaxFds());
+
#ifndef WINDOWS
if (!Config->nofork)
{
}
#endif
- printf("\nInspIRCd is now running as '%s'[%s]\n", Config->ServerName,Config->GetSID().c_str());
- Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s]", Config->ServerName,Config->GetSID().c_str());
+ Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName,Config->GetSID().c_str(), SE->GetMaxFds());
this->WritePID(Config->PID);
}
-/* moved to a function, as UID generation can call this also */
-void InspIRCd::InitialiseUID()
-{
- int i = 3;
-
- current_uid[0] = Config->sid[0];
- current_uid[1] = Config->sid[1];
- current_uid[2] = Config->sid[2];
-
- /* Initialise UID */
- for(i = 3; i < UUID_LENGTH - 1; i++)
- current_uid[i] = 'A';
-
- current_uid[UUID_LENGTH] = '\0';
-}
-
int InspIRCd::Run()
{
/* See if we're supposed to be running the test suite rather than entering the mainloop */
static char window_title[100];
#endif
+ /* Check if there is a config thread which has finished executing but has not yet been freed */
+ 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;
+
+ /* 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.
+ *
+ * XXX: The order of these is IMPORTANT, do not reorder them without testing
+ * thoroughly!!!
+ */
+ this->XLines->CheckELines();
+ this->XLines->ApplyLines();
+ this->Res->Rehash();
+ this->ResetMaxBans();
+ InitializeDisabledCommands(Config->DisabledCommands, this);
+ FOREACH_MOD_I(this, I_OnRehash, OnRehash(Config->RehashUser, Config->RehashParameter));
+ this->BuildISupport();
+ }
+
/* time() seems to be a pretty expensive syscall, so avoid calling it too much.
* Once per loop iteration is pleanty.
*/
{
if (TIME < OLDTIME)
{
- SNO->WriteToSnoMask('A', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %d secs.",abs(OLDTIME-TIME));
+ SNO->WriteToSnoMask('A', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME);
}
if ((TIME % 3600) == 0)
{
for (std::map<BufferedSocket*,BufferedSocket*>::iterator x = SocketCull.begin(); x != SocketCull.end(); ++x)
{
- Log(DEBUG,"Cull socket");
+ this->Logs->Log("MISC",DEBUG,"Cull socket");
SE->DelFd(x->second);
x->second->Close();
delete x->second;
{
for (EventHandlerIter i = Modules->EventHandlers[I_OnCheckReady].begin(); i != Modules->EventHandlers[I_OnCheckReady].end(); ++i)
{
- int res = (*i)->OnCheckReady(user);
- if (!res)
+ if (!(*i)->OnCheckReady(user))
return false;
}
-
return true;
}