2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "inspircd.h"
\r
21 #include "threadengine.h"
\r
22 #include "inspircd_namedpipe.h"
\r
23 #include "exitcodes.h"
\r
24 #include <windows.h>
\r
28 IPCThread::IPCThread()
\r
31 ServerInstance->Logs->Log("IPC", DEBUG, "Could not initialise WMI. CPU percantage reports will not be available.");
\r
34 IPCThread::~IPCThread()
\r
39 void IPCThread::Run()
\r
41 LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus";
\r
43 while (GetExitFlag() == false)
\r
45 Pipe = CreateNamedPipe (Pipename,
\r
46 PIPE_ACCESS_DUPLEX, // read/write access
\r
47 PIPE_TYPE_MESSAGE | // message type pipe
\r
48 PIPE_READMODE_MESSAGE | // message-read mode
\r
49 PIPE_WAIT, // blocking mode
\r
50 PIPE_UNLIMITED_INSTANCES, // max. instances
\r
51 MAXBUF, // output buffer size
\r
52 MAXBUF, // input buffer size
\r
53 1000, // client time-out
\r
54 NULL); // no security attribute
\r
56 if (Pipe == INVALID_HANDLE_VALUE)
\r
62 Connected = ConnectNamedPipe(Pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
\r
66 Success = ReadFile (Pipe, // handle to pipe
\r
67 this->status, // buffer to receive data
\r
68 1, // size of buffer
\r
69 &BytesRead, // number of bytes read
\r
70 NULL); // not overlapped I/O
\r
72 if (!Success || !BytesRead)
\r
78 const char oldrequest = this->GetStatus();
\r
80 /* Wait for main thread to pick up status change */
\r
81 while (this->GetStatus())
\r
84 std::stringstream stat;
\r
86 float kbitpersec_in, kbitpersec_out, kbitpersec_total;
\r
88 PROCESS_MEMORY_COUNTERS MemCounters;
\r
90 ServerInstance->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total);
\r
92 bool HaveMemoryStats = GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters));
\r
94 stat << "name " << ServerInstance->Config->ServerName << std::endl;
\r
95 stat << "gecos " << ServerInstance->Config->ServerDesc << std::endl;
\r
96 stat << "numlocalusers " << ServerInstance->Users->LocalUserCount() << std::endl;
\r
97 stat << "numusers " << ServerInstance->Users->clientlist->size() << std::endl;
\r
98 stat << "numchannels " << ServerInstance->chanlist->size() << std::endl;
\r
99 stat << "numopers " << ServerInstance->Users->OperCount() << std::endl;
\r
100 stat << "timestamp " << ServerInstance->Time() << std::endl;
\r
101 stat << "pid " << GetProcessId(GetCurrentProcess()) << std::endl;
\r
102 stat << "request " << oldrequest << std::endl;
\r
103 stat << "result " << this->GetResult() << std::endl;
\r
104 stat << "kbitspersectotal " << kbitpersec_total << std::endl;
\r
105 stat << "kbitspersecout " << kbitpersec_out << std::endl;
\r
106 stat << "kbitspersecin " << kbitpersec_in << std::endl;
\r
107 stat << "uptime " << ServerInstance->Time() - ServerInstance->startup_time << std::endl;
\r
108 stat << "cpu " << getcpu() << std::endl;
\r
109 if (HaveMemoryStats)
\r
111 stat << "workingset " << MemCounters.WorkingSetSize << std::endl;
\r
112 stat << "pagefile " << MemCounters.PagefileUsage << std::endl;
\r
113 stat << "pagefaults " << MemCounters.PageFaultCount << std::endl;
\r
116 stat << "END" << std::endl;
\r
118 /* This is a blocking call and will succeed, so long as the client doesnt disconnect */
\r
119 Success = WriteFile(Pipe, stat.str().data(), stat.str().length(), &Written, NULL);
\r
121 FlushFileBuffers(Pipe);
\r
122 DisconnectNamedPipe(Pipe);
\r
128 const char IPCThread::GetStatus()
\r
133 void IPCThread::ClearStatus()
\r
138 int IPCThread::GetResult()
\r
143 void IPCThread::SetResult(int newresult)
\r
145 result = newresult;
\r
151 /* The IPC pipe is threaded */
\r
152 thread = new IPCThread();
\r
153 ServerInstance->Threads->Start(thread);
\r
158 switch (thread->GetStatus())
\r
162 thread->SetResult(0);
\r
163 thread->ClearStatus();
\r
167 ServerInstance->Rehash("due to rehash command from GUI");
\r
168 thread->SetResult(0);
\r
169 thread->ClearStatus();
\r
173 thread->SetResult(0);
\r
174 thread->ClearStatus();
\r
175 ServerInstance->Exit(EXIT_STATUS_NOERROR);
\r
179 thread->SetResult(0);
\r
180 thread->ClearStatus();
\r
181 ServerInstance->Restart("Restarting due to command from GUI");
\r
185 thread->SetResult(0);
\r
186 thread->ClearStatus();
\r
187 ServerInstance->Config->cmdline.forcedebug = !ServerInstance->Config->cmdline.forcedebug;
\r
194 thread->SetExitFlag();
\r