From c11f2d5ca20c0be19a31e0f45b32b10bcbd601d3 Mon Sep 17 00:00:00 2001 From: Jean Flach Date: Mon, 12 Jan 2015 15:53:25 +0100 Subject: [PATCH] Add -d/--debug option for windows plugins #fixes 8119 --- plugins/check_disk.cpp | 58 +++++++++++++++--- plugins/check_load.cpp | 33 +++++++++- plugins/check_network.cpp | 43 +++++++++++-- plugins/check_ping.cpp | 74 +++++++++++++++++++--- plugins/check_procs.cpp | 126 +++++++++++++++++++++++++++----------- plugins/check_service.cpp | 27 +++++++- plugins/check_swap.cpp | 22 +++++++ plugins/check_update.cpp | 101 ++++++++++++++++++------------ plugins/check_uptime.cpp | 16 ++++- plugins/check_users.cpp | 34 +++++++++- 10 files changed, 431 insertions(+), 103 deletions(-) diff --git a/plugins/check_disk.cpp b/plugins/check_disk.cpp index b8b92ca8b..d592b0394 100644 --- a/plugins/check_disk.cpp +++ b/plugins/check_disk.cpp @@ -34,6 +34,8 @@ namespace po = boost::program_options; using std::cout; using std::endl; using std::set; using std::vector; using std::wstring; using std::wcout; +static BOOL debug = FALSE; + struct drive { wstring name; @@ -100,6 +102,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print usage message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue(), "warning threshold") ("critical,c", po::wvalue(), "critical threshold") ("path,p", po::wvalue>()->multitoken(), "declare explicitly which drives to check (default checks all)") @@ -196,11 +199,16 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } else printInfo.unit = BunitB; + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo, vector& vDrives) { + if (debug) + wcout << L"Constructing output string" << endl; state state = OK; double tCap = 0, tFree = 0; std::wstringstream perf, prePerf; @@ -233,13 +241,13 @@ int printOutput(printInfoStruct& printInfo, vector& vDrives) switch (state) { case OK: - wcout << L"DISK OK " << tFree << unit << prePerf.str() << perf.str() << endl; + wcout << L"DISK OK " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl; break; case WARNING: - wcout << L"DISK WARNING " << tFree << unit << prePerf.str() << perf.str() << endl; + wcout << L"DISK WARNING " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl; break; case CRITICAL: - wcout << L"DISK CRITICAL " << tFree << unit << prePerf.str() << perf.str() << endl; + wcout << L"DISK CRITICAL " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl; break; } @@ -249,29 +257,45 @@ int printOutput(printInfoStruct& printInfo, vector& vDrives) int check_drives(vector& vDrives) { DWORD dwResult, dwSize = 0, dwVolumePathNamesLen = MAX_PATH + 1; - wchar_t szLogicalDrives[MAX_PATH], szVolumeName[MAX_PATH], *szVolumePathNames; + wchar_t szLogicalDrives[1024], szVolumeName[MAX_PATH], *szVolumePathNames; HANDLE hVolume; wstring wsLogicalDrives; size_t volumeNameEnd = 0; set sDrives; + if (debug) + wcout << L"Getting logic drive string (includes network drives)" << endl; + dwResult = GetLogicalDriveStrings(MAX_PATH, szLogicalDrives); if (dwResult < 0 || dwResult > MAX_PATH) goto die; - + if (debug) + wcout << L"Splitting string into single drive names" << endl; + LPTSTR szSingleDrive = szLogicalDrives; while (*szSingleDrive) { wstring drname = szSingleDrive; sDrives.insert(drname); szSingleDrive += wcslen(szSingleDrive) + 1; + if (debug) + wcout << "Got: " << drname << endl; } + if (debug) + wcout << L"Getting volume mountpoints (includes NTFS folders)" << endl + << L"Getting first volume" << endl; + hVolume = FindFirstVolume(szVolumeName, MAX_PATH); if (hVolume == INVALID_HANDLE_VALUE) goto die; + if (debug) + wcout << L"Traversing through list of drives" << endl; + while (GetLastError() != ERROR_NO_MORE_FILES) { + if (debug) + wcout << L"Path name for " << szVolumeName << L"= \""; volumeNameEnd = wcslen(szVolumeName) - 1; szVolumePathNames = reinterpret_cast(new WCHAR[dwVolumePathNamesLen]); @@ -282,17 +306,25 @@ int check_drives(vector& vDrives) szVolumePathNames = reinterpret_cast(new WCHAR[dwVolumePathNamesLen]); } + wcout << szVolumePathNames << L"\"" << endl; + //.insert() does the dublicate checking sDrives.insert(wstring(szVolumePathNames)); FindNextVolume(hVolume, szVolumeName, MAX_PATH); } + wcout << L"Creating vector from found volumes, removing cd drives etc.:" << endl; for (set::iterator it = sDrives.begin(); it != sDrives.end(); ++it) { UINT type = GetDriveType(it->c_str()); if (type == DRIVE_FIXED || type == DRIVE_REMOTE) { + if (debug) + wcout << L"\t" << *it << endl; vDrives.push_back(drive(*it)); } } + + FindVolumeClose(hVolume); + delete[] reinterpret_cast(szVolumePathNames); return -1; die: @@ -306,15 +338,19 @@ int check_drives(vector& vDrives, printInfoStruct& printInfo) { wchar_t *slash = L"\\"; + if (debug) + wcout << L"Parsing user input drive names" << endl; + for (vector::iterator it = printInfo.drives.begin(); it != printInfo.drives.end(); ++it) { if (it->at(it->length() - 1) != *slash) it->append(slash); - if (std::wstring::npos == it->find(L":\\")) { wcout << "A \":\" is required after the drive name of " << *it << endl; return 3; } + if (debug) + wcout << L"Added " << *it << endl; vDrives.push_back(drive(*it)); } return -1; @@ -322,13 +358,21 @@ int check_drives(vector& vDrives, printInfoStruct& printInfo) bool getFreeAndCap(drive& drive, const Bunit& unit) { + if (debug) + wcout << L"Getting free disk space for drive " << drive.name << endl; ULARGE_INTEGER tempFree, tempTotal; if (!GetDiskFreeSpaceEx(drive.name.c_str(), NULL, &tempTotal, &tempFree)) { return FALSE; } - + if (debug) + wcout << L"\tcap: " << tempFree.QuadPart << endl; drive.cap = round((tempTotal.QuadPart / pow(1024.0, unit))); + if (debug) + wcout << L"\tAfter converion: " << drive.cap << endl + << L"\tfree: " << tempFree.QuadPart << endl; drive.free = round((tempFree.QuadPart / pow(1024.0, unit))); + if (debug) + wcout << L"\tAfter converion: " << drive.free << endl << endl; return TRUE; } \ No newline at end of file diff --git a/plugins/check_load.cpp b/plugins/check_load.cpp index 1a4637c9c..016bbb9f8 100644 --- a/plugins/check_load.cpp +++ b/plugins/check_load.cpp @@ -33,6 +33,8 @@ namespace po = boost::program_options; using std::endl; using std::cout; using std::wstring; using std::wcout; +static BOOL debug = FALSE; + struct printInfoStruct { threshold warn, crit; @@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print usage message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue(), "warning value (in percent)") ("critical,c", po::wvalue(), "critical value (in percent)") ; @@ -156,11 +159,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } } + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo) { + if (debug) + wcout << L"Constructing output string" << endl; + state state = OK; if (printInfo.warn.rend(printInfo.load)) @@ -199,6 +208,9 @@ int check_load(printInfoStruct& printInfo) LPCWSTR path = L"\\Processor(_Total)\\% Idle Time"; + if (debug) + wcout << L"Creating query and adding counter" << endl; + err = PdhOpenQuery(NULL, NULL, &phQuery); if (!SUCCEEDED(err)) goto die; @@ -207,20 +219,39 @@ int check_load(printInfoStruct& printInfo) if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Collecting first batch of query data" << endl; + err = PdhCollectQueryData(phQuery); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Sleep for one second" << endl; + Sleep(1000); + if (debug) + wcout << L"Collecting second batch of query data" << endl; + err = PdhCollectQueryData(phQuery); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Creating formatted counter array" << endl; + err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue); if (SUCCEEDED(err)) { - if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA) + if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA) { + if (debug) + wcout << L"Recieved Value of " << DisplayValue.doubleValue << L" (idle)" << endl; printInfo.load = 100.0 - DisplayValue.doubleValue; + } + + if (debug) + wcout << L"Finished collection. Cleaning up and returning" << endl; + PdhCloseQuery(phQuery); return -1; } diff --git a/plugins/check_network.cpp b/plugins/check_network.cpp index 8e0589dc5..060c0f99b 100644 --- a/plugins/check_network.cpp +++ b/plugins/check_network.cpp @@ -31,6 +31,9 @@ namespace po = boost::program_options; using std::endl; using std::vector; using std::wstring; using std::wcout; using std::cout; + +static BOOL debug = FALSE; + struct nInterface { wstring name; @@ -77,6 +80,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print usage and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue(), "warning value") ("critical,c", po::wvalue(), "critical value") ; @@ -161,11 +165,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } } + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo, const vector& vInterfaces) { + if (debug) + wcout << L"Constructing output string" << endl; + long tIn = 0, tOut = 0; std::wstringstream tss, perfDataFirst; state state = OK; @@ -209,6 +219,9 @@ int check_network(vector & vInterfaces) PDH_FMT_COUNTERVALUE_ITEM *pDisplayValuesIn = NULL, *pDisplayValuesOut = NULL; PDH_STATUS err; + if (debug) + wcout << L"Creating Query and adding counters" << endl; + err = PdhOpenQuery(NULL, NULL, &phQuery); if (!SUCCEEDED(err)) goto die; @@ -221,16 +234,28 @@ int check_network(vector & vInterfaces) if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Collecting first batch of query data" << endl; + err = PdhCollectQueryData(phQuery); if (!SUCCEEDED(err)) goto die; - + + if (debug) + wcout << L"Sleep for one second" << endl; + Sleep(1000); + if (debug) + wcout << L"Collecting second batch of query data" << endl; + err = PdhCollectQueryData(phQuery); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Creating formatted counter arrays" << endl; + err = PdhGetFormattedCounterArray(phCounterIn, PDH_FMT_LONG, &dwBufferSizeIn, &dwItemCount, pDisplayValuesIn); if (err == PDH_MORE_DATA || SUCCEEDED(err)) pDisplayValuesIn = reinterpret_cast(new BYTE[dwItemCount*dwBufferSizeIn]); @@ -251,16 +276,24 @@ int check_network(vector & vInterfaces) if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Going over counter array" << endl; + for (DWORD i = 0; i < dwItemCount; i++) { nInterface *iface = new nInterface(wstring(pDisplayValuesIn[i].szName)); iface->BytesInSec = pDisplayValuesIn[i].FmtValue.longValue; iface->BytesOutSec = pDisplayValuesOut[i].FmtValue.longValue; vInterfaces.push_back(*iface); + if (debug) + wcout << L"Collected interface " << pDisplayValuesIn[i].szName << endl; } - PdhCloseQuery(phQuery); - delete pDisplayValuesIn; - delete pDisplayValuesOut; - return -1; + if (debug) + wcout << L"Finished collection. Cleaning up and returning" << endl; + + PdhCloseQuery(phQuery); + delete reinterpret_cast(pDisplayValuesIn); + delete reinterpret_cast(pDisplayValuesOut); + return -1; die: die(err); if (phQuery) diff --git a/plugins/check_ping.cpp b/plugins/check_ping.cpp index 0e4c61fc9..c9ee7fe80 100644 --- a/plugins/check_ping.cpp +++ b/plugins/check_ping.cpp @@ -40,6 +40,8 @@ namespace po = boost::program_options; using std::cout; using std::endl; using std::wcout; using std::wstring; using std::string; +static BOOL debug = FALSE; + struct response { double avg; @@ -97,6 +99,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print usage message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("host,H", po::wvalue()->required(), "host ip to ping") (",4", "--host is an ipv4 address (default)") (",6", "--host is an ipv6 address") @@ -222,11 +225,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo.host = vm["host"].as(); + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo, response& response) { + if (debug) + wcout << L"Constructing output string" << endl; + state state = OK; double plp = ((double)response.dropped / printInfo.num) * 100.0; @@ -273,6 +282,9 @@ int check_ping4(const printInfoStruct& pi, response& response) LARGE_INTEGER frequency, timer1, timer2; LPCWSTR term; + if (debug) + wcout << L"Parsing ip address" << endl; + if (RtlIpv4StringToAddress(pi.host.c_str(), TRUE, &term, &ipDest4) == STATUS_INVALID_PARAMETER) { std::wcout << pi.host << " is not a valid ip address" << std::endl; return 3; @@ -283,6 +295,9 @@ int check_ping4(const printInfoStruct& pi, response& response) return 3; } + if (debug) + wcout << L"Creating Icmp File" << endl; + if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE) goto die; @@ -295,20 +310,33 @@ int check_ping4(const printInfoStruct& pi, response& response) QueryPerformanceFrequency(&frequency); do { QueryPerformanceCounter(&timer1); - dwRet = IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr, - NULL, 0, NULL, repBuf, dwRepSize, pi.timeout); - if (!dwRet) { + + if (debug) + wcout << L"Sending Icmp echo" << endl; + + if (!IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr, + NULL, 0, NULL, repBuf, dwRepSize, pi.timeout)) { response.dropped++; + if (debug) + wcout << L"Dropped: Response was 0" << endl; continue; } + if (debug) + wcout << "Ping recieved" << endl; + PICMP_ECHO_REPLY pEchoReply = static_cast(repBuf); if (pEchoReply->Status != IP_SUCCESS) { response.dropped++; + if (debug) + wcout << L"Dropped: echo reply status " << pEchoReply->Status << endl; continue; } + if (debug) + wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << endl; + rtt += pEchoReply->RoundTripTime; if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin) response.pMin = pEchoReply->RoundTripTime; @@ -320,6 +348,8 @@ int check_ping4(const printInfoStruct& pi, response& response) Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart)); } while (--num); + if (debug) + wcout << L"All pings sent. Cleaning up and returning" << endl; IcmpCloseHandle(hIcmp); delete reinterpret_cast(repBuf); @@ -350,6 +380,9 @@ int check_ping6(const printInfoStruct& pi, response& response) int num = pi.num; UINT rtt = 0; + if (debug) + wcout << L"Parsing ip address" << endl; + if (RtlIpv6StringToAddressEx(pi.host.c_str(), &ipDest6.sin6_addr, &ipDest6.sin6_scope_id, &ipDest6.sin6_port)) { std::wcout << pi.host << " is not a valid ipv6 address" << std::endl; return 3; @@ -362,6 +395,9 @@ int check_ping6(const printInfoStruct& pi, response& response) ipSource6.sin6_flowinfo = 0; ipSource6.sin6_port = 0; + if (debug) + wcout << L"Creating Icmp File" << endl; + HANDLE hIcmp = Icmp6CreateFile(); if (hIcmp == INVALID_HANDLE_VALUE) { goto die; @@ -370,32 +406,50 @@ int check_ping6(const printInfoStruct& pi, response& response) QueryPerformanceFrequency(&frequency); do { QueryPerformanceCounter(&timer1); + + if (debug) + wcout << L"Sending Icmp echo" << endl; + if (!Icmp6SendEcho2(hIcmp, NULL, NULL, NULL, &ipSource6, &ipDest6, NULL, 0, &ipInfo, repBuf, dwRepSize, pi.timeout)) { response.dropped++; + if (debug) + wcout << L"Dropped: Response was 0" << endl; continue; } + if (debug) + wcout << "Ping recieved" << endl; + Icmp6ParseReplies(repBuf, dwRepSize); - ICMPV6_ECHO_REPLY *echoReply = static_cast(repBuf); + ICMPV6_ECHO_REPLY *pEchoReply = static_cast(repBuf); - if (echoReply->Status != IP_SUCCESS) { + if (pEchoReply->Status != IP_SUCCESS) { response.dropped++; + if (debug) + wcout << L"Dropped: echo reply status " << pEchoReply->Status << endl; continue; } - rtt += echoReply->RoundTripTime; - if (response.pMin == 0 || echoReply->RoundTripTime < response.pMin) - response.pMin = echoReply->RoundTripTime; - else if (echoReply->RoundTripTime > response.pMax) - response.pMax = echoReply->RoundTripTime; + rtt += pEchoReply->RoundTripTime; + + if (debug) + wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << endl; + + if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin) + response.pMin = pEchoReply->RoundTripTime; + else if (pEchoReply->RoundTripTime > response.pMax) + response.pMax = pEchoReply->RoundTripTime; QueryPerformanceCounter(&timer2); if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout) Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart)); } while (--num); + if (debug) + wcout << L"All pings sent. Cleaning up and returning" << endl; + IcmpCloseHandle(hIcmp); delete reinterpret_cast(repBuf); response.avg = ((double)rtt / pi.num); diff --git a/plugins/check_procs.cpp b/plugins/check_procs.cpp index 5fd3456ed..300392c6d 100644 --- a/plugins/check_procs.cpp +++ b/plugins/check_procs.cpp @@ -32,6 +32,8 @@ namespace po = boost::program_options; using std::endl; using std::wstring; using std::wcout; using std::cout; +static BOOL debug = FALSE; + struct printInfoStruct { threshold warn, crit; @@ -59,38 +61,6 @@ int wmain(int argc, wchar_t **argv) return printOutput(countProcs(), printInfo); } -int printOutput(const int numProcs, printInfoStruct& printInfo) -{ - state state = OK; - - if (printInfo.warn.rend(numProcs)) - state = WARNING; - - if (printInfo.crit.rend(numProcs)) - state = CRITICAL; - - wstring user = L""; - if (!printInfo.user.empty()) - user.append(L" processes of user ").append(printInfo.user); - - switch (state) { - case OK: - wcout << L"PROCS OK " << numProcs << user << L" | procs=" << numProcs << L";" - << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; - break; - case WARNING: - wcout << L"PROCS WARNING " << numProcs << user << L" | procs=" << numProcs << L";" - << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; - break; - case CRITICAL: - wcout << L"PROCS CRITICAL " << numProcs << user << L" | procs=" << numProcs << L";" - << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; - break; - } - - return state; -} - int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) { wchar_t namePath[MAX_PATH]; @@ -102,9 +72,10 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print help message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") + ("user,u", po::wvalue(), "count only processes by user [arg]") ("warning,w", po::wvalue(), "warning threshold") ("critical,c", po::wvalue(), "critical threshold") - ("user,u", po::wvalue(), "count only processes by user [arg]") ; po::basic_command_line_parser parser(ac, av); @@ -132,7 +103,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& cout << desc; wprintf( L"\nIt will then output a string looking something like this:\n\n" - L"\tPROCS WARNING 67|load=67;50;90;0\n\n" + L"\tPROCS WARNING 67 | load=67;50;90;0\n\n" L"\"PROCS\" being the type of the check, \"WARNING\" the returned status\n" L"and \"67\" is the returned value.\n" L"The performance data is found behind the \"|\", in order:\n" @@ -191,20 +162,67 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& if (vm.count("user")) printInfo.user = vm["user"].as(); + if (vm.count("debug")) + debug = TRUE; + return -1; } +int printOutput(const int numProcs, printInfoStruct& printInfo) +{ + if (debug) + wcout << L"Constructing output string" << endl; + + state state = OK; + + if (printInfo.warn.rend(numProcs)) + state = WARNING; + + if (printInfo.crit.rend(numProcs)) + state = CRITICAL; + + wstring user = L""; + if (!printInfo.user.empty()) + user.append(L" processes of user ").append(printInfo.user); + + switch (state) { + case OK: + wcout << L"PROCS OK " << numProcs << user << L" | procs=" << numProcs << L";" + << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; + break; + case WARNING: + wcout << L"PROCS WARNING " << numProcs << user << L" | procs=" << numProcs << L";" + << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; + break; + case CRITICAL: + wcout << L"PROCS CRITICAL " << numProcs << user << L" | procs=" << numProcs << L";" + << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl; + break; + } + + return state; +} + int countProcs() { + if (debug) + wcout << L"Counting all processes" << endl; + HANDLE hProcessSnap; PROCESSENTRY32 pe32; + if (debug) + wcout << L"Creating snapshot" << endl; + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) return -1; pe32.dwSize = sizeof(PROCESSENTRY32); + if (debug) + wcout << L"Grabbing first proccess" << endl; + if (!Process32First(hProcessSnap, &pe32)) { CloseHandle(hProcessSnap); return -1; @@ -212,16 +230,25 @@ int countProcs() int numProcs = 0; + if (debug) + wcout << L"Counting processes..." << endl; + do { ++numProcs; } while (Process32Next(hProcessSnap, &pe32)); + if (debug) + wcout << L"Found " << numProcs << L" processes. Cleaning up udn returning" << endl; + CloseHandle(hProcessSnap); return numProcs; } int countProcs(const wstring user) { + if (debug) + wcout << L"Counting all processes of user" << user << endl; + const wchar_t *wuser = user.c_str(); int numProcs = 0; @@ -232,16 +259,28 @@ int countProcs(const wstring user) SID_NAME_USE sidNameUse; LPWSTR AcctName, DomainName; + if (debug) + wcout << L"Creating snapshot" << endl; + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) goto die; pe32.dwSize = sizeof(PROCESSENTRY32); + if (debug) + wcout << L"Grabbing first proccess" << endl; + if (!Process32First(hProcessSnap, &pe32)) goto die; + if (debug) + wcout << L"Counting processes..." << endl; + do { + if (debug) + wcout << L"Getting process token" << endl; + //get ProcessToken hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) @@ -257,8 +296,14 @@ int countProcs(const wstring user) pSIDTokenUser = reinterpret_cast(new BYTE[dwReturnLength]); memset(pSIDTokenUser, 0, dwReturnLength); - if (!pSIDTokenUser) + if (!pSIDTokenUser) { + if (debug) + wcout << L"Could not recieve token, skiping" << endl; continue; + } + + if (debug) + wcout << L"Recieved token, saving information" << endl; //write Info in pSIDTokenUser if (!GetTokenInformation(hToken, TokenUser, pSIDTokenUser, dwReturnLength, NULL)) @@ -268,6 +313,10 @@ int countProcs(const wstring user) DomainName = NULL; dwAcctName = 1; dwDomainName = 1; + + if (debug) + wcout << L"Looking up SID" << endl; + //get dwAcctName and dwDomainName size if (!LookupAccountSid(NULL, pSIDTokenUser->User.Sid, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse) @@ -284,8 +333,13 @@ int countProcs(const wstring user) (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse)) continue; - if (!wcscmp(AcctName, wuser)) + if (debug) + wcout << L"Comparing " << AcctName << L" to " << wuser << endl; + if (!wcscmp(AcctName, wuser)) { ++numProcs; + if (debug) + wcout << L"Is process of " << wuser << L" (" << numProcs << L")" << endl; + } delete[] reinterpret_cast(AcctName); delete[] reinterpret_cast(DomainName); diff --git a/plugins/check_service.cpp b/plugins/check_service.cpp index 351adc8f4..7ade9c284 100644 --- a/plugins/check_service.cpp +++ b/plugins/check_service.cpp @@ -31,6 +31,8 @@ namespace po = boost::program_options; using std::wcout; using std::endl; using std::cout; using std::wstring; +static BOOL debug; + struct printInfoStruct { bool warn; @@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print help message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("service,s", po::wvalue(), "service to check (required)") ("warn,w", "return warning (1) instead of critical (2),\n when service is not running") ; @@ -132,12 +135,18 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo.warn = true; printInfo.service = vm["service"].as(); + + if (vm.count("debug")) + debug = TRUE; return -1; } int printOutput(const printInfoStruct& printInfo) { + if (debug) + wcout << L"Constructing output string" << endl; + wstring perf; state state = OK; @@ -166,6 +175,9 @@ int printOutput(const printInfoStruct& printInfo) int ServiceStatus(const printInfoStruct& printInfo) { + if (debug) + wcout << L"Opening SC Manager" << endl; + SC_HANDLE service_api = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if (service_api == NULL) goto die; @@ -174,6 +186,9 @@ int ServiceStatus(const printInfoStruct& printInfo) DWORD cbBufSize = 0; DWORD pcbBytesNeeded = NULL, ServicesReturned = NULL, ResumeHandle = NULL; + if (debug) + wcout << L"Creating service info structure" << endl; + if (!EnumServicesStatusEx(service_api, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, lpServices, cbBufSize, &pcbBytesNeeded, &ServicesReturned, &ResumeHandle, NULL) && GetLastError() != ERROR_MORE_DATA) @@ -188,16 +203,24 @@ int ServiceStatus(const printInfoStruct& printInfo) LPENUM_SERVICE_STATUS_PROCESS pInfo = (LPENUM_SERVICE_STATUS_PROCESS)lpServices; + if (debug) + wcout << L"Traversing services" << endl; + for (DWORD i = 0; i < ServicesReturned; i++) { + if (debug) + wcout << L"Comparing " << pInfo[i].lpServiceName << L" to " << printInfo.service << endl; + if (!wcscmp(printInfo.service.c_str(), pInfo[i].lpServiceName)) { + if (debug) + wcout << L"Service " << pInfo[i].lpServiceName << L" = " << printInfo.service << ". Returning" << endl; + int state = pInfo[i].ServiceStatusProcess.dwCurrentState; delete lpServices; return state; } } - return 0; delete[] reinterpret_cast(lpServices); - return -1; + return 0; die: die(); diff --git a/plugins/check_swap.cpp b/plugins/check_swap.cpp index 6889f9c94..4a8feb933 100644 --- a/plugins/check_swap.cpp +++ b/plugins/check_swap.cpp @@ -31,6 +31,8 @@ namespace po = boost::program_options; using std::endl; using std::wcout; using std::wstring; using std::cout; +static BOOL debug = FALSE; + struct printInfoStruct { threshold warn, crit; @@ -68,6 +70,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print help message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue(), "warning threshold") ("critical,c", po::wvalue(), "critical threshold") ; @@ -141,6 +144,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& return 3; } } + if (vm.count("critical")) { try { printInfo.crit = threshold(vm["critical"].as()); @@ -150,11 +154,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } } + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo) { + if (debug) + wcout << L"Constructing output string" << endl; + state state = OK; if (printInfo.warn.rend(printInfo.swap)) @@ -192,18 +202,30 @@ int check_swap(printInfoStruct& printInfo) LPCWSTR path = L"\\Paging File(*)\\% Usage"; + if (debug) + wcout << L"Opening querry handle" << endl; + err = PdhOpenQuery(NULL, NULL, &phQuery); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Adding counter" << endl; + err = PdhAddEnglishCounter(phQuery, path, NULL, &phCounter); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Collecting querry data" << endl; + err = PdhCollectQueryData(phQuery); if (!SUCCEEDED(err)) goto die; + if (debug) + wcout << L"Formatting counter data" << endl; + err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue); if (SUCCEEDED(err)) { printInfo.swap = DisplayValue.doubleValue; diff --git a/plugins/check_update.cpp b/plugins/check_update.cpp index 2d2930f25..67a7d867a 100644 --- a/plugins/check_update.cpp +++ b/plugins/check_update.cpp @@ -35,6 +35,8 @@ namespace po = boost::program_options; using std::wcout; using std::endl; using std::wstring; using std::cout; +static BOOL debug = FALSE; + struct printInfoStruct { BOOL warn, crit; @@ -46,10 +48,10 @@ static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&) static int printOutput(const printInfoStruct&); static int check_update(printInfoStruct&); -int main(int argc, wchar_t **argv) +int wmain(int argc, wchar_t **argv) { - po::variables_map vm; printInfoStruct printInfo = { FALSE, FALSE, 0, FALSE, FALSE, FALSE }; + po::variables_map vm; int ret = parseArguments(argc, argv, vm, printInfo); if (ret != -1) @@ -62,35 +64,6 @@ int main(int argc, wchar_t **argv) return printOutput(printInfo); } -int printOutput(const printInfoStruct& printInfo) -{ - state state = OK; - wstring output = L"UPDATE "; - - if (printInfo.important) - state = WARNING; - - if (printInfo.reboot) - state = CRITICAL; - - switch (state) { - case OK: - output.append(L"OK "); - break; - case WARNING: - output.append(L"WARNING "); - break; - case CRITICAL: - output.append(L"CRITICAL "); - break; - } - - wcout << output << printInfo.numUpdates << L" | update=" << printInfo.numUpdates << L";" - << printInfo.warn << L";" << printInfo.crit << L";0;" << endl; - - return state; -} - int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) { wchar_t namePath[MAX_PATH]; @@ -102,9 +75,10 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print help message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", "warn if there are important updates available") ("critical,c", "critical if there are important updates that require a reboot") - ("possible-reboot", "treat \"update may need to reboot\" as \"update needs to reboot\"") + ("possible-reboot", "treat \"update may need reboot\" as \"update needs reboot\"") ; po::basic_command_line_parser parser(ac, av); @@ -132,7 +106,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& cout << desc; wprintf( L"\nAfter some time, it will then output a string like this one:\n\n" - L"\tUPDATE WARNING 8|updates=8;1;1;0\n\n" + L"\tUPDATE WARNING 8 | updates=8;1;1;0\n\n" L"\"UPDATE\" being the type of the check, \"WARNING\" the returned status\n" L"and \"8\" is the number of important updates updates.\n" L"The performance data is found behind the \"|\", in order:\n" @@ -170,18 +144,56 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& if (vm.count("possible-reboot")) printInfo.careForCanRequest = TRUE; + if (vm.count("debug")) + debug = TRUE; + return -1; } +int printOutput(const printInfoStruct& printInfo) +{ + if (debug) + wcout << L"Constructing output string" << endl; + + state state = OK; + wstring output = L"UPDATE "; + + if (printInfo.important) + state = WARNING; + + if (printInfo.reboot) + state = CRITICAL; + + switch (state) { + case OK: + output.append(L"OK "); + break; + case WARNING: + output.append(L"WARNING "); + break; + case CRITICAL: + output.append(L"CRITICAL "); + break; + } + + wcout << output << printInfo.numUpdates << L" | update=" << printInfo.numUpdates << L";" + << printInfo.warn << L";" << printInfo.crit << L";0;" << endl; + + return state; +} + int check_update(printInfoStruct& printInfo) { + if (debug) + wcout << "Initializing COM library" << endl; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); ISearchResult *pResult; IUpdateSession *pSession; IUpdateSearcher *pSearcher; HRESULT err; - + if (debug) + wcout << "Creating UpdateSession and UpdateSearcher" << endl; CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&pSession); pSession->CreateUpdateSearcher(&pSearcher); @@ -196,6 +208,9 @@ int check_update(printInfoStruct& printInfo) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa386526%28v=vs.85%29.aspx // http://msdn.microsoft.com/en-us/library/ff357803%28v=vs.85%29.aspx + if (debug) + wcout << L"Querrying updates from server" << endl; + err = pSearcher->Search(criteria, &pResult); if (!SUCCEEDED(err)) goto die; @@ -212,30 +227,40 @@ int check_update(printInfoStruct& printInfo) return -1; printInfo.numUpdates = updateSize; - printInfo.important = printInfo.warn; - - if (!printInfo.crit) - return -1; +// printInfo.important = printInfo.warn; IInstallationBehavior *pIbehav; InstallationRebootBehavior updateReboot; for (LONG i = 0; i < updateSize; i++) { pCollection->get_Item(i, &pUpdate); + if (debug) { + wcout << L"Checking reboot behaviour of update number " << i << endl; + } pUpdate->get_InstallationBehavior(&pIbehav); pIbehav->get_RebootBehavior(&updateReboot); if (updateReboot == irbAlwaysRequiresReboot) { printInfo.reboot = TRUE; + if (debug) + wcout << L"It requires reboot" << endl; continue; } if (printInfo.careForCanRequest && updateReboot == irbCanRequestReboot) + if (debug) + wcout << L"It requires reboot" << endl; printInfo.reboot = TRUE; } + if (debug) + wcout << L"Cleaning up and returning" << endl; + + SysFreeString(criteria); + CoUninitialize(); return 0; die: die(err); + CoUninitialize(); if (criteria) SysFreeString(criteria); return 3; diff --git a/plugins/check_uptime.cpp b/plugins/check_uptime.cpp index 9dcaa1182..82faf1ce9 100644 --- a/plugins/check_uptime.cpp +++ b/plugins/check_uptime.cpp @@ -32,6 +32,8 @@ namespace po = boost::program_options; using std::cout; using std::endl; using std::wcout; using std::wstring; +static BOOL debug; + struct printInfoStruct { threshold warn, crit; @@ -70,6 +72,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& ("help,h", "print help message and exit") ("version,V", "print version and exit") ("warning,w", po::wvalue(), "warning threshold (Uses -unit)") + ("debug,d", "Verbose/Debug output") ("critical,c", po::wvalue(), "critical threshold (Uses -unit)") ("unit,u", po::wvalue(), "desired unit of output\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds") ; @@ -164,12 +167,18 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } wcout << L"Unknown unit type " << vm["unit"].as() << endl; } else printInfo.unit = TunitS; + + if (vm.count("debug")) + debug = TRUE; return -1; } static int printOutput(printInfoStruct& printInfo) { + if (debug) + wcout << L"Constructing output string" << endl; + state state = OK; if (printInfo.warn.rend(printInfo.time)) @@ -200,8 +209,14 @@ static int printOutput(printInfoStruct& printInfo) void getUptime(printInfoStruct& printInfo) { + if (debug) + wcout << L"Getting uptime in milliseconds" << endl; + boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64()); + if (debug) + wcout << L"Converting requested unit (default: seconds)" << endl; + switch (printInfo.unit) { case TunitH: printInfo.time = boost::chrono::duration_cast(uptime).count(); @@ -216,5 +231,4 @@ void getUptime(printInfoStruct& printInfo) printInfo.time = uptime.count(); break; } - } \ No newline at end of file diff --git a/plugins/check_users.cpp b/plugins/check_users.cpp index 6cab0970c..0f23e415a 100644 --- a/plugins/check_users.cpp +++ b/plugins/check_users.cpp @@ -32,6 +32,8 @@ namespace po = boost::program_options; using std::endl; using std::wcout; using std::cout; using std::wstring; +static BOOL debug = FALSE; + struct printInfoStruct { threshold warn, crit; @@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& desc.add_options() ("help,h", "print help message and exit") ("version,V", "print version and exit") + ("debug,d", "Verbose/Debug output") ("warning,w", po::wvalue(), "warning threshold") ("critical,c", po::wvalue(), "critical threshold") ; @@ -98,7 +101,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& cout << desc; wprintf( L"\nIt will then output a string looking something like this:\n\n" - L"\tUSERS WARNING 48|users=48;10;50;0\n\n" + L"\tUSERS WARNING 48 | users=48;10;50;0\n\n" L"\"USERS\" being the type of the check, \"WARNING\" the returned status\n" L"and \"48\" is the returned value.\n" L"The performance data is found behind the \"|\", in order:\n" @@ -151,11 +154,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& } } + if (vm.count("debug")) + debug = TRUE; + return -1; } int printOutput(printInfoStruct& printInfo) { + if (debug) + wcout << L"Constructing output string" << endl; + state state = OK; if (printInfo.warn.rend(printInfo.users)) @@ -189,33 +198,52 @@ int check_users(printInfoStruct& printInfo) DWORD count; DWORD index; + if (debug) + wcout << L"Trying to enumerate terminal sessions" << endl; + if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &count)) { wcout << L"Failed to enumerate terminal sessions" << endl; + die(); if (pSessionInfo) WTSFreeMemory(pSessionInfo); return 3; } + if (debug) + wcout << L"Got all sessions (" << count << L"), traversing and counting active ones" << endl; + for (index = 0; index < count; index++) { LPWSTR name; DWORD size; int len; + if (debug) + wcout << L"Querrying session number " << index << endl; + if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pSessionInfo[index].SessionId, WTSUserName, &name, &size)) continue; + if (debug) + wcout << L"Found \"" << name << L"\". Checking whether it's a real session" << endl; + len = lstrlenW(name); WTSFreeMemory(name); if (!len) continue; - - if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) + + if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) { users++; + if (debug) + wcout << L"\"" << name << L"\" is a real session, counting it. Now " << users << endl; + } } + if (debug) + wcout << "Finished coutning user sessions (" << users << "). Freeing memory and returning" << endl; + WTSFreeMemory(pSessionInfo); printInfo.users = users; return -1; -- 2.50.1