#include "exitcodes.h"
#include "caller.h"
-#ifdef WIN32
-
-/* This MUST remain static and delcared outside the class, so that WriteProcessMemory can reference it properly */
-static DWORD owner_processid = 0;
-
-DWORD WindowsForkStart(InspIRCd * Instance)
-{
- /* Windows implementation of fork() :P */
-
- char module[MAX_PATH];
- if(!GetModuleFileName(NULL, module, MAX_PATH))
- {
- printf("GetModuleFileName() failed.\n");
- return false;
- }
-
- STARTUPINFO startupinfo;
- PROCESS_INFORMATION procinfo;
- ZeroMemory(&startupinfo, sizeof(STARTUPINFO));
- ZeroMemory(&procinfo, sizeof(PROCESS_INFORMATION));
-
- // Fill in the startup info struct
- GetStartupInfo(&startupinfo);
-
- /* Default creation flags create the processes suspended */
- DWORD startupflags = CREATE_SUSPENDED;
-
- /* On windows 2003/XP and above, we can use the value
- * CREATE_PRESERVE_CODE_AUTHZ_LEVEL which gives more access
- * to the process which we may require on these operating systems.
- */
- OSVERSIONINFO vi;
- vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&vi);
- if ((vi.dwMajorVersion >= 5) && (vi.dwMinorVersion > 0))
- startupflags |= CREATE_PRESERVE_CODE_AUTHZ_LEVEL;
-
- // Launch our "forked" process.
- BOOL bSuccess = CreateProcess ( module, // Module (exe) filename
- strdup(GetCommandLine()), // Command line (exe plus parameters from the OS)
- // NOTE: We cannot return the direct value of the
- // GetCommandLine function here, as the pointer is
- // passed straight to the child process, and will be
- // invalid once we exit as it goes out of context.
- // strdup() seems ok, though.
- 0, // PROCESS_SECURITY_ATTRIBUTES
- 0, // THREAD_SECURITY_ATTRIBUTES
- TRUE, // We went to inherit handles.
- startupflags, // Allow us full access to the process and suspend it.
- 0, // ENVIRONMENT
- 0, // CURRENT_DIRECTORY
- &startupinfo, // startup info
- &procinfo); // process info
-
- if(!bSuccess)
- {
- printf("CreateProcess() error: %s\n", dlerror());
- return false;
- }
-
- // Set the owner process id in the target process.
- SIZE_T written = 0;
- DWORD pid = GetCurrentProcessId();
- if(!WriteProcessMemory(procinfo.hProcess, &owner_processid, &pid, sizeof(DWORD), &written) || written != sizeof(DWORD))
- {
- printf("WriteProcessMemory() failed: %s\n", dlerror());
- return false;
- }
-
- // Resume the other thread (let it start)
- ResumeThread(procinfo.hThread);
-
- // Wait for the new process to kill us. If there is some error, the new process will end and we will end up at the next line.
- WaitForSingleObject(procinfo.hProcess, INFINITE);
-
- // If we hit this it means startup failed, default to 14 if this fails.
- DWORD ExitCode = 14;
- GetExitCodeProcess(procinfo.hProcess, &ExitCode);
- CloseHandle(procinfo.hThread);
- CloseHandle(procinfo.hProcess);
- return ExitCode;
-}
-
-void WindowsForkKillOwner(InspIRCd * Instance)
-{
- HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, owner_processid);
- if(!hProcess || !owner_processid)
- {
- printf("Could not open process id %u: %s.\n", owner_processid, dlerror());
- Instance->Exit(14);
- }
-
- // die die die
- if(!TerminateProcess(hProcess, 0))
- {
- printf("Could not TerminateProcess(): %s\n", dlerror());
- Instance->Exit(14);
- }
-
- CloseHandle(hProcess);
-}
-
-#endif
-
using irc::sockets::NonBlocking;
using irc::sockets::Blocking;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_sockaddr;
InspIRCd* SI = NULL;
+int* mysig = NULL;
/* Burlex: Moved from exitcodes.h -- due to duplicate symbols */
const char* ExitCodes[] =
"Received SIGTERM", /* 15 */
};
-void InspIRCd::Exit(int status)
-{
-#ifdef WINDOWS
- CloseIPC();
-#endif
- if (SI)
- {
- SI->SendError("Exiting with status " + ConvToStr(status) + " (" + std::string(ExitCodes[status]) + ")");
- SI->Cleanup();
- }
- exit (status);
-}
-
void InspIRCd::Cleanup()
{
std::vector<std::string> mymodnames;
{
#ifndef WIN32
signal(SIGALRM, SIG_IGN);
- signal(SIGHUP, InspIRCd::Rehash);
+ signal(SIGHUP, InspIRCd::SetSignal);
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
#endif
- signal(SIGTERM, InspIRCd::Exit);
+ signal(SIGTERM, InspIRCd::SetSignal);
}
void InspIRCd::QuickExit(int status)
umask (007);
printf("InspIRCd Process ID: \033[1;32m%lu\033[0m\n",(unsigned long)getpid());
- signal(SIGTERM, InspIRCd::Exit);
+ signal(SIGTERM, InspIRCd::SetSignal);
rlimit rl;
if (getrlimit(RLIMIT_CORE, &rl) == -1)
InspIRCd::InspIRCd(int argc, char** argv)
: ModCount(0),
GlobalCulls(this),
- HandleIsNick(this), IsNick(&HandleIsNick)
+
+ /* Functor initialisation. Note that the ordering here is very important. */
+ HandleProcessUser(this),
+ HandleIsNick(this),
+ HandleIsIdent(this),
+ HandleFindDescriptor(this),
+ HandleFloodQuitUser(this),
+
+ /* Functor pointer initialisation. Must match the order of the list above */
+ ProcessUser(&HandleProcessUser),
+ IsNick(&HandleIsNick),
+ IsIdent(&HandleIsIdent),
+ FindDescriptor(&HandleFindDescriptor),
+ FloodQuitUser(&HandleFloodQuitUser)
+
{
+
int found_ports = 0;
FailedPortList pl;
int do_version = 0, do_nofork = 0, do_debug = 0, do_nolog = 0, do_root = 0; /* flag variables */
memset(&server, 0, sizeof(server));
memset(&client, 0, sizeof(client));
+ this->s_signal = 0;
+
this->unregistered_count = 0;
this->clientlist = new user_hash();
this->Config->argv = argv;
this->Config->argc = argc;
- chdir(Config->GetFullProgDir().c_str());
+ if (chdir(Config->GetFullProgDir().c_str()))
+ {
+ printf("Unable to change to my directory: %s\nAborted.", strerror(errno));
+ exit(0);
+ }
this->Config->opertypes.clear();
this->Config->operclass.clear();
#ifdef WIN32
// Handle forking
- if(!do_nofork && !owner_processid)
+ if(!do_nofork)
{
DWORD ExitCode = WindowsForkStart(this);
if(ExitCode)
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
+ ChangeWindowsSpecificPointers(this);
#endif
if (!ServerConfig::FileExists(this->ConfigFileName))
{
}
}
#else
- InitIPC();
+ WindowsIPC = new IPC(this);
if(!Config->nofork)
{
WindowsForkKillOwner(this);
this->stats->LastCPU = ru.ru_utime;
}
#else
- CheckIPC(this);
+ WindowsIPC->Check();
if(Config->nofork)
{
/* If any inspsockets closed, remove them */
this->InspSocketCull();
+
+ if (this->s_signal)
+ {
+ this->SignalHandler(s_signal);
+ this->s_signal = 0;
+ }
+
}
void InspIRCd::InspSocketCull()
int main(int argc, char** argv)
{
SI = new InspIRCd(argc, argv);
+ mysig = &SI->s_signal;
SI->Run();
delete SI;
return 0;
{
return time_delta;
}
+
+void InspIRCd::SetSignal(int signal)
+{
+ *mysig = signal;
+}
+