* ---------------------------------------------------
*/
+/* w00t was here. ;p */
+
/* $Install: src/inspircd $(BINPATH) */
#include "inspircd.h"
#include <signal.h>
#include <stdlib.h>
#include <crtdbg.h>
#endif
+
+ #include <pwd.h> // setuid
+ #include <grp.h> // setgid
#endif
#include <fstream>
#include "caller.h"
#include "testsuite.h"
-using irc::sockets::insp_ntoa;
-using irc::sockets::insp_inaddr;
-using irc::sockets::insp_sockaddr;
-
InspIRCd* SI = NULL;
int* mysig = NULL;
"Couldn't load module on startup", /* 13 */
"Could not create windows forked process", /* 14 */
"Received SIGTERM", /* 15 */
+ "Bad command handler loaded", /* 16 */
+ "RegisterServiceCtrlHandler failed", /* 17 */
+ "UpdateSCMStatus failed", /* 18 */
+ "CreateEvent failed" /* 19 */
};
void InspIRCd::Cleanup()
/* Close all client sockets, or the new process inherits them */
for (std::vector<User*>::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++)
{
- (*i)->SetWriteError("Server shutdown");
+ this->Users->QuitUser((*i), "Server shutdown");
(*i)->CloseSocket();
}
ThreadEngineFactory* tef = new ThreadEngineFactory();
this->Threads = tef->Create(this);
delete tef;
+ this->Mutexes = new MutexFactory(this);
/* Default implementation does nothing */
this->PI = new ProtocolInterface(this);
/* During startup we don't actually initialize this
* in the thread engine.
*/
- this->ConfigThread = new ConfigReaderThread(this, true, NULL);
+ this->ConfigThread = new ConfigReaderThread(this, true, "");
ConfigThread->Run();
delete ConfigThread;
this->ConfigThread = NULL;
this->BuildISupport();
InitializeDisabledCommands(Config->DisabledCommands, this);
- /*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("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports);
int j = 1;
for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++)
{
- printf("%d.\tIP: %s\tPort: %lu\n", j, i->first.empty() ? "<all>" : i->first.c_str(), (unsigned long)i->second);
+ printf("%d.\tAddress: %s\tReason: %s\n", j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str());
}
}
WindowsForkKillOwner(this);
FreeConsole();
}
+ /* Set win32 service as running, if we are running as a service */
+ SetServiceRunning();
#endif
Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName,Config->GetSID().c_str(), SE->GetMaxFds());
+#ifndef WIN32
+ if (*(this->Config->SetGroup))
+ {
+ int ret;
+
+ // setgroups
+ ret = setgroups(0, NULL);
+
+ if (ret == -1)
+ {
+ this->Logs->Log("SETGROUPS", DEFAULT, "setgroups() failed (wtf?): %s", strerror(errno));
+ this->QuickExit(0);
+ }
+
+ // setgid
+ struct group *g;
+
+ errno = 0;
+ g = getgrnam(this->Config->SetGroup);
+
+ if (!g)
+ {
+ this->Logs->Log("SETGUID", DEFAULT, "getgrnam() failed (bad user?): %s", strerror(errno));
+ this->QuickExit(0);
+ }
+
+ ret = setgid(g->gr_gid);
+
+ if (ret == -1)
+ {
+ this->Logs->Log("SETGUID", DEFAULT, "setgid() failed (bad user?): %s", strerror(errno));
+ this->QuickExit(0);
+ }
+ }
+
+ if (*(this->Config->SetUser))
+ {
+ // setuid
+ struct passwd *u;
+
+ errno = 0;
+ u = getpwnam(this->Config->SetUser);
+
+ if (!u)
+ {
+ this->Logs->Log("SETGUID", DEFAULT, "getpwnam() failed (bad user?): %s", strerror(errno));
+ this->QuickExit(0);
+ }
+
+ int ret = setuid(u->pw_uid);
+
+ if (ret == -1)
+ {
+ this->Logs->Log("SETGUID", DEFAULT, "setuid() failed (bad user?): %s", strerror(errno));
+ this->QuickExit(0);
+ }
+ }
+#endif
+
this->WritePID(Config->PID);
}
this->Res->Rehash();
this->ResetMaxBans();
InitializeDisabledCommands(Config->DisabledCommands, this);
- FOREACH_MOD_I(this, I_OnRehash, OnRehash(Config->RehashUser, Config->RehashParameter));
+ User* user = !Config->RehashUserUID.empty() ? FindNick(Config->RehashUserUID) : NULL;
+ FOREACH_MOD_I(this, I_OnRehash, OnRehash(user, Config->RehashParameter));
this->BuildISupport();
}
*/
if (TIME != OLDTIME)
{
- if (TIME < OLDTIME)
+ /* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */
+ if (TIME < OLDTIME - 2)
{
- SNO->WriteToSnoMask('A', "\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);
+ }
+ else if (TIME > OLDTIME + 2)
+ {
+ SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME - OLDTIME);
}
if ((TIME % 3600) == 0)
* An ircd in five lines! bwahahaha. ahahahahaha. ahahah *cough*.
*/
-int main(int argc, char ** argv)
-{
- SI = new InspIRCd(argc, argv);
- mysig = &SI->s_signal;
- SI->Run();
- delete SI;
- return 0;
-}
-
/* this returns true when all modules are satisfied that the user should be allowed onto the irc server
* (until this returns true, a user will block in the waiting state, waiting to connect up to the
* registration timeout maximum seconds)
{
*mysig = signal;
}
+
+/* On posix systems, the flow of the program starts right here, with
+ * ENTRYPOINT being a #define that defines main(). On Windows, ENTRYPOINT
+ * defines smain() and the real main() is in the service code under
+ * win32service.cpp. This allows the service control manager to control
+ * the process where we are running as a windows service.
+ */
+ENTRYPOINT
+{
+ SI = new InspIRCd(argc, argv);
+ mysig = &SI->s_signal;
+ SI->Run();
+ delete SI;
+ return 0;
+}