Make check plugins decent

fixes #7242
This commit is contained in:
Jean Flach 2014-11-06 16:36:42 +01:00
parent ea8fd12a07
commit 83e6fb3083
12 changed files with 408 additions and 140 deletions

View File

@ -1,17 +1,26 @@
##icinga 2 plugins for Windows##
##Icinga 2 plugins for Windows##
Thhis collection of plugins is intended to provide basic functinality checks on windows machines. They (mostly) conform to the [nagios developer guidelines](https://nagios-plugins.org/doc/guidelines.html), returning adequate exit codes and printing a pertinent string with performance data.
###Intallation###
//TODO
The plugins are installed as part of Icinga 2
###Requirements###
- Boost 1.41.0
- Windows Vista, Windows Server 2008 or newer
- C99 ?
###Usage###
Call a plugin with the "--help" option to recive information about its usage.
###License###
gnu stuff
//todo
Icinga 2
Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org)
This program is free software; you can redistribute it and/or modify it under the tems of the GNU General Public License as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <set>
#include <Shlwapi.h>
@ -16,7 +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;
struct drive {
struct drive
{
wstring name;
double cap, free;
drive(wstring p)
@ -24,7 +43,8 @@ struct drive {
{}
};
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
vector<wstring> drives;
Bunit unit;
@ -58,9 +78,8 @@ int wmain(int argc, wchar_t **argv)
return ret;
for (vector<drive>::iterator it = vDrives.begin(); it != vDrives.end(); ++it) {
if (!getFreeAndCap(*it, printInfo.unit)) {
if (!getFreeAndCap(*it, printInfo.unit))
return 3;
}
}
return printOutput(printInfo, vDrives);
@ -96,9 +115,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -116,14 +133,14 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"23.8304%%\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value. Performance data will onl be displayed when\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n"
L"This program will also print out additional performance data disk by disk\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L"%s' exit codes denote the following:\n\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -163,11 +180,16 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
if (vm.count("drives"))
printInfo.drives = vm["drives"].as<vector<wstring>>();
if (vm.count("unit"))
printInfo.unit = parseBUnit(vm["unit"].as<wstring>().c_str());
else {
if (vm.count("unit")) {
try {
printInfo.unit = parseBUnit(vm["unit"].as<wstring>().c_str());
} catch (std::invalid_argument) {
wcout << L"Unknown unit Type " << vm["unit"].as<wstring>() << endl;
return 3;
}
} else
printInfo.unit = BunitB;
}
return -1;
}
@ -185,6 +207,7 @@ int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"DISK OK " << tFree << unit << endl;
return 0;
}
prePerf << L"|disk=" << tFree << unit << L";" << printInfo.warn.pString() << L";"
@ -197,6 +220,7 @@ int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
if (printInfo.warn.rend(tFree))
state = WARNING;
}
if (printInfo.crit.perc) {
if (printInfo.crit.rend((tFree / tCap) * 100.0))
state = CRITICAL;
@ -205,8 +229,6 @@ int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
state = CRITICAL;
}
switch (state) {
case OK:
wcout << L"DISK OK " << tFree << unit << prePerf.str() << perf.str() << endl;

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Pdh.h>
#include <Shlwapi.h>
#include <pdhmsg.h>
@ -14,7 +32,8 @@ namespace po = boost::program_options;
using std::endl; using std::cout; using std::wstring;
using std::wcout;
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
double load;
};
@ -23,7 +42,8 @@ static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&)
static int printOutput(printInfoStruct&);
static int check_load(printInfoStruct&);
int wmain(int argc, wchar_t **argv) {
int wmain(int argc, wchar_t **argv)
{
printInfoStruct printInfo{ };
po::variables_map vm;
@ -66,9 +86,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -91,13 +109,13 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"67%%\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value. Performance data will onl be displayed when\n"
L"you set at least one threshold\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -131,11 +149,12 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int printOutput(printInfoStruct& printInfo) {
int printOutput(printInfoStruct& printInfo)
{
state state = OK;
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"LOAD OK " << printInfo.load << endl;
wcout << L"LOAD OK " << printInfo.load << L"%" << endl;
}
if (printInfo.warn.rend(printInfo.load))
@ -163,7 +182,8 @@ int printOutput(printInfoStruct& printInfo) {
return state;
}
int check_load(printInfoStruct& printInfo) {
int check_load(printInfoStruct& printInfo)
{
PDH_HQUERY phQuery;
PDH_HCOUNTER phCounter;
DWORD dwBufferSize = 0;

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <Pdh.h>
#include <Shlwapi.h>
@ -13,7 +31,8 @@ namespace po = boost::program_options;
using std::endl; using std::vector; using std::wstring;
using std::wcout; using std::cout;
struct nInterface {
struct nInterface
{
wstring name;
long BytesInSec, BytesOutSec;
nInterface(wstring p)
@ -21,7 +40,8 @@ struct nInterface {
{}
};
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
};
@ -30,7 +50,8 @@ static int parseArguments(int, TCHAR **, po::variables_map&, printInfoStruct&);
static int printOutput(printInfoStruct&, const vector<nInterface>&);
static int check_network(vector<nInterface>&);
int wmain(int argc, wchar_t **argv) {
int wmain(int argc, wchar_t **argv)
{
vector<nInterface> vInterfaces;
printInfoStruct printInfo{ };
po::variables_map vm;
@ -46,7 +67,8 @@ int wmain(int argc, wchar_t **argv) {
return 1;
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -73,9 +95,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -98,15 +118,15 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"1131B/s\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value. Performance data will onl be displayed when\n"
L"you set at least one threshold\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"This program will also print out additional performance data interface\n"
L"by interface\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -140,7 +160,8 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int printOutput(printInfoStruct& printInfo, const vector<nInterface>& vInterfaces) {
int printOutput(printInfoStruct& printInfo, const vector<nInterface>& vInterfaces)
{
long tIn = 0, tOut = 0;
std::wstringstream tss;
state state = OK;
@ -175,7 +196,8 @@ int printOutput(printInfoStruct& printInfo, const vector<nInterface>& vInterface
return state;
}
int check_network(vector <nInterface>& vInterfaces) {
int check_network(vector <nInterface>& vInterfaces)
{
const wchar_t *perfIn = L"\\Network Interface(*)\\Bytes Received/sec";
const wchar_t *perfOut = L"\\Network Interface(*)\\Bytes Sent/sec";
@ -187,6 +209,7 @@ int check_network(vector <nInterface>& vInterfaces) {
if (PdhOpenQuery(NULL, NULL, &phQuery) != ERROR_SUCCESS)
goto die;
//Totaly reasonable statement
if (PdhOpenQuery(NULL, NULL, &phQuery) == ERROR_SUCCESS) {
if (PdhAddEnglishCounter(phQuery, perfIn, NULL, &phCounterIn) == ERROR_SUCCESS) {
if (PdhAddEnglishCounter(phQuery, perfOut, NULL, &phCounterOut) == ERROR_SUCCESS) {
@ -222,7 +245,8 @@ die:
return 3;
}
void die(DWORD err) {
void die(DWORD err)
{
if (!err)
err = GetLastError();
LPWSTR mBuf = NULL;

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <tlhelp32.h>
@ -14,7 +32,8 @@ namespace po = boost::program_options;
using std::endl; using std::wstring; using std::wcout;
using std::cout;
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
wstring user;
};
@ -24,12 +43,13 @@ static int countProcs(const wstring);
static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&);
static int printOutput(const int, printInfoStruct&);
int wmain(int argc, wchar_t **argv) {
int wmain(int argc, wchar_t **argv)
{
po::variables_map vm;
printInfoStruct printInfo = { };
int r = parseArguments(argc, argv, vm, printInfo);
if (r != -1)
return r;
@ -39,11 +59,13 @@ int wmain(int argc, wchar_t **argv) {
return printOutput(countProcs(), printInfo);
}
int printOutput(const int numProcs, printInfoStruct& printInfo) {
int printOutput(const int numProcs, printInfoStruct& printInfo)
{
state state = OK;
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"PROCS OK " << numProcs << endl;
return 0;
}
if (printInfo.warn.rend(numProcs))
@ -52,9 +74,8 @@ int printOutput(const int numProcs, printInfoStruct& printInfo) {
if (printInfo.crit.rend(numProcs))
state = CRITICAL;
switch (state)
{
case OK:
switch (state) {
case OK:
wcout << L"PROCS OK " << numProcs << L"|procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0" << endl;
break;
@ -71,7 +92,8 @@ int printOutput(const int numProcs, printInfoStruct& printInfo) {
return state;
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -99,9 +121,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
std::cout << e.what() << endl << desc << endl;
return 3;
}
@ -110,6 +130,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
std::cout << desc << endl;
return 0;
}
if (vm.count("help")) {
wcout << progName << " Help\n\tVersion: " << VERSION << endl;
wprintf(
@ -123,14 +144,14 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"67\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value. Performance data will onl be displayed when\n"
L"you set at least one threshold\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"For \"-user\" option keep in mind you need root to see other users processes\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -151,6 +172,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << endl;
return 0;
}
if (vm.count("version")) {
std::cout << "Version: " << VERSION << endl;
return 0;
@ -168,7 +190,8 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int countProcs() {
int countProcs()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
@ -193,7 +216,8 @@ int countProcs() {
return numProcs;
}
int countProcs(const wstring user) {
int countProcs(const wstring user)
{
const wchar_t *wuser = user.c_str();
int numProcs = 0;
@ -217,18 +241,18 @@ int countProcs(const wstring user) {
do {
//get ProcessToken
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
//Won't count pid 0 (system idle) and 4/8 (Sytem)
continue;
}
//Get dwReturnLength in first call
dwReturnLength = 1;
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwReturnLength)
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER)
continue;
}
pSIDTokenUser = (PTOKEN_USER)new BYTE[dwReturnLength];
memset(pSIDTokenUser, 0, dwReturnLength);
@ -260,9 +284,9 @@ int countProcs(const wstring user) {
(LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse))
continue;
if (!wcscmp(AcctName, wuser)) {
if (!wcscmp(AcctName, wuser))
++numProcs;
}
} while (Process32Next(hProcessSnap, &pe32));

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <iostream>
@ -13,7 +31,8 @@ namespace po = boost::program_options;
using std::wcout; using std::endl;
using std::cout; using std::wstring;
struct printInfoStruct {
struct printInfoStruct
{
bool warn;
int ServiceState;
wstring service;
@ -39,7 +58,8 @@ int wmain(int argc, wchar_t **argv)
return printOutput(printInfo);
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -51,7 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
("help", "print verbose help and exit")
("version,v", "print version and exit")
("service,s", po::wvalue<wstring>(), "service to check (required)")
("warn,w", "return warning (1) instead of critical (2)\n when service is not running")
("warn,w", "return warning (1) instead of critical (2),\n when service is not running")
;
po::basic_command_line_parser<wchar_t> parser(ac, av);
@ -69,11 +89,13 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
}
if (vm.count("h")) {
cout << desc << endl;
return 0;
}
}
if (vm.count("help")) {
wcout << progName << " Help\n\tVersion: " << VERSION << endl;
wprintf(
@ -82,19 +104,16 @@ 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"\tSERVICE CRITICAL NOT_RUNNING|service=1;-1;!4;1;7\n\n"
L"\tSERVICE CRITICAL NOT_RUNNING\n\n"
L"\"SERVICE\" being the type of the check, \"CRITICAL\" the returned status\n"
L"and \"1\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value.\n"
L"A service is either running (Code 0x04) or not running (any other).\n"
L"For more information consult the msdn on service state transitions.\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"%s' thresholds work differently, since a service is either running or not\n"
L"all \"-w\" and \"-c\" do is say whether a not running service is a warning\n"
L"or critical state respectively.\n"
@ -102,10 +121,13 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << endl;
return 0;
}
if (vm.count("version")) {
cout << "Version: " << VERSION << endl;
return 0;
} if (!vm.count("service")) {
}
if (!vm.count("service")) {
cout << "Missing argument: service" << endl << desc << endl;
return 3;
}
@ -118,31 +140,31 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int printOutput(const printInfoStruct& printInfo) {
int printOutput(const printInfoStruct& printInfo)
{
wstring perf;
state state = OK;
if (printInfo.ServiceState != 0x04)
printInfo.warn ? state = WARNING : state = CRITICAL;
printInfo.warn ? perf.append(L"!4;-1;1;7") : perf.append(L"-1;!4;1;7");
switch (state) {
case OK:
wcout << L"SERVICE OK RUNNING|service=4;" << perf << endl;
wcout << L"SERVICE OK RUNNING" << endl;
break;
case WARNING:
wcout << L"SERVICE WARNING NOT_RUNNING|service=" << printInfo.ServiceState << perf << endl;
wcout << L"SERVICE WARNING NOT_RUNNING" << endl;
break;
case CRITICAL:
wcout << L"SERVICE CRITICAL NOT_RUNNING|service=" << printInfo.ServiceState << perf << endl;
wcout << L"SERVICE CRITICAL NOT_RUNNING" << endl;
break;
}
return state;
}
int ServiceStatus(const printInfoStruct& printInfo) {
int ServiceStatus(const printInfoStruct& printInfo)
{
SC_HANDLE service_api = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
if (service_api == NULL)
goto die;
@ -168,8 +190,8 @@ int ServiceStatus(const printInfoStruct& printInfo) {
goto die;
LPENUM_SERVICE_STATUS_PROCESS pInfo = (LPENUM_SERVICE_STATUS_PROCESS)lpServices;
for (DWORD i = 0; i< *lpServicesReturned; i++)
{
for (DWORD i = 0; i< *lpServicesReturned; i++) {
if (!wcscmp(printInfo.service.c_str(), pInfo[i].lpServiceName))
return pInfo[i].ServiceStatusProcess.dwCurrentState;
}

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Shlwapi.h>
#include <Pdh.h>
#include <iostream>
@ -13,7 +31,8 @@ namespace po = boost::program_options;
using std::endl; using std::wcout; using std::wstring;
using std::cout;
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
double swap;
};
@ -22,7 +41,8 @@ static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&)
static int printOutput(printInfoStruct&);
static int check_swap(printInfoStruct&);
int wmain(int argc, wchar_t **argv) {
int wmain(int argc, wchar_t **argv)
{
printInfoStruct printInfo = { };
po::variables_map vm;
@ -37,7 +57,8 @@ int wmain(int argc, wchar_t **argv) {
return printOutput(printInfo);
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -64,9 +85,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -75,6 +94,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc << endl;
return 0;
}
if (vm.count("help")) {
wcout << progName << " Help\n\tVersion: " << VERSION << endl;
wprintf(
@ -88,12 +108,13 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"23.8304%%\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value.\n\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -127,9 +148,15 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int printOutput(printInfoStruct& printInfo) {
int printOutput(printInfoStruct& printInfo)
{
state state = OK;
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"SWAP OK " << printInfo.swap << L"%" << endl;
return 0;
}
if (printInfo.warn.rend(printInfo.swap))
state = WARNING;
@ -154,7 +181,8 @@ int printOutput(printInfoStruct& printInfo) {
return state;
}
int check_swap(printInfoStruct& printInfo) {
int check_swap(printInfoStruct& printInfo)
{
PDH_HQUERY phQuery;
PDH_HCOUNTER phCounter;
DWORD dwBufferSize = 0;

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <windows.h>
#include <Shlwapi.h>
#include <iostream>
@ -17,7 +35,8 @@ namespace po = boost::program_options;
using std::wcout; using std::endl;
using std::wstring; using std::cout;
struct printInfoStruct {
struct printInfoStruct
{
BOOL warn, crit;
LONG numUpdates;
BOOL important, reboot, careForCanRequest;
@ -48,14 +67,18 @@ int printOutput(const printInfoStruct& printInfo)
state state = OK;
wstring output = L"UPDATE ";
if (!printInfo.warn && !printInfo.crit) {
wcout << L"UPDATE OK " << printInfo.numUpdates << endl;
return 0;
}
if (printInfo.important)
state = WARNING;
if (printInfo.reboot)
state = CRITICAL;
switch (state)
{
switch (state) {
case OK:
output.append(L"OK ");
break;
@ -69,6 +92,7 @@ int printOutput(const printInfoStruct& printInfo)
wcout << output << printInfo.numUpdates << L"|update=" << printInfo.numUpdates << L";"
<< printInfo.warn << L";" << printInfo.crit << L";0" << endl;
return state;
}
@ -101,9 +125,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -112,6 +134,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc << endl;
return 0;
}
if (vm.count("help")) {
wcout << progName << " Help\n\tVersion: " << VERSION << endl;
wprintf(
@ -125,15 +148,16 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"8\" is the number of important updates updates.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value.\n\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"An update counts as important when it is part of the Security- or\n"
L"CriticalUpdates group.\n"
L"Consult the msdn on WSUS Classification GUIDs for more information.\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"%s works different from other plugins in that you do not set thresholds\n"
L"but only activate them. Using \"-w\" triggers warning state if there are not\n"
L"installed and non-optional updates. \"-c\" triggers critical if there are\n"
@ -205,8 +229,7 @@ int check_update(printInfoStruct& printInfo)
IInstallationBehavior *pIbehav;
InstallationRebootBehavior updateReboot;
for (LONG i = 0; i < updateSize; i++)
{
for (LONG i = 0; i < updateSize; i++) {
pCollection->get_Item(i, &pUpdate);
pUpdate->get_InstallationBehavior(&pIbehav);
pIbehav->get_RebootBehavior(&updateReboot);

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <iostream>
@ -14,7 +32,8 @@ namespace po = boost::program_options;
using std::cout; using std::endl;
using std::wcout; using std::wstring;
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
long long time;
Tunit unit;
@ -39,7 +58,8 @@ int main(int argc, wchar_t **argv)
return printOutput(printInfo);
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -52,7 +72,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
("version,v", "print version and exit")
("warning,w", po::wvalue<wstring>(), "warning threshold (Uses -unit)")
("critical,c", po::wvalue<wstring>(), "critical threshold (Uses -unit)")
("unit,u", po::wvalue<wstring>(), "desired unit of output\nh - hours\nm - minutes\ns - seconds (default)\nms - milliseconds")
("unit,u", po::wvalue<wstring>(), "desired unit of output\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds")
;
po::basic_command_line_parser<wchar_t> parser(ac, av);
@ -67,8 +87,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -91,14 +110,15 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"712h\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value.\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"Note that the returned time ins always rounded down,\n"
L"4 hours and 44 minutes will show as 4h.\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -132,15 +152,26 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
printInfo.crit = parse(vm["critical"].as<wstring>());
if (vm.count("unit")) {
printInfo.unit = parseTUnit(vm["unit"].as<wstring>().c_str());
} else {
try{
printInfo.unit = parseTUnit(vm["unit"].as<wstring>().c_str());
} catch (std::invalid_argument) {
} wcout << L"Unknown unit type " << vm["unit"].as<wstring>() << endl;
} else
printInfo.unit = TunitS;
}
return -1;
}
static int printOutput(printInfoStruct& printInfo) {
static int printOutput(printInfoStruct& printInfo)
{
state state = OK;
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"UPTIME OK " << printInfo.time << TunitStr(printInfo.unit) << endl;
return 0;
}
if (printInfo.warn.rend(printInfo.time))
state = WARNING;
if (printInfo.crit.rend(printInfo.time))
@ -167,7 +198,8 @@ static int printOutput(printInfoStruct& printInfo) {
return state;
}
void getUptime(printInfoStruct& printInfo) {
void getUptime(printInfoStruct& printInfo)
{
boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64());
switch (printInfo.unit) {

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <wtsapi32.h>
@ -14,7 +32,8 @@ namespace po = boost::program_options;
using std::endl; using std::wcout;
using std::cout; using std::wstring;
struct printInfoStruct {
struct printInfoStruct
{
threshold warn, crit;
int users;
};
@ -23,7 +42,8 @@ static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&)
static int printOutput(printInfoStruct&);
static int check_users(printInfoStruct&);
int wmain(int argc, wchar_t **argv) {
int wmain(int argc, wchar_t **argv)
{
printInfoStruct printInfo = { };
po::variables_map vm;
@ -38,7 +58,8 @@ int wmain(int argc, wchar_t **argv) {
return printOutput(printInfo);
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) {
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath);
@ -65,9 +86,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
.run(),
vm);
vm.notify();
}
catch (std::exception& e) {
} catch (std::exception& e) {
cout << e.what() << endl << desc << endl;
return 3;
}
@ -76,6 +95,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc << endl;
return 0;
}
if (vm.count("help")) {
wcout << progName << " Help\n\tVersion: " << VERSION << endl;
wprintf(
@ -89,12 +109,13 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
L"and \"48\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
L"returned value, warning threshold, critical threshold, minimal value and,\n"
L"if applicable, the maximal value.\n\n"
L"if applicable, the maximal value. Performance data will only be displayed when\n"
L"you set at least one threshold\n\n"
L"%s' exit codes denote the following:\n"
L" 0\tOK,\n\tno Thresholds were broken or the programs check part was not executed\n"
L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tThe programme experienced an internal or input error\n\n"
L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
L"Threshold syntax:\n\n"
L"-w THRESHOLD\n"
L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
@ -128,9 +149,15 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return -1;
}
int printOutput(printInfoStruct& printInfo) {
int printOutput(printInfoStruct& printInfo)
{
state state = OK;
if (!printInfo.warn.set && !printInfo.crit.set) {
wcout << L"USERS OK " << printInfo.users << endl;
return 0;
}
if (printInfo.warn.rend(printInfo.users))
state = WARNING;
@ -155,7 +182,8 @@ int printOutput(printInfoStruct& printInfo) {
return state;
}
int check_users(printInfoStruct& printInfo) {
int check_users(printInfoStruct& printInfo)
{
int users = 0;
WTS_SESSION_INFOW *pSessionInfo;
DWORD count;

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include <vector>
#include "thresholds.h"

View File

@ -1,3 +1,21 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef THRESHOLDS_H
#define THRESHOLDS_H
#include <string>