* +------------------------------------+
*
* InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
* ---------------------------------------------------
*/
-/* $Install: src/inspircd $(BINPATH) */
+/* $Core */
#include "inspircd.h"
+#include "inspircd_version.h"
#include <signal.h>
#ifndef WIN32
{
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 */
/* Close logging */
this->Logs->CloseLogs();
DeleteZero(this->Logs);
-
- delete RehashFinishMutex;
}
void InspIRCd::Restart(const std::string &reason)
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);
SE = SEF->Create(this);
delete SEF;
- ThreadEngineFactory* tef = new ThreadEngineFactory();
- this->Threads = tef->Create(this);
- delete tef;
- this->Mutexes = new MutexFactory(this);
+ this->Threads = new ThreadEngine(this);
/* Default implementation does nothing */
this->PI = new ProtocolInterface(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 */
}
/* 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;
Exit(0);
}
- RehashFinishMutex = Mutexes->CreateMutex();
-
while (true)
{
#ifndef WIN32
#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.