* ---------------------------------------------------
*/
-/* $Install: src/inspircd $(BINPATH) */
+/* $Core */
#include "inspircd.h"
+#include "inspircd_version.h"
#include <signal.h>
#ifndef WIN32
"CreateEvent failed" /* 19 */
};
-template<typename T> static void DeleteZero(T* n)
+template<typename T> static void DeleteZero(T*&n)
{
if (n != NULL)
{
{
if (Config)
{
- for (unsigned int i = 0; i < Config->ports.size(); i++)
+ for (unsigned int i = 0; i < ports.size(); i++)
{
/* This calls the constructor and closes the listening socket */
- delete Config->ports[i];
+ delete ports[i];
}
- Config->ports.clear();
+ ports.clear();
}
/* Close all client sockets, or the new process inherits them */
this->Modules->Unload(k->c_str());
}
}
- /* Remove core commands */
- Parser->RemoveCommands("<core>");
/* Cleanup Server Names */
for(servernamelist::iterator itr = servernames.begin(); itr != servernames.end(); ++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 */
+ DeleteZero(this->FakeClient);
DeleteZero(this->Users);
DeleteZero(this->Modes);
DeleteZero(this->XLines);
DeleteZero(this->PI);
DeleteZero(this->Threads);
DeleteZero(this->Timers);
+ DeleteZero(this->SE);
/* Close logging */
this->Logs->CloseLogs();
DeleteZero(this->Logs);
}
}
-InspIRCd::InspIRCd(int argc, char** argv)
- : GlobalCulls(this),
-
+InspIRCd::InspIRCd(int argc, char** argv) :
/* Functor initialisation. Note that the ordering here is very important.
*
* THIS MUST MATCH ORDER OF DECLARATION OF THE HandleWhateverFunc classes
HandleProcessUser(this),
HandleIsNick(this),
HandleIsIdent(this),
- HandleFindDescriptor(this),
HandleFloodQuitUser(this),
HandleIsChannel(this),
HandleIsSID(this),
Rehash(&HandleRehash),
IsNick(&HandleIsNick),
IsIdent(&HandleIsIdent),
- FindDescriptor(&HandleFindDescriptor),
FloodQuitUser(&HandleFloodQuitUser)
{
// Avoid erroneous frees on early exit
WindowsIPC = 0;
#endif
- int found_ports = 0;
FailedPortList pl;
int do_version = 0, do_nofork = 0, do_debug = 0,
do_nolog = 0, do_root = 0, do_testsuite = 0; /* flag variables */
- char c = 0;
+ int c = 0;
// Initialize so that if we exit before proper initialization they're not deleted
this->Logs = 0;
this->XLines = 0;
this->Modes = 0;
this->Res = 0;
+ this->ConfigThread = NULL;
// Initialise TIME
this->TIME = time(NULL);
- memset(&server, 0, sizeof(server));
- memset(&client, 0, sizeof(client));
-
// This must be created first, so other parts of Insp can use it while starting up
this->Logs = new LogManager(this);
{ 0, 0, 0, 0 }
};
- while ((c = getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
+ int index;
+ while ((c = getopt_long_only(argc, argv, ":f:", longopts, &index)) != -1)
{
switch (c)
{
case 0:
/* getopt_long_only() set an int variable, just keep going */
break;
+ case '?':
+ /* Unknown parameter */
default:
- /* Unknown parameter! DANGER, INTRUDER.... err.... yeah. */
- printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n\
- [--runasroot] [--version] [--config <config>] [--testsuite]\n", argv[0]);
+ /* Fall through to handle other weird values too */
+ printf("Unknown parameter '%s'\n", argv[optind-1]);
+ printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n%*s[--runasroot] [--version] [--config <config>] [--testsuite]\n", argv[0], static_cast<int>(8+strlen(argv[0])), " ");
Exit(EXIT_STATUS_ARGV);
break;
}
WSAStartup(MAKEWORD(2,0), &wsadata);
ChangeWindowsSpecificPointers(this);
#endif
- strlcpy(Config->MyExecutable,argv[0],MAXBUF);
+ Config->MyExecutable = argv[0];
/* Set the finished argument values */
Config->nofork = do_nofork;
printf_c("\t\033[1;32mpeavey, aquanight, psychon, dz, danieldg\033[0m\n\n");
printf_c("Others:\t\t\t\033[1;32mSee /INFO Output\033[0m\n");
- Config->ClearStack();
-
this->Modes = new ModeParser(this);
if (!do_root)
/* During startup we don't actually initialize this
* in the thread engine.
*/
- this->ConfigThread = new ConfigReaderThread(this, true, "");
- ConfigThread->Run();
- delete ConfigThread;
- this->ConfigThread = NULL;
- /* Switch over logfiles */
+ this->Config->Read();
+ this->Config->Apply(NULL, "");
Logs->OpenFileLogs();
- /** Note: This is safe, the method checks for user == NULL */
- this->Parser->SetupCommandTable();
-
this->Res = new DNS(this);
this->AddServerName(Config->ServerName);
}
/* set up fake client again this time with the correct uid */
- this->FakeClient = new User(this, "#INVALID");
- this->FakeClient->SetFd(FD_MAGIC_NUMBER);
+ this->FakeClient = new FakeUser(this, "!");
+ this->FakeClient->SetFakeServer(Config->ServerName);
// Get XLine to do it's thing.
this->XLines->CheckELines();
this->XLines->ApplyLines();
- CheckDie();
- int bounditems = BindPorts(true, found_ports, pl);
+ int bounditems = BindPorts(pl);
printf("\n");
/* Just in case no modules were loaded - fix for bug #101 */
this->BuildISupport();
- InitializeDisabledCommands(Config->DisabledCommands, this);
+ Config->ApplyDisabledCommands(Config->DisabledCommands);
- if (Config->ports.size() != (unsigned int)found_ports)
+ if (!pl.empty())
{
- printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports);
+ printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n",
+ bounditems, bounditems + (int)pl.size());
printf("The following port(s) failed to bind:\n");
printf("Hint: Try using a public IP instead of blank or *\n\n");
int j = 1;
#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())
+ if (this->ConfigThread && this->ConfigThread->IsDone())
{
/* Rehash has completed */
-
- /* 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. 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!!!
- */
- this->XLines->CheckELines();
- this->XLines->ApplyLines();
- this->Res->Rehash();
- this->ResetMaxBans();
- InitializeDisabledCommands(Config->DisabledCommands, this);
- 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.
- */
+ this->ConfigThread->Finish();
+
+ ConfigThread->join();
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.
*/
bool InspIRCd::AllModulesReportReady(User* user)
{
- for (EventHandlerIter i = Modules->EventHandlers[I_OnCheckReady].begin(); i != Modules->EventHandlers[I_OnCheckReady].end(); ++i)
- {
- if (!(*i)->OnCheckReady(user))
- return false;
- }
- return true;
+ ModResult res;
+ FIRST_MOD_RESULT(this, OnCheckReady, res, (user));
+ return (res == MOD_RES_PASSTHRU);
}
time_t InspIRCd::Time()