* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * InspIRCd: (C) 2002-2010 InspIRCd Development Team
* See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
ports.clear();
/* Close all client sockets, or the new process inherits them */
- std::vector<User*>::reverse_iterator i = Users->local_users.rbegin();
+ std::vector<LocalUser*>::reverse_iterator i = Users->local_users.rbegin();
while (i != this->Users->local_users.rend())
{
User* u = *i++;
/* 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 */
- FakeClient->cull();
+ if (FakeClient)
+ FakeClient->cull();
+ if (Res)
+ Res->cull();
DeleteZero(this->FakeClient);
DeleteZero(this->Users);
DeleteZero(this->Modes);
/* Figure out our filename (if theyve renamed it, we're boned) */
std::string me;
+ char** argv = Config->cmdline.argv;
+
#ifdef WINDOWS
char module[MAX_PATH];
if (GetModuleFileName(NULL, module, MAX_PATH))
me = module;
#else
- me = Config->MyDir + "/inspircd";
+ me = argv[0];
#endif
- char** argv = Config->argv;
-
this->Cleanup();
if (execv(me.c_str(), argv) == -1)
exit(0);
}
setsid ();
- umask (007);
printf("InspIRCd Process ID: \033[1;32m%lu\033[0m\n",(unsigned long)getpid());
signal(SIGTERM, InspIRCd::SetSignal);
}
InspIRCd::InspIRCd(int argc, char** argv) :
- ConfigFileName("inspircd.conf"),
+ ConfigFileName("conf/inspircd.conf"),
/* Functor pointer initialisation.
*
this->ConfigThread = NULL;
// Initialise TIME
- this->TIME = time(NULL);
+ clock_gettime(CLOCK_REALTIME, &TIME);
+ this->startup_time = TIME.tv_sec;
// This must be created first, so other parts of Insp can use it while starting up
this->Logs = new LogManager;
this->Parser = new CommandParser;
this->XLines = new XLineManager;
- this->Config->argv = argv;
- this->Config->argc = argc;
-
- this->TIME = this->OLDTIME = this->startup_time = time(NULL);
- srand(this->TIME);
+ this->Config->cmdline.argv = argv;
+ this->Config->cmdline.argc = argc;
- *this->LogFileName = 0;
+ srand(TIME.tv_nsec ^ TIME.tv_sec);
struct option longopts[] =
{
{
case 'f':
/* Log filename was set */
- strlcpy(LogFileName, optarg, MAXBUF);
+ Config->cmdline.startup_log = optarg;
break;
case 'c':
/* Config filename was set */
#endif
/* Set the finished argument values */
- Config->nofork = do_nofork;
- Config->forcedebug = do_debug;
- Config->writelog = !do_nolog;
- Config->TestSuite = do_testsuite;
+ Config->cmdline.nofork = do_nofork;
+ Config->cmdline.forcedebug = do_debug;
+ Config->cmdline.writelog = !do_nolog;
+ Config->cmdline.TestSuite = do_testsuite;
- if (!this->OpenLog(argv, argc))
+ if (do_debug)
{
- printf("ERROR: Could not open logfile %s: %s\n\n", Config->logpath.c_str(), strerror(errno));
+ FileWriter* fw = new FileWriter(stdout);
+ FileLogStream* fls = new FileLogStream(DEBUG, fw);
+ Logs->AddLogTypes("*", fls, true);
+ }
+ else if (!this->OpenLog(argv, argc))
+ {
+ printf("ERROR: Could not open initial logfile %s: %s\n\n", Config->cmdline.startup_log.c_str(), strerror(errno));
Exit(EXIT_STATUS_LOG);
}
this->SetSignals();
- if (!Config->nofork)
+ if (!Config->cmdline.nofork)
{
if (!this->DaemonSeed())
{
this->Config->Apply(NULL, "");
Logs->OpenFileLogs();
- this->Res = new DNS;
+ this->Res = new DNS();
/*
* Initialise SID/UID.
}
/* set up fake client again this time with the correct uid */
- this->FakeClient = new FakeUser("!");
- this->FakeClient->SetFakeServer(Config->ServerName);
+ this->FakeClient = new FakeUser(Config->sid, Config->ServerName);
// Get XLine to do it's thing.
this->XLines->CheckELines();
Config->ServerName.c_str(),Config->GetSID().c_str(), SE->GetMaxFds());
#ifndef WINDOWS
- if (!Config->nofork)
+ if (!Config->cmdline.nofork)
{
if (kill(getppid(), SIGTERM) == -1)
{
{
fclose(stdin);
fclose(stderr);
- fclose(stdout);
+ if (!Config->cmdline.forcedebug)
+ fclose(stdout);
}
else
{
Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName.c_str(),Config->GetSID().c_str(), SE->GetMaxFds());
#ifndef WIN32
- if (!Config->SetGroup.empty())
+ std::string SetUser = Config->ConfValue("security")->getString("runasuser");
+ std::string SetGroup = Config->ConfValue("security")->getString("runasgroup");
+ if (!SetGroup.empty())
{
int ret;
struct group *g;
errno = 0;
- g = getgrnam(this->Config->SetGroup.c_str());
+ g = getgrnam(SetGroup.c_str());
if (!g)
{
}
}
- if (!Config->SetUser.empty())
+ if (!SetUser.empty())
{
// setuid
struct passwd *u;
errno = 0;
- u = getpwnam(this->Config->SetUser.c_str());
+ u = getpwnam(SetUser.c_str());
if (!u)
{
this->WritePID(Config->PID);
}
+void InspIRCd::UpdateTime()
+{
+ clock_gettime(CLOCK_REALTIME, &TIME);
+}
+
int InspIRCd::Run()
{
/* See if we're supposed to be running the test suite rather than entering the mainloop */
- if (Config->TestSuite)
+ if (Config->cmdline.TestSuite)
{
TestSuite* ts = new TestSuite;
delete ts;
Exit(0);
}
+ UpdateTime();
+ time_t OLDTIME = TIME.tv_sec;
+
while (true)
{
#ifndef WIN32
ConfigThread = NULL;
}
- /* time() seems to be a pretty expensive syscall, so avoid calling it too much.
- * Once per loop iteration is pleanty.
- */
- OLDTIME = TIME;
- TIME = time(NULL);
+ UpdateTime();
/* Run background module timers every few seconds
* (the docs say modules shouldnt rely on accurate
* timing using this event, so we dont have to
* time this exactly).
*/
- if (TIME != OLDTIME)
+ if (TIME.tv_sec != OLDTIME)
{
+ OLDTIME = TIME.tv_sec;
+#ifndef WIN32
+ getrusage(RUSAGE_SELF, &ru);
+ stats->LastSampled = TIME;
+ stats->LastCPU = ru.ru_utime;
+#else
+ WindowsIPC->Check();
+#endif
+
/* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */
- if (TIME < OLDTIME - 2)
+ if (TIME.tv_sec < OLDTIME - 2)
{
- SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME);
+ SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME.tv_sec);
}
- else if (TIME > OLDTIME + 2)
+ else if (TIME.tv_sec > OLDTIME + 2)
{
- SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME - OLDTIME);
+ SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME.tv_sec - OLDTIME);
}
- if ((TIME % 3600) == 0)
+ if ((TIME.tv_sec % 3600) == 0)
{
this->RehashUsersAndChans();
FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect());
}
- Timers->TickTimers(TIME);
+ Timers->TickTimers(TIME.tv_sec);
this->DoBackgroundUserStuff();
- if ((TIME % 5) == 0)
+ if ((TIME.tv_sec % 5) == 0)
{
- FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME));
+ FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME.tv_sec));
SNO->FlushSnotices();
}
-#ifndef WIN32
- /* Same change as in cmd_stats.cpp, use RUSAGE_SELF rather than '0' -- Om */
- if (!getrusage(RUSAGE_SELF, &ru))
- {
- gettimeofday(&this->stats->LastSampled, NULL);
- this->stats->LastCPU = ru.ru_utime;
- }
-#else
- WindowsIPC->Check();
-#endif
}
/* Call the socket engine to wait on the active
* (until this returns true, a user will block in the waiting state, waiting to connect up to the
* registration timeout maximum seconds)
*/
-bool InspIRCd::AllModulesReportReady(User* user)
+bool InspIRCd::AllModulesReportReady(LocalUser* user)
{
ModResult res;
FIRST_MOD_RESULT(OnCheckReady, res, (user));
return (res == MOD_RES_PASSTHRU);
}
-time_t InspIRCd::Time()
-{
- return TIME;
-}
-
void InspIRCd::SetSignal(int signal)
{
*mysig = signal;