Rev 55 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 55 | Rev 59 | ||
---|---|---|---|
1 | <?php /* <ViaThinkSoftSignature> |
1 | <?php /* <ViaThinkSoftSignature> |
2 | ogeU7sU9og0Wo32ZGa8L9wIY+V280zVqPOo8/wFGNLcjhWISQDQiY/6hyvIb0IODQ |
2 | QoZ88Uk+0bsqwHYjMZ5dp5xPx6r1En9+loEwswsXD8grSVXtxqkcuW/iu7bJNusTk |
3 | 7GQ2eU7C0QiTPiaMy7C1H9EXqhoCyKtDqTtkXso2KCYTNqkUtcna/UjX12mZwvQ89 |
3 | aufV9B2vIRXketty/Elm2F19KtbS9egj8AWXQ76RUfJ7hDVdzfvABjKxpLxNzb1SN |
4 | ltvtnRJeC1OXO1XcwE0/L1XZlo68dYSvgmufJQheVYAj9uU7PW9sb2YH+WTK8BM2M |
4 | wn3Fa2t3V4Li/UEJlSoNUtmMSWYpULwwpBQeZPjCtF6iRwP6nUgFQczREnuYKDO7W |
5 | JUHn+JdLnY9QUlOLp6bVYXJqDxqzj81uHGH5oXnhrqvsKvd8CrhUwy2X6fCpWgyId |
5 | S43iFGwAQPHZ3UgGQDxO3EBNZn5SzzgngwhIegSYVKVV2oQjUHD0Qnp7lDaJIwlE0 |
6 | S46OaEpBykHYdPIwFo04G3HfIyeWCQxnOIcxBbeuz1jee48I5BHFJczmkpYerE/Ao |
6 | 4vq2Mo/TiltvtryEiwn6xJbs67+qtC8FdJKIzy+q6TnHN122Zrk+qwoL6MqlFhvXv |
7 | V0zlIF7cXWvSNn2XVC9+AyfDIA/BmtafqkOnDKHNrVmsQHx0QBL++C6ZoooE78ArT |
7 | mMHtf5bc/0+4BpT30EjNtHWpDmDae9uFO0fjeotMGAnhG/FAHqiRvHPYL62xyG+of |
8 | rkmjPLr8uK896O1qEppZ67rWDRdsZNMQIpk9QDS4PM6SQn6dfawxYxWA12h6+iFOB |
8 | 3kooFcSVXYcFjAnIWMoGSOl7VcJ4yRgO3sW6atLQmSQG5vEBTP9ZzLXbd6NDSxuVa |
9 | vuYVdNL17sZABPbpGqhnJCNS6e/nHgeym6b5XVuN+d8u+R6Fm7SPj6VttIDgF9Ux6 |
9 | 5Sse9JGELVW+tAUJux99LpMveKi37X6frXJyPcVdrsz68vqtQrTOwKq5yZ3dEfAVM |
10 | vBgpF+v9hSdgbup9ClFX1XJGsTmwS4PWB667oJdBCyHpzyvkpvw8VY/wAIKlkEdD+ |
10 | H6sjhMh4tGCVI88jak6TbRIzNgae0xT0BegBE5sxYxA5+ZmwqBuFNYmUtm1rsv/Q1 |
11 | O2lRasjrVrvNGp8LlBWlheMwEexhS2tmCZ6W+oP21puOsKhtCZD5a0PWjd/Oyo5bD |
11 | SQy+i8uvS7DdVo29ZD/+hn3ebocOx8GEA5jXzJtKik3IgGHlLF5XFycoRbSt72z2/ |
12 | DKlbuNs4pXokF5C0nVyHH8H/6BGGdRmTwUc64dE5RrSZlRi+2PvCJsAGzJeIagsVc |
12 | Ik6PK4osg2gQnTUY0++XLdGejEg3Mja+aOvSyXDd+gJbT3ed1Fsv6CXmIa2cmt82c |
13 | BrDl7uNe84b9sBJlJtIiWulE7pxg6wwk9dcSznUEzEsq/LnpKANxv4l8kCckP1BoI |
13 | P2YbR/Eqbxu22lKXVq0iqnN2vigtOvUIHey4Mi/A0zzCYBARBzMMzlahJQH5R24ub |
14 | yA4FahIjnsByB4vpV+zwX59DxVtmZH4nNigtZIL9j5cEjgb5XHwYDyh/nlStEj8FL |
14 | y63OylvBLtuu66PWB1ebZnnPLEzBdU5YzFiHkS+xTgDqjNB4BlTGmHwGbFujWUcwi |
15 | wHJ0YMnYuItDuiW2j1ZBCj/ZemKJNHDjLtlo9QOsIWrcKgm/CRO/08WMt62CL4GvJ |
15 | JKUbPBjFguVetaedI6kMe5D6BMdK+UBk+rhV3M7u0r/nV6S0RqK0tOKZSmZMhiECn |
16 | gqvRGbkZKuJMQTBkSxR9Ex6MyzhknWokHVV3xAWAb62B6wILFtWAYVgAgzcERr+Qd |
16 | GKgMPVoiroN+DLSC6dlc/uVMdLD6pJHmcNht8ExAwe214w9Afr/uNCkrpJBX/B3gu |
17 | suffXc41q5xjx1jpBkgCN26wj96fPu+jeKHS3/m/ck4PLNsWwicNGOS/uppJTb8d+ |
17 | sLtBmAlXXUiHCXzD+uN1/QK1ZG5npIgPodDouWDg8nSnokK4XcxqqpfnUSk67qeu7 |
18 | FvNy7yTk4E91H9ui4Us6RzoqbRT+Z8EQQqBl5nLkzqNzNN4gMgBNvICfsWBNJbHpY |
18 | r0wIFCRCLyBceUAeGSZyqgQyP8wZ6A6+9+or/jey0E/pCDUhqB5gjVyYrp8UNG54X |
19 | enq7LIYYfqBISDJ5WcWw/Z51e3z8Uk9TOOBNkcpRyjUe/F1Q3bhRLrz/eeXnBzkG0 |
19 | EHv/hM6EnaoZwbOptxKkVwkzXrT1Fj2W6BfnFme6xSqSi7MkkDpfsVoNYqamabWGp |
20 | 7Cji5xIasOO6qkgZSbcNqqvQ0chkrfOgB2FnsT8WUFIYtLaJOXHV/r0VGbTFhOTSv |
20 | A6Pn/wW4XdJdoUOZ4hVR433AnQl0Yl9u2qQwUO/nFtNYPSxitH6h8CMjN0A1OzZje |
21 | 2968Q3wsFxstk8DlKtWgl3LeYb2ECvNPFM5iZrisvx8EGcZNp2xJDniE9xorfKJTl |
21 | IBUfyPrItQhMAUYBOewxXhqbRF0NrNxW7zHBtDn7jmZnJFzM0d0JGmTvBIwVr5nxD |
22 | Gh43qnLC0djTq+mIp8V2fP8QqK8MoSxPiowJIyzXUCD2YOppdiYeaFdqXyZioy9wJ |
22 | OxPQ+uJpangO69Nx1KTWTlwmav8V3lfcS2rJrh0s8N+A7CBgZ+YqdCgga6mt+JEMe |
23 | Q== |
23 | Q== |
24 | </ViaThinkSoftSignature> */ ?> |
24 | </ViaThinkSoftSignature> */ ?> |
25 | <?php |
25 | <?php |
26 | 26 | ||
27 | /* |
27 | /* |
28 | 28 | ||
29 | VNag - Nagios Framework for PHP (C) 2014-2022 |
29 | VNag - Nagios Framework for PHP (C) 2014-2022 |
30 | __ ___ _____ _ _ _ ____ __ _ |
30 | __ ___ _____ _ _ _ ____ __ _ |
31 | \ \ / (_) __ |_ _| |__ (_)_ __ | | __/ ___| ___ / _| |_ |
31 | \ \ / (_) __ |_ _| |__ (_)_ __ | | __/ ___| ___ / _| |_ |
32 | \ \ / /| |/ _` || | | '_ \| | '_ \| |/ /\___ \ / _ \| |_| __| |
32 | \ \ / /| |/ _` || | | '_ \| | '_ \| |/ /\___ \ / _ \| |_| __| |
33 | \ V / | | (_| || | | | | | | | | | < ___) | (_) | _| |_ |
33 | \ V / | | (_| || | | | | | | | | | < ___) | (_) | _| |_ |
34 | \_/ |_|\__,_||_| |_| |_|_|_| |_|_|\_\|____/ \___/|_| \__| |
34 | \_/ |_|\__,_||_| |_| |_|_|_| |_|_|\_\|____/ \___/|_| \__| |
35 | 35 | ||
36 | Developed by Daniel Marschall www.viathinksoft.com |
36 | Developed by Daniel Marschall www.viathinksoft.com |
37 | Licensed under the terms of the Apache 2.0 license |
37 | Licensed under the terms of the Apache 2.0 license |
38 | Revision 2022-06-06 |
38 | Revision 2022-12-18 |
39 | 39 | ||
40 | */ |
40 | */ |
41 | 41 | ||
42 | /**************************************************************************************************** |
42 | /**************************************************************************************************** |
43 | 43 | ||
44 | Introduction: |
44 | Introduction: |
45 | 45 | ||
46 | VNag is a small framework for Nagios Plugin Developers who use PHP CLI scripts. |
46 | VNag is a small framework for Nagios Plugin Developers who use PHP CLI scripts. |
47 | The main purpose of VNag is to make the development of plugins as easy as possible, so that |
47 | The main purpose of VNag is to make the development of plugins as easy as possible, so that |
48 | the developer can concentrate on the actual work. VNag will try to automate as much |
48 | the developer can concentrate on the actual work. VNag will try to automate as much |
49 | as possible. |
49 | as possible. |
50 | 50 | ||
51 | Please note that your script should include the +x chmod flag: |
51 | Please note that your script should include the +x chmod flag: |
52 | chmod +x myscript.php |
52 | chmod +x myscript.php |
53 | 53 | ||
54 | Please see the the demo/ folder for a few examples how to use this framework. |
54 | Please see the the demo/ folder for a few examples how to use this framework. |
55 | 55 | ||
56 | Arguments: |
56 | Arguments: |
57 | 57 | ||
58 | Example: |
58 | Example: |
59 | $this->addExpectedArgument($argSilent = new VNagArgument('s', 'silent', VNagArgument::VALUE_FORBIDDEN, null, 'Description for the --silent output', $defaultValue)); |
59 | $this->addExpectedArgument($argSilent = new VNagArgument('s', 'silent', VNagArgument::VALUE_FORBIDDEN, null, 'Description for the --silent output', $defaultValue)); |
60 | $this->addExpectedArgument($argHost = new VNagArgument('H', 'host', VNagArgument::VALUE_REQUIRED, 'hostname', 'Description for the --host output', $defaultValue)); |
60 | $this->addExpectedArgument($argHost = new VNagArgument('H', 'host', VNagArgument::VALUE_REQUIRED, 'hostname', 'Description for the --host output', $defaultValue)); |
61 | 61 | ||
62 | In the example above, the two argument objects $argSilent and $argHost were created. |
62 | In the example above, the two argument objects $argSilent and $argHost were created. |
63 | With these objects of the type VNagArgument, you can query the argument's value, |
63 | With these objects of the type VNagArgument, you can query the argument's value, |
64 | how often the argument was passed and if it is set: |
64 | how often the argument was passed and if it is set: |
65 | 65 | ||
66 | $argSilent->count(); // 1 if "-s" is passed, 2 if "-s -s" is passed etc. |
66 | $argSilent->count(); // 1 if "-s" is passed, 2 if "-s -s" is passed etc. |
67 | $argSilent->available(); // true if "-s" is passed, false otherwise |
67 | $argSilent->available(); // true if "-s" is passed, false otherwise |
68 | $argHost->getValue(); // "example.com" if "-h example.com" is passed |
68 | $argHost->getValue(); // "example.com" if "-h example.com" is passed |
69 | 69 | ||
70 | It is recommended that you pass every argument to $this->addExpectedArgument() . |
70 | It is recommended that you pass every argument to $this->addExpectedArgument() . |
71 | Using this way, VNag can generate a --help page for you, which lists all your arguments. |
71 | Using this way, VNag can generate a --help page for you, which lists all your arguments. |
72 | Future version of VNag may also require to have a complete list of all valid arguments, |
72 | Future version of VNag may also require to have a complete list of all valid arguments, |
73 | since the Nagios Development Guidelines recommend to output the usage information if an illegal |
73 | since the Nagios Development Guidelines recommend to output the usage information if an illegal |
74 | argument is passed. Due to PHP's horrible bad implementation of GNU's getopt(), this check for |
74 | argument is passed. Due to PHP's horrible bad implementation of GNU's getopt(), this check for |
75 | unknown arguments is currently not possible, and the developer of VNag does not want to use |
75 | unknown arguments is currently not possible, and the developer of VNag does not want to use |
76 | dirty hacks/workarounds, which would not match to all argument notation variations/styles. |
76 | dirty hacks/workarounds, which would not match to all argument notation variations/styles. |
77 | See: https://bugs.php.net/bug.php?id=68806 |
77 | See: https://bugs.php.net/bug.php?id=68806 |
78 | https://bugs.php.net/bug.php?id=65673 |
78 | https://bugs.php.net/bug.php?id=65673 |
79 | https://bugs.php.net/bug.php?id=26818 |
79 | https://bugs.php.net/bug.php?id=26818 |
80 | 80 | ||
81 | Setting the status: |
81 | Setting the status: |
82 | 82 | ||
83 | You can set the status with: |
83 | You can set the status with: |
84 | $this->setStatus(VNag::STATUS_OK); |
84 | $this->setStatus(VNag::STATUS_OK); |
85 | If you don't set a status, the script will return Unknown instead. |
85 | If you don't set a status, the script will return Unknown instead. |
86 | setStatus($status) will keep the most severe status, e.g. |
86 | setStatus($status) will keep the most severe status, e.g. |
87 | $this->setStatus(VNag::STATUS_CRITICAL); |
87 | $this->setStatus(VNag::STATUS_CRITICAL); |
88 | $this->setStatus(VNag::STATUS_OK); |
88 | $this->setStatus(VNag::STATUS_OK); |
89 | will result in a status "Critical". |
89 | will result in a status "Critical". |
90 | If you want to completely overwrite the status, use $force=true: |
90 | If you want to completely overwrite the status, use $force=true: |
91 | $this->setStatus(VNag::STATUS_CRITICAL); |
91 | $this->setStatus(VNag::STATUS_CRITICAL); |
92 | $this->setStatus(VNag::STATUS_OK, true); |
92 | $this->setStatus(VNag::STATUS_OK, true); |
93 | The status will now be "OK". |
93 | The status will now be "OK". |
94 | 94 | ||
95 | Possible status codes are: |
95 | Possible status codes are: |
96 | (For service plugins:) |
96 | (For service plugins:) |
97 | VNag::STATUS_OK = 0; |
97 | VNag::STATUS_OK = 0; |
98 | VNag::STATUS_WARNING = 1; |
98 | VNag::STATUS_WARNING = 1; |
99 | VNag::STATUS_CRITICAL = 2; |
99 | VNag::STATUS_CRITICAL = 2; |
100 | VNag::STATUS_UNKNOWN = 3; |
100 | VNag::STATUS_UNKNOWN = 3; |
101 | 101 | ||
102 | (For host plugins:) |
102 | (For host plugins:) |
103 | VNag::STATUS_UP = 0; |
103 | VNag::STATUS_UP = 0; |
104 | VNag::STATUS_DOWN = 1; |
104 | VNag::STATUS_DOWN = 1; |
105 | 105 | ||
106 | Output: |
106 | Output: |
107 | 107 | ||
108 | After the callback function cbRun() of your job has finished, |
108 | After the callback function cbRun() of your job has finished, |
109 | the framework will automatically output the results in the Nagios console output format, |
109 | the framework will automatically output the results in the Nagios console output format, |
110 | the visual HTML output and/or the invisible HTML output. |
110 | the visual HTML output and/or the invisible HTML output. |
111 | 111 | ||
112 | In case of CLI invokation, the Shell exit code will be remembered and |
112 | In case of CLI invokation, the Shell exit code will be remembered and |
113 | automatically returned by the shutdown handler once the script normally |
113 | automatically returned by the shutdown handler once the script normally |
114 | terminates. (In case you run different jobs, which is not recommended, the |
114 | terminates. (In case you run different jobs, which is not recommended, the |
115 | shutdown handler will output the baddest exit code). |
115 | shutdown handler will output the baddest exit code). |
116 | 116 | ||
117 | The Shell output format will be: |
117 | The Shell output format will be: |
118 | <Service status text>: <Comma separates messages> | <whitespace separated primary performance data> |
118 | <Service status text>: <Comma separates messages> | <whitespace separated primary performance data> |
119 | "Verbose information:" |
119 | "Verbose information:" |
120 | <Multiline verbose output> | <Multiline secondary performance data> |
120 | <Multiline verbose output> | <Multiline secondary performance data> |
121 | 121 | ||
122 | <Service status text> will be automatically created by VNag. |
122 | <Service status text> will be automatically created by VNag. |
123 | 123 | ||
124 | Verbose information are printed below the first line. Most Nagios clients will only print the first line. |
124 | Verbose information are printed below the first line. Most Nagios clients will only print the first line. |
125 | If you have important output, use $this->setHeadline() instead. |
125 | If you have important output, use $this->setHeadline() instead. |
126 | You can add verbose information with following method: |
126 | You can add verbose information with following method: |
127 | $this->addVerboseMessage('foobar', $verbosity); |
127 | $this->addVerboseMessage('foobar', $verbosity); |
128 | 128 | ||
129 | Following verbosity levels are defined: |
129 | Following verbosity levels are defined: |
130 | VNag::VERBOSITY_SUMMARY = 0; // always printed |
130 | VNag::VERBOSITY_SUMMARY = 0; // always printed |
131 | VNag::VERBOSITY_ADDITIONAL_INFORMATION = 1; // requires at least -v |
131 | VNag::VERBOSITY_ADDITIONAL_INFORMATION = 1; // requires at least -v |
132 | VNag::VERBOSITY_CONFIGURATION_DEBUG = 2; // requiers at least -vv |
132 | VNag::VERBOSITY_CONFIGURATION_DEBUG = 2; // requiers at least -vv |
133 | VNag::VERBOSITY_PLUGIN_DEBUG = 3; // requiers at least -vvv |
133 | VNag::VERBOSITY_PLUGIN_DEBUG = 3; // requiers at least -vvv |
134 | 134 | ||
135 | All STDOUT outputs of your script (e.g. by echo) will be interpreted as "verbose" output |
135 | All STDOUT outputs of your script (e.g. by echo) will be interpreted as "verbose" output |
136 | and is automatically collected, so |
136 | and is automatically collected, so |
137 | echo "foobar"; |
137 | echo "foobar"; |
138 | has the same functionality as |
138 | has the same functionality as |
139 | $this->addVerboseMessage('foobar', VNag::VERBOSITY_SUMMARY); |
139 | $this->addVerboseMessage('foobar', VNag::VERBOSITY_SUMMARY); |
140 | 140 | ||
141 | You can set messages (which will be added into the first line, which is preferred for plugin outputs) |
141 | You can set messages (which will be added into the first line, which is preferred for plugin outputs) |
142 | using |
142 | using |
143 | $this->setHeadline($msg, $append, $verbosity); |
143 | $this->setHeadline($msg, $append, $verbosity); |
144 | Using the flag $append, you can choose if you want to append or replace the message. |
144 | Using the flag $append, you can choose if you want to append or replace the message. |
145 | 145 | ||
146 | VNag will catch Exceptions of your script and will automatically end the plugin, |
146 | VNag will catch Exceptions of your script and will automatically end the plugin, |
147 | returning a valid Nagios output. |
147 | returning a valid Nagios output. |
148 | 148 | ||
149 | Automatic handling of basic arguments: |
149 | Automatic handling of basic arguments: |
150 | 150 | ||
151 | VNag will automatic handle of following CLI arguments: |
151 | VNag will automatic handle of following CLI arguments: |
152 | -? |
152 | -? |
153 | -V --version |
153 | -V --version |
154 | -h --help |
154 | -h --help |
155 | -v --verbose |
155 | -v --verbose |
156 | -t --timeout (only works if you set declare(ticks=1) at the beginning of each of your scripts) |
156 | -t --timeout (only works if you set declare(ticks=1) at the beginning of each of your scripts) |
157 | -w --warning |
157 | -w --warning |
158 | -c --critical |
158 | -c --critical |
159 | 159 | ||
160 | You can performe range checking by using: |
160 | You can performe range checking by using: |
161 | $example_value = '10MB'; |
161 | $example_value = '10MB'; |
162 | $this->checkAgainstWarningRange($example_value); |
162 | $this->checkAgainstWarningRange($example_value); |
163 | this is more or less the same as: |
163 | this is more or less the same as: |
164 | $example_value = '10MB'; |
164 | $example_value = '10MB'; |
165 | $wr = $this->getWarningRange(); |
165 | $wr = $this->getWarningRange(); |
166 | if (isset($wr) && $wr->checkAlert($example_value)) { |
166 | if (isset($wr) && $wr->checkAlert($example_value)) { |
167 | $this->setStatus(VNag::STATUS_WARNING); |
167 | $this->setStatus(VNag::STATUS_WARNING); |
168 | } |
168 | } |
169 | 169 | ||
170 | In case that your script allows ranges which can be relative and absolute, you can provide multiple arguments; |
170 | In case that your script allows ranges which can be relative and absolute, you can provide multiple arguments; |
171 | $wr->checkAlert() will be true, as soon as one of the arguments is in the warning range. |
171 | $wr->checkAlert() will be true, as soon as one of the arguments is in the warning range. |
172 | The check will be done in this way: |
172 | The check will be done in this way: |
173 | $example_values = array('10MB', '5%'); |
173 | $example_values = array('10MB', '5%'); |
174 | $this->checkAgainstWarningRange($example_values); |
174 | $this->checkAgainstWarningRange($example_values); |
175 | this is more or less the same as: |
175 | this is more or less the same as: |
176 | $example_values = array('10MB', '5%'); |
176 | $example_values = array('10MB', '5%'); |
177 | $wr = $this->getWarningRange(); |
177 | $wr = $this->getWarningRange(); |
178 | if (isset($wr) && $wr->checkAlert($example_values)) { |
178 | if (isset($wr) && $wr->checkAlert($example_values)) { |
179 | $this->setStatus(VNag::STATUS_WARNING); |
179 | $this->setStatus(VNag::STATUS_WARNING); |
180 | } |
180 | } |
181 | 181 | ||
182 | Note that VNag will automatically detect the UOM (Unit of Measurement) and is also able to convert them, |
182 | Note that VNag will automatically detect the UOM (Unit of Measurement) and is also able to convert them, |
183 | e.g. if you use the range "-w 20MB:40MB", your script will be able to use $wr->checkAlert('3000KB') |
183 | e.g. if you use the range "-w 20MB:40MB", your script will be able to use $wr->checkAlert('3000KB') |
184 | 184 | ||
185 | Please note that only following UOMs are accepted (as defined in the Plugin Development Guidelines): |
185 | Please note that only following UOMs are accepted (as defined in the Plugin Development Guidelines): |
186 | - no unit specified: assume a number (int or float) of things (eg, users, processes, load averages) |
186 | - no unit specified: assume a number (int or float) of things (eg, users, processes, load averages) |
187 | - s, ms, us: seconds |
187 | - s, ms, us: seconds |
188 | - %: percentage |
188 | - %: percentage |
189 | - B, KB, MB, TB: bytes // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway |
189 | - B, KB, MB, TB: bytes // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway |
190 | - c: a continous counter (such as bytes transmitted on an interface) |
190 | - c: a continous counter (such as bytes transmitted on an interface) |
191 | 191 | ||
192 | Multiple warning/critical ranges: |
192 | Multiple warning/critical ranges: |
193 | 193 | ||
194 | The arguments -w and -c can have many different values, separated by comma. |
194 | The arguments -w and -c can have many different values, separated by comma. |
195 | We can see this feature e.g. with the official plugin /usr/lib/nagios/plugins/check_ping: |
195 | We can see this feature e.g. with the official plugin /usr/lib/nagios/plugins/check_ping: |
196 | It has following syntax for the arguments -w and -c: <latency>,<packetloss>% |
196 | It has following syntax for the arguments -w and -c: <latency>,<packetloss>% |
197 | 197 | ||
198 | When you are using checkAgainstWarningRange, you can set the fourth argument to the range number |
198 | When you are using checkAgainstWarningRange, you can set the fourth argument to the range number |
199 | you would like to check (beginning with 0). |
199 | you would like to check (beginning with 0). |
200 | 200 | ||
201 | Example: |
201 | Example: |
202 | // -w 1MB:5MB,5%:10% |
202 | // -w 1MB:5MB,5%:10% |
203 | $this->checkAgainstWarningRange('4MB', true, true, 0); // check value 4MB against range "1MB:5MB" (no warning) |
203 | $this->checkAgainstWarningRange('4MB', true, true, 0); // check value 4MB against range "1MB:5MB" (no warning) |
204 | $this->checkAgainstWarningRange('15%', true, true, 1); // check value 15% gainst range "5%:10%" (gives warning) |
204 | $this->checkAgainstWarningRange('15%', true, true, 1); // check value 15% gainst range "5%:10%" (gives warning) |
205 | 205 | ||
206 | Visual HTTP output: |
206 | Visual HTTP output: |
207 | 207 | ||
208 | Can be enabled/disabled with $this->http_visual_output |
208 | Can be enabled/disabled with $this->http_visual_output |
209 | 209 | ||
210 | Valid values: |
210 | Valid values: |
211 | 211 | ||
212 | VNag::OUTPUT_SPECIAL = 1; // illegal usage / help page, version page |
212 | VNag::OUTPUT_SPECIAL = 1; // illegal usage / help page, version page |
213 | VNag::OUTPUT_NORMAL = 2; |
213 | VNag::OUTPUT_NORMAL = 2; |
214 | VNag::OUTPUT_EXCEPTION = 4; |
214 | VNag::OUTPUT_EXCEPTION = 4; |
215 | VNag::OUTPUT_ALWAYS = 7; |
215 | VNag::OUTPUT_ALWAYS = 7; |
216 | VNag::OUTPUT_NEVER = 0; |
216 | VNag::OUTPUT_NEVER = 0; |
217 | 217 | ||
218 | Encryption and Decryption: |
218 | Encryption and Decryption: |
219 | 219 | ||
220 | In case you are emitting machine-readable code in your HTTP output |
220 | In case you are emitting machine-readable code in your HTTP output |
221 | (can be enabled/disabled by $this->http_invisible_output), |
221 | (can be enabled/disabled by $this->http_invisible_output), |
222 | you can encrypt the machine-readable part of your HTTP output by |
222 | you can encrypt the machine-readable part of your HTTP output by |
223 | setting $this->password_out . If you want to read the information, |
223 | setting $this->password_out . If you want to read the information, |
224 | you need to set $this->password_in at the web-reader plugin. |
224 | you need to set $this->password_in at the web-reader plugin. |
225 | The visual output is not encrypted. So, if you want to hide the information, |
225 | The visual output is not encrypted. So, if you want to hide the information, |
226 | then you must not enable visual HTML output. |
226 | then you must not enable visual HTML output. |
227 | If you don't want to encrypt the machine-readable output, |
227 | If you don't want to encrypt the machine-readable output, |
228 | please set $this->password_out to null or empty string. |
228 | please set $this->password_out to null or empty string. |
229 | 229 | ||
230 | Attention! |
230 | Attention! |
231 | - Encryption and decryption require the OpenSSL extension in PHP. |
231 | - Encryption and decryption require the OpenSSL extension in PHP. |
232 | 232 | ||
233 | Digital signature: |
233 | Digital signature: |
234 | 234 | ||
235 | You can sign the output by setting $this->privkey with a filename containing |
235 | You can sign the output by setting $this->privkey with a filename containing |
236 | a private key created by OpenSSL. If it is encrypted, please also set |
236 | a private key created by OpenSSL. If it is encrypted, please also set |
237 | $this->privkey_password . |
237 | $this->privkey_password . |
238 | To check the signature, set $this->pubkey at your web-reader plugin with |
238 | To check the signature, set $this->pubkey at your web-reader plugin with |
239 | the filename of the public key file. |
239 | the filename of the public key file. |
240 | 240 | ||
241 | Attention! |
241 | Attention! |
242 | - Signatures require the OpenSSL extension in PHP. |
242 | - Signatures require the OpenSSL extension in PHP. |
243 | 243 | ||
244 | Performance data: |
244 | Performance data: |
245 | 245 | ||
246 | You can add performance data using |
246 | You can add performance data using |
247 | $this->addPerformanceData(new VNagPerformanceData($label, $value, $warn, $crit, $min, $max)); |
247 | $this->addPerformanceData(new VNagPerformanceData($label, $value, $warn, $crit, $min, $max)); |
248 | or by the alternative constructor |
248 | or by the alternative constructor |
249 | $this->addPerformanceData(VNagPerformanceData::createByString("'XYZ'=100;120;130;0;500")); |
249 | $this->addPerformanceData(VNagPerformanceData::createByString("'XYZ'=100;120;130;0;500")); |
250 | $value may contain an UOM, e.g. "10MB". All other parameters may not contain an UOM. |
250 | $value may contain an UOM, e.g. "10MB". All other parameters may not contain an UOM. |
251 | 251 | ||
252 | Guidelines: |
252 | Guidelines: |
253 | 253 | ||
254 | This framework currently supports meets following guidelines: |
254 | This framework currently supports meets following guidelines: |
255 | - https://nagios-plugins.org/doc/guidelines.html#PLUGOUTPUT (Plugin Output for Nagios) |
255 | - https://nagios-plugins.org/doc/guidelines.html#PLUGOUTPUT (Plugin Output for Nagios) |
256 | - https://nagios-plugins.org/doc/guidelines.html#AEN33 (Print only one line of text) |
256 | - https://nagios-plugins.org/doc/guidelines.html#AEN33 (Print only one line of text) |
257 | - https://nagios-plugins.org/doc/guidelines.html#AEN41 (Verbose output) |
257 | - https://nagios-plugins.org/doc/guidelines.html#AEN41 (Verbose output) |
258 | - https://nagios-plugins.org/doc/guidelines.html#AEN78 (Plugin Return Codes) |
258 | - https://nagios-plugins.org/doc/guidelines.html#AEN78 (Plugin Return Codes) |
259 | - https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT (Threshold and ranges) |
259 | - https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT (Threshold and ranges) |
260 | - https://nagios-plugins.org/doc/guidelines.html#AEN200 (Performance data) |
260 | - https://nagios-plugins.org/doc/guidelines.html#AEN200 (Performance data) |
261 | - https://nagios-plugins.org/doc/guidelines.html#PLUGOPTIONS (Plugin Options) |
261 | - https://nagios-plugins.org/doc/guidelines.html#PLUGOPTIONS (Plugin Options) |
262 | - https://nagios-plugins.org/doc/guidelines.html#AEN302 (Option Processing) |
262 | - https://nagios-plugins.org/doc/guidelines.html#AEN302 (Option Processing) |
263 | Note: The screen output of the help page will (mostly) be limited to 80 characters width; but the max recommended length of 23 lines cannot be guaranteed. |
263 | Note: The screen output of the help page will (mostly) be limited to 80 characters width; but the max recommended length of 23 lines cannot be guaranteed. |
264 | 264 | ||
265 | This framework does currently NOT support following guidelines: |
265 | This framework does currently NOT support following guidelines: |
266 | - https://nagios-plugins.org/doc/guidelines.html#AEN74 (Screen Output) |
266 | - https://nagios-plugins.org/doc/guidelines.html#AEN74 (Screen Output) |
267 | - https://nagios-plugins.org/doc/guidelines.html#AEN239 (Translations) |
267 | - https://nagios-plugins.org/doc/guidelines.html#AEN239 (Translations) |
268 | - https://nagios-plugins.org/doc/guidelines.html#AEN293 (Use DEFAULT_SOCKET_TIMEOUT) |
268 | - https://nagios-plugins.org/doc/guidelines.html#AEN293 (Use DEFAULT_SOCKET_TIMEOUT) |
269 | - https://nagios-plugins.org/doc/guidelines.html#AEN296 (Add alarms to network plugins) |
269 | - https://nagios-plugins.org/doc/guidelines.html#AEN296 (Add alarms to network plugins) |
270 | - https://nagios-plugins.org/doc/guidelines.html#AEN245 (Don't execute system commands without specifying their full path) |
270 | - https://nagios-plugins.org/doc/guidelines.html#AEN245 (Don't execute system commands without specifying their full path) |
271 | - https://nagios-plugins.org/doc/guidelines.html#AEN249 (Use spopen() if external commands must be executed) |
271 | - https://nagios-plugins.org/doc/guidelines.html#AEN249 (Use spopen() if external commands must be executed) |
272 | - https://nagios-plugins.org/doc/guidelines.html#AEN253 (Don't make temp files unless absolutely required) |
272 | - https://nagios-plugins.org/doc/guidelines.html#AEN253 (Don't make temp files unless absolutely required) |
273 | - https://nagios-plugins.org/doc/guidelines.html#AEN259 (Validate all input) |
273 | - https://nagios-plugins.org/doc/guidelines.html#AEN259 (Validate all input) |
274 | - https://nagios-plugins.org/doc/guidelines.html#AEN317 (Plugins with more than one type of threshold, or with threshold ranges) |
274 | - https://nagios-plugins.org/doc/guidelines.html#AEN317 (Plugins with more than one type of threshold, or with threshold ranges) |
275 | 275 | ||
276 | We will intentionally NOT follow the following guidelines: |
276 | We will intentionally NOT follow the following guidelines: |
277 | - https://nagios-plugins.org/doc/guidelines.html#AEN256 (Don't be tricked into following symlinks) |
277 | - https://nagios-plugins.org/doc/guidelines.html#AEN256 (Don't be tricked into following symlinks) |
278 | Reason: We believe that this guideline is contraproductive. |
278 | Reason: We believe that this guideline is contraproductive. |
279 | Nagios plugins usually run as user 'nagios'. It is the task of the system administrator |
279 | Nagios plugins usually run as user 'nagios'. It is the task of the system administrator |
280 | to ensure that the user 'nagios' must not read/write to files which are not intended |
280 | to ensure that the user 'nagios' must not read/write to files which are not intended |
281 | for access by the Nagios service. Instead, symlinks are useful for several tasks. |
281 | for access by the Nagios service. Instead, symlinks are useful for several tasks. |
282 | See also http://stackoverflow.com/questions/27112949/nagios-plugins-why-not-following-symlinks |
282 | See also http://stackoverflow.com/questions/27112949/nagios-plugins-why-not-following-symlinks |
283 | 283 | ||
284 | VNag over HTTP: |
284 | VNag over HTTP: |
285 | 285 | ||
286 | A script that uses the VNag framework can run as CLI script (normal Nagios plugin) or as web site (or both). |
286 | A script that uses the VNag framework can run as CLI script (normal Nagios plugin) or as web site (or both). |
287 | Having the script run as website, you can include a Nagios information combined with a human friendly HTML output which can |
287 | Having the script run as website, you can include a Nagios information combined with a human friendly HTML output which can |
288 | include colors, graphics (like charts) etc. |
288 | include colors, graphics (like charts) etc. |
289 | 289 | ||
290 | For example: |
290 | For example: |
291 | A script that measures traffic can have a website which shows graphs, |
291 | A script that measures traffic can have a website which shows graphs, |
292 | and has a hidden Nagios output included, which can be read by a Nagios plugin that |
292 | and has a hidden Nagios output included, which can be read by a Nagios plugin that |
293 | converts the hidden information on that website into an output that Nagios can evaluate. |
293 | converts the hidden information on that website into an output that Nagios can evaluate. |
294 | 294 | ||
295 | Here is a comparison of the usage and behavior of VNag in regards to CLI and HTTP calls: |
295 | Here is a comparison of the usage and behavior of VNag in regards to CLI and HTTP calls: |
296 | 296 | ||
297 | ------------------------------------------------------------------------------------------ |
297 | ------------------------------------------------------------------------------------------ |
298 | CLI script HTTP script |
298 | CLI script HTTP script |
299 | ------------------------------------------------------------------------------------------ |
299 | ------------------------------------------------------------------------------------------ |
300 | * "echo" will be discarded. * "echo" output will be discarded. |
300 | * "echo" will be discarded. * "echo" output will be discarded. |
301 | 301 | ||
302 | * Exceptions will be handled. * Exceptions will be handled. |
302 | * Exceptions will be handled. * Exceptions will be handled. |
303 | 303 | ||
304 | * outputHTML() will be ignored. * outputHTML() will be handled. |
304 | * outputHTML() will be ignored. * outputHTML() will be handled. |
305 | (This allows you to have the same script |
305 | (This allows you to have the same script |
306 | running as CLI and HTML) |
306 | running as CLI and HTML) |
307 | 307 | ||
308 | * Arguments are passed via CLI. * Arguments are passed via $_REQUEST |
308 | * Arguments are passed via CLI. * Arguments are passed via $_REQUEST |
309 | (i.e. GET or POST) |
309 | (i.e. GET or POST) |
310 | 310 | ||
311 | * Arguments: "-vvv" * Arguments: GET ?v[]=&v[]=&v[]= or POST |
311 | * Arguments: "-vvv" * Arguments: GET ?v[]=&v[]=&v[]= or POST |
312 | 312 | ||
313 | * When run() has finished, the program * When run() has finished, the program |
313 | * When run() has finished, the program * When run() has finished, the program |
314 | flow continues, although it is not flow continues. |
314 | flow continues, although it is not flow continues. |
315 | recommended that you do anything after it. |
315 | recommended that you do anything after it. |
316 | (The exit code is remembered for the |
316 | (The exit code is remembered for the |
317 | shutdown handler) |
317 | shutdown handler) |
318 | 318 | ||
319 | * Exactly 1 job must be called, resulting * You can call as many jobs as you want. |
319 | * Exactly 1 job must be called, resulting * You can call as many jobs as you want. |
320 | in a single output of that job. A website can include more than one |
320 | in a single output of that job. A website can include more than one |
321 | Nagios output which are enumerated with |
321 | Nagios output which are enumerated with |
322 | a serial number (0,1,2,3,...) or manual ID. |
322 | a serial number (0,1,2,3,...) or manual ID. |
323 | ------------------------------------------------------------------------------------------ |
323 | ------------------------------------------------------------------------------------------ |
324 | 324 | ||
325 | ****************************************************************************************************/ |
325 | ****************************************************************************************************/ |
326 | 326 | ||
327 | if (!VNag::is_http_mode()) error_reporting(E_ALL); |
327 | if (!VNag::is_http_mode()) error_reporting(E_ALL); |
328 | 328 | ||
329 | # If you want to use -t/--timeout with your module, you must add following line in your module code: |
329 | # If you want to use -t/--timeout with your module, you must add following line in your module code: |
330 | // WONTFIX: declare(ticks=1) is deprecated? http://www.hackingwithphp.com/4/21/0/the-declare-function-and-ticks |
330 | // WONTFIX: declare(ticks=1) is deprecated? http://www.hackingwithphp.com/4/21/0/the-declare-function-and-ticks |
331 | // WONTFIX: check is the main script used declare(ticks=1). (Not possible in PHP) |
331 | // WONTFIX: check is the main script used declare(ticks=1). (Not possible in PHP) |
332 | declare(ticks=1); |
332 | declare(ticks=1); |
333 | 333 | ||
334 | # Attention: The -t/--timeout parameter does not respect the built-in set_time_limit() of PHP. |
334 | # Attention: The -t/--timeout parameter does not respect the built-in set_time_limit() of PHP. |
335 | # PHP should set this time limit to infinite. |
335 | # PHP should set this time limit to infinite. |
336 | set_time_limit(0); |
336 | set_time_limit(0); |
337 | 337 | ||
338 | define('VNAG_JSONDATA_V1', 'oid:1.3.6.1.4.1.37476.2.3.1.1'); // {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) vnag(3) jsondata(1) v1(1)} |
338 | define('VNAG_JSONDATA_V1', 'oid:1.3.6.1.4.1.37476.2.3.1.1'); // {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 products(2) vnag(3) jsondata(1) v1(1)} |
339 | 339 | ||
340 | // Set this to an array to overwrite getopt() and $_REQUEST[], respectively. |
340 | // Set this to an array to overwrite getopt() and $_REQUEST[], respectively. |
341 | // Useful for mock tests. |
341 | // Useful for mock tests. |
342 | $OVERWRITE_ARGUMENTS = null; |
342 | $OVERWRITE_ARGUMENTS = null; |
343 | 343 | ||
344 | function _empty($x) { |
344 | function _empty($x) { |
345 | // Returns true for '' or null. Does not return true for value 0 or '0' (like empty() does) |
345 | // Returns true for '' or null. Does not return true for value 0 or '0' (like empty() does) |
346 | return trim($x) == ''; |
346 | return trim($x) == ''; |
347 | } |
347 | } |
348 | 348 | ||
349 | abstract class VNag { |
349 | abstract class VNag { |
350 | /*public*/ const VNAG_VERSION = '2022-06-06'; |
350 | /*public*/ const VNAG_VERSION = '2022-12-18'; |
351 | 351 | ||
352 | // Status 0..3 for STATUSMODEL_SERVICE (the default status model): |
352 | // Status 0..3 for STATUSMODEL_SERVICE (the default status model): |
353 | # The guideline states: "Higher-level errors (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins and should generally NOT be reported as UNKNOWN states." |
353 | # The guideline states: "Higher-level errors (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins and should generally NOT be reported as UNKNOWN states." |
354 | # We choose 4 as exitcode. The plugin developer is free to return any other status. |
354 | # We choose 4 as exitcode. The plugin developer is free to return any other status. |
355 | /*public*/ const STATUS_OK = 0; |
355 | /*public*/ const STATUS_OK = 0; |
356 | /*public*/ const STATUS_WARNING = 1; |
356 | /*public*/ const STATUS_WARNING = 1; |
357 | /*public*/ const STATUS_CRITICAL = 2; |
357 | /*public*/ const STATUS_CRITICAL = 2; |
358 | /*public*/ const STATUS_UNKNOWN = 3; |
358 | /*public*/ const STATUS_UNKNOWN = 3; |
359 | /*public*/ const STATUS_ERROR = 4; // and upwards |
359 | /*public*/ const STATUS_ERROR = 4; // and upwards |
360 | 360 | ||
361 | // Status 0..1 for STATUSMODEL_HOST: |
361 | // Status 0..1 for STATUSMODEL_HOST: |
362 | // The page https://blog.centreon.com/good-practices-how-to-develop-monitoring-plugin-nagios/ |
362 | // The page https://blog.centreon.com/good-practices-how-to-develop-monitoring-plugin-nagios/ |
363 | // states that host plugins may return following status codes: |
363 | // states that host plugins may return following status codes: |
364 | // 0=UP, 1=DOWN, Other=Maintains last known state |
364 | // 0=UP, 1=DOWN, Other=Maintains last known state |
365 | /*public*/ const STATUS_UP = 0; |
365 | /*public*/ const STATUS_UP = 0; |
366 | /*public*/ const STATUS_DOWN = 1; |
366 | /*public*/ const STATUS_DOWN = 1; |
367 | /*public*/ const STATUS_MAINTAIN = 2; // and upwards |
367 | /*public*/ const STATUS_MAINTAIN = 2; // and upwards |
368 | 368 | ||
369 | /*public*/ const VERBOSITY_SUMMARY = 0; |
369 | /*public*/ const VERBOSITY_SUMMARY = 0; |
370 | /*public*/ const VERBOSITY_ADDITIONAL_INFORMATION = 1; |
370 | /*public*/ const VERBOSITY_ADDITIONAL_INFORMATION = 1; |
371 | /*public*/ const VERBOSITY_CONFIGURATION_DEBUG = 2; |
371 | /*public*/ const VERBOSITY_CONFIGURATION_DEBUG = 2; |
372 | /*public*/ const VERBOSITY_PLUGIN_DEBUG = 3; |
372 | /*public*/ const VERBOSITY_PLUGIN_DEBUG = 3; |
373 | /*public*/ const MAX_VERBOSITY = self::VERBOSITY_PLUGIN_DEBUG; |
373 | /*public*/ const MAX_VERBOSITY = self::VERBOSITY_PLUGIN_DEBUG; |
374 | 374 | ||
375 | /*public*/ const STATUSMODEL_SERVICE = 0; |
375 | /*public*/ const STATUSMODEL_SERVICE = 0; |
376 | /*public*/ const STATUSMODEL_HOST = 1; |
376 | /*public*/ const STATUSMODEL_HOST = 1; |
377 | 377 | ||
378 | private $initialized = false; |
378 | private $initialized = false; |
379 | 379 | ||
380 | private $status = null; |
380 | private $status = null; |
381 | private $messages = array(); // array of messages which are all put together into the headline, comma separated |
381 | private $messages = array(); // array of messages which are all put together into the headline, comma separated |
382 | private $verbose_info = ''; // all other lines |
382 | private $verbose_info = ''; // all other lines |
383 | private $warningRanges = array(); |
383 | private $warningRanges = array(); |
384 | private $criticalRanges = array(); |
384 | private $criticalRanges = array(); |
385 | private $performanceDataObjects = array(); |
385 | private $performanceDataObjects = array(); |
386 | private static $exitcode = 0; |
386 | private static $exitcode = 0; |
387 | 387 | ||
388 | private $helpObj = null; |
388 | private $helpObj = null; |
389 | private $argHandler = null; |
389 | private $argHandler = null; |
390 | 390 | ||
391 | /*public*/ const OUTPUT_NEVER = 0; |
391 | /*public*/ const OUTPUT_NEVER = 0; |
392 | /*public*/ const OUTPUT_SPECIAL = 1; // illegal usage / help page, version page |
392 | /*public*/ const OUTPUT_SPECIAL = 1; // illegal usage / help page, version page |
393 | /*public*/ const OUTPUT_NORMAL = 2; |
393 | /*public*/ const OUTPUT_NORMAL = 2; |
394 | /*public*/ const OUTPUT_EXCEPTION = 4; |
394 | /*public*/ const OUTPUT_EXCEPTION = 4; |
395 | /*public*/ const OUTPUT_ALWAYS = 7; // = OUTPUT_SPECIAL+OUTPUT_NORMAL+OUTPUT_EXCEPTION |
395 | /*public*/ const OUTPUT_ALWAYS = 7; // = OUTPUT_SPECIAL+OUTPUT_NORMAL+OUTPUT_EXCEPTION |
396 | 396 | ||
397 | public $http_visual_output = self::OUTPUT_ALWAYS; // show a human-readable panel? ... |
397 | public $http_visual_output = self::OUTPUT_ALWAYS; // show a human-readable panel? ... |
398 | public $http_invisible_output = self::OUTPUT_ALWAYS; // ... and/or output an invisible machine-readable tag? |
398 | public $http_invisible_output = self::OUTPUT_ALWAYS; // ... and/or output an invisible machine-readable tag? |
399 | 399 | ||
400 | // $html_before and $html_after contain the output HTML which were sent by the user |
400 | // $html_before and $html_after contain the output HTML which were sent by the user |
401 | 401 | ||
402 | // before and after the visual output |
402 | // before and after the visual output |
403 | protected $html_before = ''; |
403 | protected $html_before = ''; |
404 | protected $html_after = ''; |
404 | protected $html_after = ''; |
405 | 405 | ||
406 | protected $statusmodel = self::STATUSMODEL_SERVICE; |
406 | protected $statusmodel = self::STATUSMODEL_SERVICE; |
407 | 407 | ||
408 | protected $show_status_in_headline = true; |
408 | protected $show_status_in_headline = true; |
409 | 409 | ||
410 | protected $default_status = self::STATUS_UNKNOWN; |
410 | protected $default_status = self::STATUS_UNKNOWN; |
411 | protected $default_warning_range = null; |
411 | protected $default_warning_range = null; |
412 | protected $default_critical_range = null; |
412 | protected $default_critical_range = null; |
413 | 413 | ||
414 | protected $argWarning; |
414 | protected $argWarning; |
415 | protected $argCritical; |
415 | protected $argCritical; |
416 | protected $argVersion; |
416 | protected $argVersion; |
417 | protected $argVerbosity; |
417 | protected $argVerbosity; |
418 | protected $argTimeout; |
418 | protected $argTimeout; |
419 | protected $argHelp; |
419 | protected $argHelp; |
420 | protected $argUsage; |
420 | protected $argUsage; |
421 | 421 | ||
422 | // ----------------------------------------------------------- |
422 | // ----------------------------------------------------------- |
423 | 423 | ||
424 | // The ID will be used for writing AND reading of the machine-readable |
424 | // The ID will be used for writing AND reading of the machine-readable |
425 | // Nagios output embedded in a website. (A web-reader acts as proxy, so the |
425 | // Nagios output embedded in a website. (A web-reader acts as proxy, so the |
426 | // input and output ID will be equal) |
426 | // input and output ID will be equal) |
427 | // Attention: Once you run run(), $id will be "used" and resetted to null. |
427 | // Attention: Once you run run(), $id will be "used" and resetted to null. |
428 | // The ID can be any string, e.g. a GUID, an OID, a package name or something else. |
428 | // The ID can be any string, e.g. a GUID, an OID, a package name or something else. |
429 | // It should be unique. If you don't set an ID, a serial number (0, 1, 2, 3, ...) will be |
429 | // It should be unique. If you don't set an ID, a serial number (0, 1, 2, 3, ...) will be |
430 | // used for your outputs. |
430 | // used for your outputs. |
431 | public $id = null; |
431 | public $id = null; |
432 | protected static $http_serial_number = 0; |
432 | protected static $http_serial_number = 0; |
433 | 433 | ||
434 | // ----------------------------------------------------------- |
434 | // ----------------------------------------------------------- |
435 | 435 | ||
436 | // Private key: Optional feature used in writeInvisibleHTML (called by run in HTTP mode) in order to sign/encrypt the output |
436 | // Private key: Optional feature used in writeInvisibleHTML (called by run in HTTP mode) in order to sign/encrypt the output |
437 | public $privkey = null; |
437 | public $privkey = null; |
438 | public $privkey_password = null; |
438 | public $privkey_password = null; |
439 | public $sign_algo = null; // default: OPENSSL_ALGO_SHA256 |
439 | public $sign_algo = null; // default: OPENSSL_ALGO_SHA256 |
440 | 440 | ||
441 | // Public key: Optional feature used in a web-reader [readInvisibleHTML) to check the integrity of a message |
441 | // Public key: Optional feature used in a web-reader [readInvisibleHTML) to check the integrity of a message |
442 | public $pubkey = null; |
442 | public $pubkey = null; |
443 | 443 | ||
444 | // ----------------------------------------------------------- |
444 | // ----------------------------------------------------------- |
445 | 445 | ||
446 | // These settings should be set by derivated classes where the user intuitively expects the |
446 | // These settings should be set by derivated classes where the user intuitively expects the |
447 | // warning (w) or critical (c) parameter to mean something else than defined in the development guidelines. |
447 | // warning (w) or critical (c) parameter to mean something else than defined in the development guidelines. |
448 | // Usually, the single value "-w X" means the same like "-w X:X", which means everything except X is bad. |
448 | // Usually, the single value "-w X" means the same like "-w X:X", which means everything except X is bad. |
449 | // This behavior is VNag::SINGLEVALUE_RANGE_DEFAULT. |
449 | // This behavior is VNag::SINGLEVALUE_RANGE_DEFAULT. |
450 | // But for plugins e.g. for checking disk space, the user expects the argument "-w X" to mean |
450 | // But for plugins e.g. for checking disk space, the user expects the argument "-w X" to mean |
451 | // "everything below X is bad" (if X is defined as free disk space). |
451 | // "everything below X is bad" (if X is defined as free disk space). |
452 | // So we would choose the setting VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD. |
452 | // So we would choose the setting VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD. |
453 | // Note: This setting is implemented as array, so that each range number (in case you want to have more |
453 | // Note: This setting is implemented as array, so that each range number (in case you want to have more |
454 | // than one range, like in the PING plugin that checks latency and package loss) |
454 | // than one range, like in the PING plugin that checks latency and package loss) |
455 | // can have its individual behavior for single values. |
455 | // can have its individual behavior for single values. |
456 | protected $warningSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT); |
456 | protected $warningSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT); |
457 | protected $criticalSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT); |
457 | protected $criticalSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT); |
458 | 458 | ||
459 | // Default behavior according to the development guidelines: |
459 | // Default behavior according to the development guidelines: |
460 | // x means x:x, which means, everything except x% is bad. |
460 | // x means x:x, which means, everything except x% is bad. |
461 | // @x means @x:x, which means, x is bad and everything else is good. |
461 | // @x means @x:x, which means, x is bad and everything else is good. |
462 | const SINGLEVALUE_RANGE_DEFAULT = 0; |
462 | const SINGLEVALUE_RANGE_DEFAULT = 0; |
463 | 463 | ||
464 | // The single value x means, everything > x is bad. @x is not defined. |
464 | // The single value x means, everything > x is bad. @x is not defined. |
465 | const SINGLEVALUE_RANGE_VAL_GT_X_BAD = 1; |
465 | const SINGLEVALUE_RANGE_VAL_GT_X_BAD = 1; |
466 | 466 | ||
467 | // The single value x means, everything >= x is bad. @x is not defined. |
467 | // The single value x means, everything >= x is bad. @x is not defined. |
468 | const SINGLEVALUE_RANGE_VAL_GE_X_BAD = 2; |
468 | const SINGLEVALUE_RANGE_VAL_GE_X_BAD = 2; |
469 | 469 | ||
470 | // The single value x means, everything < x is bad. @x is not defined. |
470 | // The single value x means, everything < x is bad. @x is not defined. |
471 | const SINGLEVALUE_RANGE_VAL_LT_X_BAD = 3; |
471 | const SINGLEVALUE_RANGE_VAL_LT_X_BAD = 3; |
472 | 472 | ||
473 | // The single value x means, everything <= x is bad. @x is not defined. |
473 | // The single value x means, everything <= x is bad. @x is not defined. |
474 | const SINGLEVALUE_RANGE_VAL_LE_X_BAD = 4; |
474 | const SINGLEVALUE_RANGE_VAL_LE_X_BAD = 4; |
475 | 475 | ||
476 | // ----------------------------------------------------------- |
476 | // ----------------------------------------------------------- |
477 | 477 | ||
478 | // Encryption password: Optional feature used in writeInvisibleHTML (called by run in HTTP mode) |
478 | // Encryption password: Optional feature used in writeInvisibleHTML (called by run in HTTP mode) |
479 | public $password_out = null; |
479 | public $password_out = null; |
480 | 480 | ||
481 | // Decryption password: Used in readInvisibleHTML to decrypt an encrypted machine-readable info |
481 | // Decryption password: Used in readInvisibleHTML to decrypt an encrypted machine-readable info |
482 | public $password_in = null; |
482 | public $password_in = null; |
483 | 483 | ||
484 | // ----------------------------------------------------------- |
484 | // ----------------------------------------------------------- |
485 | 485 | ||
486 | public static function is_http_mode() { |
486 | public static function is_http_mode() { |
487 | return php_sapi_name() !== 'cli'; |
487 | return php_sapi_name() !== 'cli'; |
488 | } |
488 | } |
489 | 489 | ||
490 | public function getHelpManager() { |
490 | public function getHelpManager() { |
491 | return $this->helpObj; |
491 | return $this->helpObj; |
492 | } |
492 | } |
493 | 493 | ||
494 | public function getArgumentHandler() { |
494 | public function getArgumentHandler() { |
495 | return $this->argHandler; |
495 | return $this->argHandler; |
496 | } |
496 | } |
497 | 497 | ||
498 | public function outputHTML($text, $after_visual_output=true) { |
498 | public function outputHTML($text, $after_visual_output=true) { |
499 | if ($this->is_http_mode()) { |
499 | if ($this->is_http_mode()) { |
500 | if ($this->initialized) { |
500 | if ($this->initialized) { |
501 | if ($after_visual_output) { |
501 | if ($after_visual_output) { |
502 | $this->html_after .= $text; |
502 | $this->html_after .= $text; |
503 | } else { |
503 | } else { |
504 | $this->html_before .= $text; |
504 | $this->html_before .= $text; |
505 | } |
505 | } |
506 | } else { |
506 | } else { |
507 | echo $text; |
507 | echo $text; |
508 | } |
508 | } |
509 | } |
509 | } |
510 | } |
510 | } |
511 | 511 | ||
512 | protected function resetArguments() { |
512 | protected function resetArguments() { |
513 | $this->argWarning = null; |
513 | $this->argWarning = null; |
514 | $this->argCritical = null; |
514 | $this->argCritical = null; |
515 | $this->argVersion = null; |
515 | $this->argVersion = null; |
516 | $this->argVerbosity = null; |
516 | $this->argVerbosity = null; |
517 | $this->argTimeout = null; |
517 | $this->argTimeout = null; |
518 | $this->argHelp = null; |
518 | $this->argHelp = null; |
519 | // $this->argUsage = null; |
519 | // $this->argUsage = null; |
520 | 520 | ||
521 | // Also remove cache |
521 | // Also remove cache |
522 | $this->argWarning = null; |
522 | $this->argWarning = null; |
523 | $this->argCritical = null; |
523 | $this->argCritical = null; |
524 | } |
524 | } |
525 | 525 | ||
526 | // e.g. $args = "wcVvht" |
526 | // e.g. $args = "wcVvht" |
527 | public function registerExpectedStandardArguments($args) { |
527 | public function registerExpectedStandardArguments($args) { |
528 | $this->resetArguments(); |
528 | $this->resetArguments(); |
529 | 529 | ||
530 | for ($i=0; $i<strlen($args); $i++) { |
530 | for ($i=0; $i<strlen($args); $i++) { |
531 | switch ($args[$i]) { |
531 | switch ($args[$i]) { |
532 | case 'w': |
532 | case 'w': |
533 | $this->addExpectedArgument($this->argWarning = new VNagArgument('w', 'warning', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$warning_range)); |
533 | $this->addExpectedArgument($this->argWarning = new VNagArgument('w', 'warning', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$warning_range)); |
534 | break; |
534 | break; |
535 | case 'c': |
535 | case 'c': |
536 | $this->addExpectedArgument($this->argCritical = new VNagArgument('c', 'critical', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$critical_range)); |
536 | $this->addExpectedArgument($this->argCritical = new VNagArgument('c', 'critical', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$critical_range)); |
537 | break; |
537 | break; |
538 | case 'V': |
538 | case 'V': |
539 | $this->addExpectedArgument($this->argVersion = new VNagArgument('V', 'version', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_version)); |
539 | $this->addExpectedArgument($this->argVersion = new VNagArgument('V', 'version', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_version)); |
540 | break; |
540 | break; |
541 | case 'v': |
541 | case 'v': |
542 | // In HTTP: -vvv is &v[]=&v[]=&v[]= |
542 | // In HTTP: -vvv is &v[]=&v[]=&v[]= |
543 | $this->addExpectedArgument($this->argVerbosity = new VNagArgument('v', 'verbose', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$verbosity_helptext)); |
543 | $this->addExpectedArgument($this->argVerbosity = new VNagArgument('v', 'verbose', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$verbosity_helptext)); |
544 | break; |
544 | break; |
545 | case 't': |
545 | case 't': |
546 | // Attention: not every plugin supports it because of declare(ticks=1) needs to be written in the main script |
546 | // Attention: not every plugin supports it because of declare(ticks=1) needs to be written in the main script |
547 | $this->addExpectedArgument($this->argTimeout = new VNagArgument('t', 'timeout', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_seconds, VNagLang::$timeout_helptext)); |
547 | $this->addExpectedArgument($this->argTimeout = new VNagArgument('t', 'timeout', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_seconds, VNagLang::$timeout_helptext)); |
548 | break; |
548 | break; |
549 | // case '?': |
549 | // case '?': |
550 | case 'h': |
550 | case 'h': |
551 | $this->addExpectedArgument($this->argHelp = new VNagArgument('h', 'help', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$help_helptext)); |
551 | $this->addExpectedArgument($this->argHelp = new VNagArgument('h', 'help', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$help_helptext)); |
552 | break; |
552 | break; |
553 | default: |
553 | default: |
554 | $letter = $args[$i]; |
554 | $letter = $args[$i]; |
555 | throw new VNagInvalidStandardArgument(sprintf(VNagLang::$no_standard_arguments_with_letter, $letter)); |
555 | throw new VNagInvalidStandardArgument(sprintf(VNagLang::$no_standard_arguments_with_letter, $letter)); |
556 | #break; |
556 | #break; |
557 | } |
557 | } |
558 | } |
558 | } |
559 | } |
559 | } |
560 | 560 | ||
561 | public function addExpectedArgument($argObj) { |
561 | public function addExpectedArgument($argObj) { |
562 | // Emulate C++ "friend" access to hidden functions |
562 | // Emulate C++ "friend" access to hidden functions |
563 | 563 | ||
564 | // $this->helpObj->_addOption($argObj); |
564 | // $this->helpObj->_addOption($argObj); |
565 | $helpObjAddEntryMethod = new ReflectionMethod($this->helpObj, '_addOption'); |
565 | $helpObjAddEntryMethod = new ReflectionMethod($this->helpObj, '_addOption'); |
566 | $helpObjAddEntryMethod->setAccessible(true); |
566 | $helpObjAddEntryMethod->setAccessible(true); |
567 | $helpObjAddEntryMethod->invoke($this->helpObj, $argObj); |
567 | $helpObjAddEntryMethod->invoke($this->helpObj, $argObj); |
568 | 568 | ||
569 | // $this->argHandler->_addExpectedArgument($argObj); |
569 | // $this->argHandler->_addExpectedArgument($argObj); |
570 | $argHandlerAddEntryMethod = new ReflectionMethod($this->argHandler, '_addExpectedArgument'); |
570 | $argHandlerAddEntryMethod = new ReflectionMethod($this->argHandler, '_addExpectedArgument'); |
571 | $argHandlerAddEntryMethod->setAccessible(true); |
571 | $argHandlerAddEntryMethod->setAccessible(true); |
572 | $argHandlerAddEntryMethod->invoke($this->argHandler, $argObj); |
572 | $argHandlerAddEntryMethod->invoke($this->argHandler, $argObj); |
573 | } |
573 | } |
574 | 574 | ||
575 | protected function createArgumentHandler() { |
575 | protected function createArgumentHandler() { |
576 | $this->argHandler = new VNagArgumentHandler(); |
576 | $this->argHandler = new VNagArgumentHandler(); |
577 | } |
577 | } |
578 | 578 | ||
579 | protected function createHelpObject() { |
579 | protected function createHelpObject() { |
580 | $this->helpObj = new VNagHelp(); |
580 | $this->helpObj = new VNagHelp(); |
581 | } |
581 | } |
582 | 582 | ||
583 | protected function checkInitialized() { |
583 | protected function checkInitialized() { |
584 | if (!$this->initialized) throw new VNagFunctionCallOutsideSession(); |
584 | if (!$this->initialized) throw new VNagFunctionCallOutsideSession(); |
585 | } |
585 | } |
586 | 586 | ||
587 | protected function getVerbosityLevel() { |
587 | protected function getVerbosityLevel() { |
588 | $this->checkInitialized(); // if (!$this->initialized) return false; |
588 | $this->checkInitialized(); // if (!$this->initialized) return false; |
589 | 589 | ||
590 | if (!isset($this->argVerbosity)) { |
590 | if (!isset($this->argVerbosity)) { |
591 | //The verbose argument is always optional |
591 | //The verbose argument is always optional |
592 | //throw new VNagRequiredArgumentNotRegistered('-v'); |
592 | //throw new VNagRequiredArgumentNotRegistered('-v'); |
593 | return self::VERBOSITY_SUMMARY; |
593 | return self::VERBOSITY_SUMMARY; |
594 | } else { |
594 | } else { |
595 | $level = $this->argVerbosity->count(); |
595 | $level = $this->argVerbosity->count(); |
596 | if ($level > self::MAX_VERBOSITY) $level = self::MAX_VERBOSITY; |
596 | if ($level > self::MAX_VERBOSITY) $level = self::MAX_VERBOSITY; |
597 | return $level; |
597 | return $level; |
598 | } |
598 | } |
599 | } |
599 | } |
600 | 600 | ||
601 | public function getWarningRange($argumentNumber=0) { |
601 | public function getWarningRange($argumentNumber=0) { |
602 | $this->checkInitialized(); // if (!$this->initialized) return false; |
602 | $this->checkInitialized(); // if (!$this->initialized) return false; |
603 | 603 | ||
604 | if (!isset($this->warningRanges[$argumentNumber])) { |
604 | if (!isset($this->warningRanges[$argumentNumber])) { |
605 | if (!is_null($this->argWarning)) { |
605 | if (!is_null($this->argWarning)) { |
606 | $warning = $this->argWarning->getValue(); |
606 | $warning = $this->argWarning->getValue(); |
607 | if (!is_null($warning)) { |
607 | if (!is_null($warning)) { |
608 | $vals = explode(',',$warning); |
608 | $vals = explode(',',$warning); |
609 | foreach ($vals as $number => $val) { |
609 | foreach ($vals as $number => $val) { |
610 | if (_empty($val)) { |
610 | if (_empty($val)) { |
611 | $this->warningRanges[$number] = null; |
611 | $this->warningRanges[$number] = null; |
612 | } else { |
612 | } else { |
613 | $singleValueBehavior = isset($this->warningSingleValueRangeBehaviors[$number]) ? $this->warningSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT; |
613 | $singleValueBehavior = isset($this->warningSingleValueRangeBehaviors[$number]) ? $this->warningSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT; |
614 | $this->warningRanges[$number] = new VNagRange($val, $singleValueBehavior); |
614 | $this->warningRanges[$number] = new VNagRange($val, $singleValueBehavior); |
615 | } |
615 | } |
616 | } |
616 | } |
617 | } else { |
617 | } else { |
618 | $this->warningRanges[0] = $this->default_warning_range; |
618 | $this->warningRanges[0] = $this->default_warning_range; |
619 | } |
619 | } |
620 | } else { |
620 | } else { |
621 | return null; |
621 | return null; |
622 | } |
622 | } |
623 | } |
623 | } |
624 | 624 | ||
625 | if (isset($this->warningRanges[$argumentNumber])) { |
625 | if (isset($this->warningRanges[$argumentNumber])) { |
626 | return $this->warningRanges[$argumentNumber]; |
626 | return $this->warningRanges[$argumentNumber]; |
627 | } else { |
627 | } else { |
628 | return null; |
628 | return null; |
629 | } |
629 | } |
630 | } |
630 | } |
631 | 631 | ||
632 | public function getCriticalRange($argumentNumber=0) { |
632 | public function getCriticalRange($argumentNumber=0) { |
633 | $this->checkInitialized(); // if (!$this->initialized) return false; |
633 | $this->checkInitialized(); // if (!$this->initialized) return false; |
634 | 634 | ||
635 | if (!isset($this->criticalRanges[$argumentNumber])) { |
635 | if (!isset($this->criticalRanges[$argumentNumber])) { |
636 | if (!is_null($this->argCritical)) { |
636 | if (!is_null($this->argCritical)) { |
637 | $critical = $this->argCritical->getValue(); |
637 | $critical = $this->argCritical->getValue(); |
638 | if (!is_null($critical)) { |
638 | if (!is_null($critical)) { |
639 | $vals = explode(',',$critical); |
639 | $vals = explode(',',$critical); |
640 | foreach ($vals as $number => $val) { |
640 | foreach ($vals as $number => $val) { |
641 | $singleValueBehavior = isset($this->criticalSingleValueRangeBehaviors[$number]) ? $this->criticalSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT; |
641 | $singleValueBehavior = isset($this->criticalSingleValueRangeBehaviors[$number]) ? $this->criticalSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT; |
642 | $this->criticalRanges[$number] = new VNagRange($val, $singleValueBehavior); |
642 | $this->criticalRanges[$number] = new VNagRange($val, $singleValueBehavior); |
643 | } |
643 | } |
644 | } else { |
644 | } else { |
645 | $this->criticalRanges[0] = $this->default_critical_range; |
645 | $this->criticalRanges[0] = $this->default_critical_range; |
646 | } |
646 | } |
647 | } else { |
647 | } else { |
648 | return null; |
648 | return null; |
649 | } |
649 | } |
650 | } |
650 | } |
651 | 651 | ||
652 | if (isset($this->criticalRanges[$argumentNumber])) { |
652 | if (isset($this->criticalRanges[$argumentNumber])) { |
653 | return $this->criticalRanges[$argumentNumber]; |
653 | return $this->criticalRanges[$argumentNumber]; |
654 | } else { |
654 | } else { |
655 | return null; |
655 | return null; |
656 | } |
656 | } |
657 | } |
657 | } |
658 | 658 | ||
659 | public function checkAgainstWarningRange($values, $force=true, $autostatus=true, $argumentNumber=0) { |
659 | public function checkAgainstWarningRange($values, $force=true, $autostatus=true, $argumentNumber=0) { |
660 | $this->checkInitialized(); // if (!$this->initialized) return; |
660 | $this->checkInitialized(); // if (!$this->initialized) return; |
661 | 661 | ||
662 | if (!$this->getArgumentHandler()->isArgRegistered('w')) { |
662 | if (!$this->getArgumentHandler()->isArgRegistered('w')) { |
663 | // Developer's mistake: The argument is not in the list of expected arguments |
663 | // Developer's mistake: The argument is not in the list of expected arguments |
664 | throw new VNagRequiredArgumentNotRegistered('-w'); |
664 | throw new VNagRequiredArgumentNotRegistered('-w'); |
665 | } |
665 | } |
666 | 666 | ||
667 | $wr = $this->getWarningRange($argumentNumber); |
667 | $wr = $this->getWarningRange($argumentNumber); |
668 | if (isset($wr)) { |
668 | if (isset($wr)) { |
669 | if ($wr->checkAlert($values)) { |
669 | if ($wr->checkAlert($values)) { |
670 | if ($autostatus) $this->setStatus(VNag::STATUS_WARNING); |
670 | if ($autostatus) $this->setStatus(VNag::STATUS_WARNING); |
671 | return true; |
671 | return true; |
672 | } else { |
672 | } else { |
673 | if ($autostatus) $this->setStatus(VNag::STATUS_OK); |
673 | if ($autostatus) $this->setStatus(VNag::STATUS_OK); |
674 | return false; |
674 | return false; |
675 | } |
675 | } |
676 | } else { |
676 | } else { |
677 | if ($force) { |
677 | if ($force) { |
678 | // User's mistake: They did not pass the argument to the plugin |
678 | // User's mistake: They did not pass the argument to the plugin |
679 | if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) { |
679 | if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) { |
680 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_warning_ranges, $argumentNumber+1)); |
680 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_warning_ranges, $argumentNumber+1)); |
681 | } else { |
681 | } else { |
682 | throw new VNagRequiredArgumentMissing('-w'); |
682 | throw new VNagRequiredArgumentMissing('-w'); |
683 | } |
683 | } |
684 | } |
684 | } |
685 | } |
685 | } |
686 | } |
686 | } |
687 | 687 | ||
688 | public function checkAgainstCriticalRange($values, $force=true, $autostatus=true, $argumentNumber=0) { |
688 | public function checkAgainstCriticalRange($values, $force=true, $autostatus=true, $argumentNumber=0) { |
689 | $this->checkInitialized(); // if (!$this->initialized) return; |
689 | $this->checkInitialized(); // if (!$this->initialized) return; |
690 | 690 | ||
691 | if (!$this->getArgumentHandler()->isArgRegistered('c')) { |
691 | if (!$this->getArgumentHandler()->isArgRegistered('c')) { |
692 | // Developer's mistake: The argument is not in the list of expected arguments |
692 | // Developer's mistake: The argument is not in the list of expected arguments |
693 | throw new VNagRequiredArgumentNotRegistered('-c'); |
693 | throw new VNagRequiredArgumentNotRegistered('-c'); |
694 | } |
694 | } |
695 | 695 | ||
696 | $cr = $this->getCriticalRange($argumentNumber); |
696 | $cr = $this->getCriticalRange($argumentNumber); |
697 | if (isset($cr)) { |
697 | if (isset($cr)) { |
698 | if ($cr->checkAlert($values)) { |
698 | if ($cr->checkAlert($values)) { |
699 | if ($autostatus) $this->setStatus(VNag::STATUS_CRITICAL); |
699 | if ($autostatus) $this->setStatus(VNag::STATUS_CRITICAL); |
700 | return true; |
700 | return true; |
701 | } else { |
701 | } else { |
702 | if ($autostatus) $this->setStatus(VNag::STATUS_OK); |
702 | if ($autostatus) $this->setStatus(VNag::STATUS_OK); |
703 | return false; |
703 | return false; |
704 | } |
704 | } |
705 | } else { |
705 | } else { |
706 | if ($force) { |
706 | if ($force) { |
707 | // User's mistake: They did not pass the argument to the plugin |
707 | // User's mistake: They did not pass the argument to the plugin |
708 | if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) { |
708 | if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) { |
709 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_critical_ranges, $argumentNumber+1)); |
709 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_critical_ranges, $argumentNumber+1)); |
710 | } else { |
710 | } else { |
711 | throw new VNagRequiredArgumentMissing('-c'); |
711 | throw new VNagRequiredArgumentMissing('-c'); |
712 | } |
712 | } |
713 | } |
713 | } |
714 | } |
714 | } |
715 | } |
715 | } |
716 | 716 | ||
717 | protected static function getBaddestExitcode($code1, $code2) { |
717 | protected static function getBaddestExitcode($code1, $code2) { |
718 | return max($code1, $code2); |
718 | return max($code1, $code2); |
719 | } |
719 | } |
720 | 720 | ||
721 | # DO NOT CALL MANUALLY |
721 | # DO NOT CALL MANUALLY |
722 | # Unfortunately, this function has to be public, otherwise register_shutdown_function() wouldn't work |
722 | # Unfortunately, this function has to be public, otherwise register_shutdown_function() wouldn't work |
723 | public static function _shutdownHandler() { |
723 | public static function _shutdownHandler() { |
724 | if (!self::is_http_mode()) { |
724 | if (!self::is_http_mode()) { |
725 | exit((int)self::$exitcode); |
725 | exit((int)self::$exitcode); |
726 | } |
726 | } |
727 | } |
727 | } |
728 | 728 | ||
729 | protected function _exit($code) { |
729 | protected function _exit($code) { |
730 | self::$exitcode = $this->getBaddestExitcode($code, self::$exitcode); |
730 | self::$exitcode = $this->getBaddestExitcode($code, self::$exitcode); |
731 | } |
731 | } |
732 | 732 | ||
733 | private $constructed = false; |
733 | private $constructed = false; |
734 | function __construct() { |
734 | function __construct() { |
735 | $this->createHelpObject(); |
735 | $this->createHelpObject(); |
736 | $this->createArgumentHandler(); |
736 | $this->createArgumentHandler(); |
737 | 737 | ||
738 | $this->addExpectedArgument($this->argUsage = new VNagArgument('?', '', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_usage)); |
738 | $this->addExpectedArgument($this->argUsage = new VNagArgument('?', '', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_usage)); |
739 | 739 | ||
740 | $this->constructed = true; |
740 | $this->constructed = true; |
741 | } |
741 | } |
742 | 742 | ||
743 | function __destruct() { |
743 | function __destruct() { |
744 | if (Timeouter::started()) { |
744 | if (Timeouter::started()) { |
745 | Timeouter::end(); |
745 | Timeouter::end(); |
746 | } |
746 | } |
747 | } |
747 | } |
748 | 748 | ||
749 | public function run() { |
749 | public function run() { |
750 | global $inside_vnag_run; |
750 | global $inside_vnag_run; |
751 | 751 | ||
752 | $inside_vnag_run = true; |
752 | $inside_vnag_run = true; |
753 | try { |
753 | try { |
754 | if (!$this->constructed) { |
754 | if (!$this->constructed) { |
755 | throw new VNagNotConstructed(VNagLang::$notConstructed); |
755 | throw new VNagNotConstructed(VNagLang::$notConstructed); |
756 | } |
756 | } |
757 | 757 | ||
758 | try { |
758 | try { |
759 | $this->initialized = true; |
759 | $this->initialized = true; |
760 | $this->html_before = ''; |
760 | $this->html_before = ''; |
761 | $this->html_after = ''; |
761 | $this->html_after = ''; |
762 | $this->setStatus(null, true); |
762 | $this->setStatus(null, true); |
763 | $this->messages = array(); |
763 | $this->messages = array(); |
764 | 764 | ||
765 | register_shutdown_function(array($this, '_shutdownHandler')); |
765 | register_shutdown_function(array($this, '_shutdownHandler')); |
766 | 766 | ||
767 | if ($this->argHandler->illegalUsage()) { |
767 | if ($this->argHandler->illegalUsage()) { |
768 | $content = $this->helpObj->printUsagePage(); |
768 | $content = $this->helpObj->printUsagePage(); |
769 | $this->setStatus(VNag::STATUS_UNKNOWN); |
769 | $this->setStatus(VNag::STATUS_UNKNOWN); |
770 | 770 | ||
771 | if ($this->is_http_mode()) { |
771 | if ($this->is_http_mode()) { |
772 | echo $this->html_before; |
772 | echo $this->html_before; |
773 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
773 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
774 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
774 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
775 | echo $this->html_after; |
775 | echo $this->html_after; |
776 | return; // cancel |
776 | return; // cancel |
777 | } else { |
777 | } else { |
778 | echo $content; |
778 | echo $content; |
779 | return $this->_exit($this->status); |
779 | return $this->_exit($this->status); |
780 | } |
780 | } |
781 | } |
781 | } |
782 | 782 | ||
783 | if (!is_null($this->argVersion) && ($this->argVersion->available())) { |
783 | if (!is_null($this->argVersion) && ($this->argVersion->available())) { |
784 | $content = $this->helpObj->printVersionPage(); |
784 | $content = $this->helpObj->printVersionPage(); |
785 | $this->setStatus(VNag::STATUS_UNKNOWN); |
785 | $this->setStatus(VNag::STATUS_UNKNOWN); |
786 | 786 | ||
787 | if ($this->is_http_mode()) { |
787 | if ($this->is_http_mode()) { |
788 | echo $this->html_before; |
788 | echo $this->html_before; |
789 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
789 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
790 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
790 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
791 | echo $this->html_after; |
791 | echo $this->html_after; |
792 | return; // cancel |
792 | return; // cancel |
793 | } else { |
793 | } else { |
794 | echo $content; |
794 | echo $content; |
795 | return $this->_exit($this->status); |
795 | return $this->_exit($this->status); |
796 | } |
796 | } |
797 | } |
797 | } |
798 | 798 | ||
799 | if (!is_null($this->argHelp) && ($this->argHelp->available())) { |
799 | if (!is_null($this->argHelp) && ($this->argHelp->available())) { |
800 | $content = $this->helpObj->printHelpPage(); |
800 | $content = $this->helpObj->printHelpPage(); |
801 | $this->setStatus(VNag::STATUS_UNKNOWN); |
801 | $this->setStatus(VNag::STATUS_UNKNOWN); |
802 | 802 | ||
803 | if ($this->is_http_mode()) { |
803 | if ($this->is_http_mode()) { |
804 | echo $this->html_before; |
804 | echo $this->html_before; |
805 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
805 | if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content); |
806 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
806 | if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content); |
807 | echo $this->html_after; |
807 | echo $this->html_after; |
808 | return; // cancel |
808 | return; // cancel |
809 | } else { |
809 | } else { |
810 | echo $content; |
810 | echo $content; |
811 | return $this->_exit($this->status); |
811 | return $this->_exit($this->status); |
812 | } |
812 | } |
813 | } |
813 | } |
814 | 814 | ||
815 | // Initialize ranges (and check their validity) |
815 | // Initialize ranges (and check their validity) |
816 | $this->getWarningRange(); |
816 | $this->getWarningRange(); |
817 | $this->getCriticalRange(); |
817 | $this->getCriticalRange(); |
818 | 818 | ||
819 | if (!is_null($this->argTimeout)) { |
819 | if (!is_null($this->argTimeout)) { |
820 | $timeout = $this->argTimeout->getValue(); |
820 | $timeout = $this->argTimeout->getValue(); |
821 | if (!is_null($timeout)) { |
821 | if (!is_null($timeout)) { |
822 | Timeouter::start($timeout); |
822 | Timeouter::start($timeout); |
823 | } |
823 | } |
824 | } |
824 | } |
825 | 825 | ||
826 | ob_start(); |
826 | ob_start(); |
827 | $init_ob_level = ob_get_level(); |
827 | $init_ob_level = ob_get_level(); |
828 | try { |
828 | try { |
829 | $this->cbRun(); |
829 | $this->cbRun(); |
830 | 830 | ||
831 | // This will NOT be put in the 'finally' block, because otherwise it would trigger if an Exception happened (Which clears the OB) |
831 | // This will NOT be put in the 'finally' block, because otherwise it would trigger if an Exception happened (Which clears the OB) |
832 | if (ob_get_level() < $init_ob_level) throw new VNagImplementationErrorException(VNagLang::$output_level_lowered); |
832 | if (ob_get_level() < $init_ob_level) throw new VNagImplementationErrorException(VNagLang::$output_level_lowered); |
833 | } finally { |
833 | } finally { |
834 | while (ob_get_level() > $init_ob_level) @ob_end_clean(); |
834 | while (ob_get_level() > $init_ob_level) @ob_end_clean(); |
835 | } |
835 | } |
836 | 836 | ||
837 | if (is_null($this->status)) $this->setStatus($this->default_status,true); |
837 | if (is_null($this->status)) $this->setStatus($this->default_status,true); |
838 | 838 | ||
839 | $outputType = VNag::OUTPUT_NORMAL; |
839 | $outputType = VNag::OUTPUT_NORMAL; |
840 | } catch (Exception $e) { |
840 | } catch (Exception $e) { |
841 | $this->handleException($e); |
841 | $this->handleException($e); |
842 | $outputType = VNag::OUTPUT_EXCEPTION; |
842 | $outputType = VNag::OUTPUT_EXCEPTION; |
843 | } |
843 | } |
844 | 844 | ||
845 | if ($this->is_http_mode()) { |
845 | if ($this->is_http_mode()) { |
846 | echo $this->html_before; |
846 | echo $this->html_before; |
847 | if ($this->http_invisible_output & $outputType) { |
847 | if ($this->http_invisible_output & $outputType) { |
848 | echo $this->writeInvisibleHTML(); |
848 | echo $this->writeInvisibleHTML(); |
849 | } |
849 | } |
850 | if ($this->http_visual_output & $outputType) { |
850 | if ($this->http_visual_output & $outputType) { |
851 | echo $this->writeVisualHTML(); |
851 | echo $this->writeVisualHTML(); |
852 | } |
852 | } |
853 | echo $this->html_after; |
853 | echo $this->html_after; |
854 | } else { |
854 | } else { |
855 | echo $this->getNagiosConsoleText(); |
855 | echo $this->getNagiosConsoleText(); |
856 | return $this->_exit($this->status); |
856 | return $this->_exit($this->status); |
857 | } |
857 | } |
858 | 858 | ||
859 | Timeouter::end(); |
859 | Timeouter::end(); |
860 | } finally { |
860 | } finally { |
861 | $inside_vnag_run = false; |
861 | $inside_vnag_run = false; |
862 | } |
862 | } |
863 | } |
863 | } |
864 | 864 | ||
865 | private function getNagiosConsoleText() { |
865 | private function getNagiosConsoleText() { |
866 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
866 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
867 | // 1. space separated list of label/value pairs |
867 | // 1. space separated list of label/value pairs |
868 | $ary_perfdata = $this->getPerformanceData(); |
868 | $ary_perfdata = $this->getPerformanceData(); |
869 | $performancedata_first = array_shift($ary_perfdata); |
869 | $performancedata_first = array_shift($ary_perfdata); |
870 | $performancedata_rest = implode(' ', $ary_perfdata); |
870 | $performancedata_rest = implode(' ', $ary_perfdata); |
871 | 871 | ||
872 | $status_text = VNagLang::status($this->status, $this->statusmodel); |
872 | $status_text = VNagLang::status($this->status, $this->statusmodel); |
873 | if (_empty($this->getHeadline())) { |
873 | if (_empty($this->getHeadline())) { |
874 | $content = $status_text; |
874 | $content = $status_text; |
875 | } else { |
875 | } else { |
876 | if ($this->show_status_in_headline) { |
876 | if ($this->show_status_in_headline) { |
877 | $content = $status_text.': '.$this->getHeadline(); |
877 | $content = $status_text.': '.$this->getHeadline(); |
878 | } else { |
878 | } else { |
879 | $content = $this->getHeadline(); |
879 | $content = $this->getHeadline(); |
880 | } |
880 | } |
881 | } |
881 | } |
882 | 882 | ||
883 | if (!_empty($performancedata_first)) $content .= '|'.trim($performancedata_first); |
883 | if (!_empty($performancedata_first)) $content .= '|'.trim($performancedata_first); |
884 | $content .= "\n"; |
884 | $content .= "\n"; |
885 | if (!_empty($this->verbose_info)) { |
885 | if (!_empty($this->verbose_info)) { |
886 | //$content .= "\n".VNagLang::$verbose_info.":\n\n"; |
886 | //$content .= "\n".VNagLang::$verbose_info.":\n\n"; |
887 | $content .= trim($this->verbose_info); |
887 | $content .= trim($this->verbose_info); |
888 | } |
888 | } |
889 | if (!_empty($performancedata_rest)) $content .= '|'.trim($performancedata_rest); |
889 | if (!_empty($performancedata_rest)) $content .= '|'.trim($performancedata_rest); |
890 | $content .= "\n"; |
890 | $content .= "\n"; |
891 | 891 | ||
892 | return trim($content)."\n"; |
892 | return trim($content)."\n"; |
893 | } |
893 | } |
894 | 894 | ||
895 | abstract protected function cbRun(); |
895 | abstract protected function cbRun(); |
896 | 896 | ||
897 | public function addPerformanceData($prefDataObj, $move_to_font=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
897 | public function addPerformanceData($prefDataObj, $move_to_font=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
898 | $this->checkInitialized(); // if (!$this->initialized) return; |
898 | $this->checkInitialized(); // if (!$this->initialized) return; |
899 | 899 | ||
900 | if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v'); |
900 | if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v'); |
901 | if (self::getVerbosityLevel() < $verbosityLevel) return false; |
901 | if (self::getVerbosityLevel() < $verbosityLevel) return false; |
902 | 902 | ||
903 | if ($move_to_font) { |
903 | if ($move_to_font) { |
904 | array_unshift($this->performanceDataObjects, $prefDataObj); |
904 | array_unshift($this->performanceDataObjects, $prefDataObj); |
905 | } else { |
905 | } else { |
906 | $this->performanceDataObjects[] = $prefDataObj; |
906 | $this->performanceDataObjects[] = $prefDataObj; |
907 | } |
907 | } |
908 | 908 | ||
909 | return true; |
909 | return true; |
910 | } |
910 | } |
911 | 911 | ||
912 | public function getPerformanceData() { |
912 | public function getPerformanceData() { |
913 | $this->checkInitialized(); // if (!$this->initialized) return null; |
913 | $this->checkInitialized(); // if (!$this->initialized) return null; |
914 | 914 | ||
915 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
915 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
916 | // 1. space separated list of label/value pairs |
916 | // 1. space separated list of label/value pairs |
917 | return $this->performanceDataObjects; |
917 | return $this->performanceDataObjects; |
918 | } |
918 | } |
919 | 919 | ||
920 | public function removePerformanceData($prefDataObj) { |
920 | public function removePerformanceData($prefDataObj) { |
921 | if (($key = array_search($prefDataObj, $this->performanceDataObjects, true)) !== false) { |
921 | if (($key = array_search($prefDataObj, $this->performanceDataObjects, true)) !== false) { |
922 | unset($this->performanceDataObjects[$key]); |
922 | unset($this->performanceDataObjects[$key]); |
923 | return true; |
923 | return true; |
924 | } else { |
924 | } else { |
925 | return false; |
925 | return false; |
926 | } |
926 | } |
927 | } |
927 | } |
928 | 928 | ||
929 | public function clearPerformanceData() { |
929 | public function clearPerformanceData() { |
930 | $this->performanceDataObjects = array(); |
930 | $this->performanceDataObjects = array(); |
931 | } |
931 | } |
932 | 932 | ||
933 | public function getVerboseInfo() { |
933 | public function getVerboseInfo() { |
934 | return $this->verbose_info; |
934 | return $this->verbose_info; |
935 | } |
935 | } |
936 | 936 | ||
937 | public function clearVerboseInfo() { |
937 | public function clearVerboseInfo() { |
938 | $this->verbose_info = ''; |
938 | $this->verbose_info = ''; |
939 | } |
939 | } |
940 | 940 | ||
941 | private function writeVisualHTML($special_content=null) { |
941 | private function writeVisualHTML($special_content=null) { |
942 | if (!_empty($special_content)) { |
942 | if (!_empty($special_content)) { |
943 | $content = $special_content; |
943 | $content = $special_content; |
944 | } else { |
944 | } else { |
945 | $content = strtoupper(VNagLang::$status.': '.VNagLang::status($this->status, $this->statusmodel))."\n\n"; |
945 | $content = strtoupper(VNagLang::$status.': '.VNagLang::status($this->status, $this->statusmodel))."\n\n"; |
946 | 946 | ||
947 | $content .= strtoupper(VNagLang::$message).":\n"; |
947 | $content .= strtoupper(VNagLang::$message).":\n"; |
948 | $status_text = VNagLang::status($this->status, $this->statusmodel); |
948 | $status_text = VNagLang::status($this->status, $this->statusmodel); |
949 | if (_empty($this->getHeadline())) { |
949 | if (_empty($this->getHeadline())) { |
950 | $content .= $status_text; |
950 | $content .= $status_text; |
951 | } else { |
951 | } else { |
952 | if ($this->show_status_in_headline) { |
952 | if ($this->show_status_in_headline) { |
953 | $content .= $status_text.': '.trim($this->getHeadline()); |
953 | $content .= $status_text.': '.trim($this->getHeadline()); |
954 | } else { |
954 | } else { |
955 | $content .= trim($this->getHeadline()); |
955 | $content .= trim($this->getHeadline()); |
956 | } |
956 | } |
957 | } |
957 | } |
958 | $content .= "\n\n"; |
958 | $content .= "\n\n"; |
959 | 959 | ||
960 | if (!_empty($this->verbose_info)) { |
960 | if (!_empty($this->verbose_info)) { |
961 | $content .= strtoupper(VNagLang::$verbose_info).":\n".trim($this->verbose_info)."\n\n"; |
961 | $content .= strtoupper(VNagLang::$verbose_info).":\n".trim($this->verbose_info)."\n\n"; |
962 | } |
962 | } |
963 | 963 | ||
964 | $perfdata = $this->getPerformanceData(); |
964 | $perfdata = $this->getPerformanceData(); |
965 | if (count($perfdata) > 0) { |
965 | if (count($perfdata) > 0) { |
966 | $content .= strtoupper(VNagLang::$performance_data).":\n"; |
966 | $content .= strtoupper(VNagLang::$performance_data).":\n"; |
967 | foreach ($perfdata as $pd) { |
967 | foreach ($perfdata as $pd) { |
968 | $content .= trim($pd)."\n"; |
968 | $content .= trim($pd)."\n"; |
969 | } |
969 | } |
970 | $content .= "\n"; |
970 | $content .= "\n"; |
971 | } |
971 | } |
972 | } |
972 | } |
973 | 973 | ||
974 | $colorinfo = ''; |
974 | $colorinfo = ''; |
975 | $status = $this->getStatus(); |
975 | $status = $this->getStatus(); |
976 | 976 | ||
977 | if ($status == VNag::STATUS_OK) $colorinfo = ' style="background-color:green;color:white;font-weight:bold"'; |
977 | if ($status == VNag::STATUS_OK) $colorinfo = ' style="background-color:green;color:white;font-weight:bold"'; |
978 | else if ($status == VNag::STATUS_WARNING) $colorinfo = ' style="background-color:yellow;color:black;font-weight:bold"'; |
978 | else if ($status == VNag::STATUS_WARNING) $colorinfo = ' style="background-color:yellow;color:black;font-weight:bold"'; |
979 | else if ($status == VNag::STATUS_CRITICAL) $colorinfo = ' style="background-color:red;color:white;font-weight:bold"'; |
979 | else if ($status == VNag::STATUS_CRITICAL) $colorinfo = ' style="background-color:red;color:white;font-weight:bold"'; |
980 | else if ($status == VNag::STATUS_ERROR) $colorinfo = ' style="background-color:purple;color:white;font-weight:bold"'; |
980 | else if ($status == VNag::STATUS_ERROR) $colorinfo = ' style="background-color:purple;color:white;font-weight:bold"'; |
981 | else /* if ($status == VNag::STATUS_UNKNOWN) */ $colorinfo = ' style="background-color:lightgray;color:black;font-weight:bold"'; |
981 | else /* if ($status == VNag::STATUS_UNKNOWN) */ $colorinfo = ' style="background-color:lightgray;color:black;font-weight:bold"'; |
982 | 982 | ||
983 | $html_content = trim($content); |
983 | $html_content = trim($content); |
984 | $html_content = htmlentities($html_content); |
984 | $html_content = htmlentities($html_content); |
985 | $html_content = str_replace(' ', ' ', $html_content); |
985 | $html_content = str_replace(' ', ' ', $html_content); |
986 | $html_content = nl2br($html_content); |
986 | $html_content = nl2br($html_content); |
987 | 987 | ||
988 | // FUT: Allow individual design via CSS |
988 | // FUT: Allow individual design via CSS |
989 | return '<table border="1" cellspacing="2" cellpadding="2" style="width:100%" class="vnag_table">'. |
989 | return '<table border="1" cellspacing="2" cellpadding="2" style="width:100%" class="vnag_table">'. |
990 | '<tr'.$colorinfo.' class="vnag_title_row">'. |
990 | '<tr'.$colorinfo.' class="vnag_title_row">'. |
991 | '<td>'.VNagLang::$nagios_output.'</td>'. |
991 | '<td>'.VNagLang::$nagios_output.'</td>'. |
992 | '</tr>'. |
992 | '</tr>'. |
993 | '<tr class="vnag_message_row">'. |
993 | '<tr class="vnag_message_row">'. |
994 | '<td><code>'. |
994 | '<td><code>'. |
995 | $html_content. |
995 | $html_content. |
996 | '</code></td>'. |
996 | '</code></td>'. |
997 | '</tr>'. |
997 | '</tr>'. |
998 | '</table>'; |
998 | '</table>'; |
999 | } |
999 | } |
1000 | 1000 | ||
1001 | protected function readInvisibleHTML($html) { |
1001 | protected function readInvisibleHTML($html) { |
1002 | $this->checkInitialized(); // if (!$this->initialized) return; |
1002 | $this->checkInitialized(); // if (!$this->initialized) return; |
1003 | 1003 | ||
1004 | $doc = new DOMDocument(); // Requires: aptitude install php-dom |
1004 | $doc = new DOMDocument(); // Requires: aptitude install php-dom |
1005 | @$doc->loadHTML($html); // added '@' because we don't want a warning for the non-standard <vnag> tag |
1005 | @$doc->loadHTML($html); // added '@' because we don't want a warning for the non-standard <vnag> tag |
1006 | 1006 | ||
1007 | $tags = $doc->getElementsByTagName('script'); |
1007 | $tags = $doc->getElementsByTagName('script'); |
1008 | foreach ($tags as $tag) { |
1008 | foreach ($tags as $tag) { |
1009 | $type = $tag->getAttribute('type'); |
1009 | $type = $tag->getAttribute('type'); |
1010 | if ($type !== 'application/json') continue; |
1010 | if ($type !== 'application/json') continue; |
1011 | 1011 | ||
1012 | $json = $tag->nodeValue; |
1012 | $json = $tag->nodeValue; |
1013 | if (!$json) continue; |
1013 | if (!$json) continue; |
1014 | 1014 | ||
1015 | $data = @json_decode($json,true); |
1015 | $data = @json_decode($json,true); |
1016 | if (!is_array($data)) continue; |
1016 | if (!is_array($data)) continue; |
1017 | 1017 | ||
1018 | if (!isset($data['type'])) continue; |
1018 | if (!isset($data['type'])) continue; |
1019 | if ($data['type'] === VNAG_JSONDATA_V1) { |
1019 | if ($data['type'] === VNAG_JSONDATA_V1) { |
1020 | if (!isset($data['datasets'])) throw new VNagWebInfoException(VNagLang::$dataset_missing); |
1020 | if (!isset($data['datasets'])) throw new VNagWebInfoException(VNagLang::$dataset_missing); |
1021 | foreach ($data['datasets'] as $dataset) { |
1021 | foreach ($data['datasets'] as $dataset) { |
1022 | $payload = base64_decode($dataset['payload']); |
1022 | $payload = base64_decode($dataset['payload']); |
1023 | if (!$payload) { |
1023 | if (!$payload) { |
1024 | throw new VNagWebInfoException(VNagLang::$payload_not_base64); |
1024 | throw new VNagWebInfoException(VNagLang::$payload_not_base64); |
1025 | } |
1025 | } |
1026 | 1026 | ||
1027 | if (isset($dataset['encryption'])) { |
1027 | if (isset($dataset['encryption'])) { |
1028 | // The dataset is encrypted. We need to decrypt it first. |
1028 | // The dataset is encrypted. We need to decrypt it first. |
1029 | 1029 | ||
1030 | $cryptInfo = $dataset['encryption']; |
1030 | $cryptInfo = $dataset['encryption']; |
1031 | if (!is_array($cryptInfo)) { |
1031 | if (!is_array($cryptInfo)) { |
1032 | throw new VNagWebInfoException(VNagLang::$dataset_encryption_no_array); |
1032 | throw new VNagWebInfoException(VNagLang::$dataset_encryption_no_array); |
1033 | } |
1033 | } |
1034 | 1034 | ||
1035 | $password = is_null($this->password_in) ? '' : $this->password_in; |
1035 | $password = is_null($this->password_in) ? '' : $this->password_in; |
1036 | 1036 | ||
1037 | $salt = base64_decode($cryptInfo['salt']); |
1037 | $salt = base64_decode($cryptInfo['salt']); |
1038 | 1038 | ||
1039 | if ($cryptInfo['hash'] != hash('sha256',$salt.$password)) { |
1039 | if ($cryptInfo['hash'] != hash('sha256',$salt.$password)) { |
1040 | if ($password == '') { |
1040 | if ($password == '') { |
1041 | throw new VNagWebInfoException(VNagLang::$require_password); |
1041 | throw new VNagWebInfoException(VNagLang::$require_password); |
1042 | } else { |
1042 | } else { |
1043 | throw new VNagWebInfoException(VNagLang::$wrong_password); |
1043 | throw new VNagWebInfoException(VNagLang::$wrong_password); |
1044 | } |
1044 | } |
1045 | } |
1045 | } |
1046 | 1046 | ||
1047 | if (!function_exists('openssl_decrypt')) { |
1047 | if (!function_exists('openssl_decrypt')) { |
1048 | throw new VNagException(VNagLang::$openssl_missing); |
1048 | throw new VNagException(VNagLang::$openssl_missing); |
1049 | } |
1049 | } |
1050 | 1050 | ||
1051 | $payload = openssl_decrypt($payload, $cryptInfo['method'], $password, 0, $cryptInfo['iv']); |
1051 | $payload = openssl_decrypt($payload, $cryptInfo['method'], $password, 0, $cryptInfo['iv']); |
1052 | } |
1052 | } |
1053 | 1053 | ||
1054 | if (!is_null($this->pubkey) && ($this->pubkey !== '')) { |
1054 | if (!is_null($this->pubkey) && ($this->pubkey !== '')) { |
1055 | if (substr($this->pubkey,0,3) === '---') { |
1055 | if (substr($this->pubkey,0,3) === '---') { |
1056 | $public_key = $this->pubkey; |
1056 | $public_key = $this->pubkey; |
1057 | } else { |
1057 | } else { |
1058 | if (!file_exists($this->pubkey)) { |
1058 | if (!file_exists($this->pubkey)) { |
1059 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$pubkey_file_not_found, $this->pubkey)); |
1059 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$pubkey_file_not_found, $this->pubkey)); |
1060 | } |
1060 | } |
1061 | 1061 | ||
1062 | $public_key = @file_get_contents($this->pubkey); |
1062 | $public_key = @file_get_contents($this->pubkey); |
1063 | if (!$public_key) { |
1063 | if (!$public_key) { |
1064 | throw new VNagPublicKeyException(sprintf(VNagLang::$pubkey_file_not_readable, $this->pubkey)); |
1064 | throw new VNagPublicKeyException(sprintf(VNagLang::$pubkey_file_not_readable, $this->pubkey)); |
1065 | } |
1065 | } |
1066 | } |
1066 | } |
1067 | 1067 | ||
1068 | if (!isset($dataset['signature'])) { |
1068 | if (!isset($dataset['signature'])) { |
1069 | throw new VNagSignatureException(VNagLang::$signature_missing); |
1069 | throw new VNagSignatureException(VNagLang::$signature_missing); |
1070 | } |
1070 | } |
1071 | 1071 | ||
1072 | $signature = base64_decode($dataset['signature']); |
1072 | $signature = base64_decode($dataset['signature']); |
1073 | if (!$signature) { |
1073 | if (!$signature) { |
1074 | throw new VNagSignatureException(VNagLang::$signature_not_bas64); |
1074 | throw new VNagSignatureException(VNagLang::$signature_not_bas64); |
1075 | } |
1075 | } |
1076 | 1076 | ||
1077 | if (!function_exists('openssl_verify')) { |
1077 | if (!function_exists('openssl_verify')) { |
1078 | throw new VNagException(VNagLang::$openssl_missing); |
1078 | throw new VNagException(VNagLang::$openssl_missing); |
1079 | } |
1079 | } |
1080 | 1080 | ||
1081 | $sign_algo = is_null($this->sign_algo) ? OPENSSL_ALGO_SHA256 : $this->sign_algo; |
1081 | $sign_algo = is_null($this->sign_algo) ? OPENSSL_ALGO_SHA256 : $this->sign_algo; |
1082 | if (!openssl_verify($payload, $signature, $public_key, $sign_algo)) { |
1082 | if (!openssl_verify($payload, $signature, $public_key, $sign_algo)) { |
1083 | throw new VNagSignatureException(VNagLang::$signature_invalid); |
1083 | throw new VNagSignatureException(VNagLang::$signature_invalid); |
1084 | } |
1084 | } |
1085 | } |
1085 | } |
1086 | 1086 | ||
1087 | $payload = @json_decode($payload,true); |
1087 | $payload = @json_decode($payload,true); |
1088 | if (!$payload) { |
1088 | if (!$payload) { |
1089 | throw new VNagWebInfoException(VNagLang::$payload_not_json); |
1089 | throw new VNagWebInfoException(VNagLang::$payload_not_json); |
1090 | } |
1090 | } |
1091 | 1091 | ||
1092 | if ($payload['id'] == $this->id) { |
1092 | if ($payload['id'] == $this->id) { |
1093 | return $payload; |
1093 | return $payload; |
1094 | } |
1094 | } |
1095 | } |
1095 | } |
1096 | } |
1096 | } |
1097 | } |
1097 | } |
1098 | 1098 | ||
1099 | return null; |
1099 | return null; |
1100 | } |
1100 | } |
1101 | 1101 | ||
1102 | private function getNextMonitorID($peek=false) { |
1102 | private function getNextMonitorID($peek=false) { |
1103 | $result = is_null($this->id) ? self::$http_serial_number : $this->id; |
1103 | $result = is_null($this->id) ? self::$http_serial_number : $this->id; |
1104 | 1104 | ||
1105 | if (!$peek) { |
1105 | if (!$peek) { |
1106 | $this->id = null; // use manual ID only once |
1106 | $this->id = null; // use manual ID only once |
1107 | self::$http_serial_number++; |
1107 | self::$http_serial_number++; |
1108 | } |
1108 | } |
1109 | 1109 | ||
1110 | return $result; |
1110 | return $result; |
1111 | } |
1111 | } |
1112 | 1112 | ||
1113 | private function writeInvisibleHTML($special_content=null) { |
1113 | private function writeInvisibleHTML($special_content=null) { |
1114 | // 1. Create the payload |
1114 | // 1. Create the payload |
1115 | 1115 | ||
1116 | $payload['id'] = $this->getNextMonitorID(); |
1116 | $payload['id'] = $this->getNextMonitorID(); |
1117 | 1117 | ||
1118 | $payload['status'] = $this->getStatus(); |
1118 | $payload['status'] = $this->getStatus(); |
1119 | 1119 | ||
1120 | if (!_empty($special_content)) { |
1120 | if (!_empty($special_content)) { |
1121 | $payload['text'] = $special_content; |
1121 | $payload['text'] = $special_content; |
1122 | } else { |
1122 | } else { |
1123 | $payload['headline'] = $this->getHeadline(); |
1123 | $payload['headline'] = $this->getHeadline(); |
1124 | $payload['verbose_info'] = $this->verbose_info; |
1124 | $payload['verbose_info'] = $this->verbose_info; |
1125 | 1125 | ||
1126 | $payload['performance_data'] = array(); |
1126 | $payload['performance_data'] = array(); |
1127 | foreach ($this->performanceDataObjects as $perfdata) { |
1127 | foreach ($this->performanceDataObjects as $perfdata) { |
1128 | $payload['performance_data'][] = (string)$perfdata; |
1128 | $payload['performance_data'][] = (string)$perfdata; |
1129 | } |
1129 | } |
1130 | } |
1130 | } |
1131 | 1131 | ||
1132 | $payload = json_encode($payload); |
1132 | $payload = json_encode($payload); |
1133 | 1133 | ||
1134 | // 2. Encode the payload as JSON and optionally sign and/or encrypt it |
1134 | // 2. Encode the payload as JSON and optionally sign and/or encrypt it |
1135 | 1135 | ||
1136 | $dataset = array(); |
1136 | $dataset = array(); |
1137 | 1137 | ||
1138 | if (!is_null($this->privkey) && ($this->privkey !== '')) { |
1138 | if (!is_null($this->privkey) && ($this->privkey !== '')) { |
1139 | if (!function_exists('openssl_pkey_get_private') || !function_exists('openssl_sign')) { |
1139 | if (!function_exists('openssl_pkey_get_private') || !function_exists('openssl_sign')) { |
1140 | throw new VNagException(VNagLang::$openssl_missing); |
1140 | throw new VNagException(VNagLang::$openssl_missing); |
1141 | } |
1141 | } |
1142 | 1142 | ||
1143 | if (substr($this->privkey,0,3) === '---') { |
1143 | if (substr($this->privkey,0,3) === '---') { |
1144 | $pkeyid = @openssl_pkey_get_private($this->privkey, $this->privkey_password); |
1144 | $pkeyid = @openssl_pkey_get_private($this->privkey, $this->privkey_password); |
1145 | if (!$pkeyid) { |
1145 | if (!$pkeyid) { |
1146 | throw new VNagPrivateKeyException(sprintf(VNagLang::$privkey_not_readable)); |
1146 | throw new VNagPrivateKeyException(sprintf(VNagLang::$privkey_not_readable)); |
1147 | } |
1147 | } |
1148 | } else { |
1148 | } else { |
1149 | if (!file_exists($this->privkey)) { |
1149 | if (!file_exists($this->privkey)) { |
1150 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$privkey_file_not_found, $this->privkey)); |
1150 | throw new VNagInvalidArgumentException(sprintf(VNagLang::$privkey_file_not_found, $this->privkey)); |
1151 | } |
1151 | } |
1152 | $pkeyid = @openssl_pkey_get_private('file://'.$this->privkey, $this->privkey_password); |
1152 | $pkeyid = @openssl_pkey_get_private('file://'.$this->privkey, $this->privkey_password); |
1153 | if (!$pkeyid) { |
1153 | if (!$pkeyid) { |
1154 | throw new VNagPrivateKeyException(sprintf(VNagLang::$privkey_file_not_readable, $this->privkey)); |
1154 | throw new VNagPrivateKeyException(sprintf(VNagLang::$privkey_file_not_readable, $this->privkey)); |
1155 | } |
1155 | } |
1156 | } |
1156 | } |
1157 | 1157 | ||
1158 | $signature = ''; |
1158 | $signature = ''; |
1159 | $sign_algo = is_null($this->sign_algo) ? OPENSSL_ALGO_SHA256 : $this->sign_algo; |
1159 | $sign_algo = is_null($this->sign_algo) ? OPENSSL_ALGO_SHA256 : $this->sign_algo; |
1160 | if (@openssl_sign($payload, $signature, $pkeyid, $sign_algo)) { |
1160 | if (@openssl_sign($payload, $signature, $pkeyid, $sign_algo)) { |
1161 | if (version_compare(PHP_VERSION, '8.0.0') < 0) { |
1161 | if (version_compare(PHP_VERSION, '8.0.0') < 0) { |
1162 | openssl_free_key($pkeyid); |
1162 | openssl_free_key($pkeyid); |
1163 | } |
1163 | } |
1164 | 1164 | ||
1165 | $dataset['signature'] = base64_encode($signature); |
1165 | $dataset['signature'] = base64_encode($signature); |
1166 | } else { |
1166 | } else { |
1167 | throw new VNagPrivateKeyException(sprintf(VNagLang::$signature_failed)); |
1167 | throw new VNagPrivateKeyException(sprintf(VNagLang::$signature_failed)); |
1168 | } |
1168 | } |
1169 | } |
1169 | } |
1170 | 1170 | ||
1171 | if (!is_null($this->password_out) && ($this->password_out !== '')) { |
1171 | if (!is_null($this->password_out) && ($this->password_out !== '')) { |
1172 | if (!function_exists('openssl_encrypt')) { |
1172 | if (!function_exists('openssl_encrypt')) { |
1173 | throw new VNagException(VNagLang::$openssl_missing); |
1173 | throw new VNagException(VNagLang::$openssl_missing); |
1174 | } |
1174 | } |
1175 | 1175 | ||
1176 | $password = $this->password_out; |
1176 | $password = $this->password_out; |
1177 | 1177 | ||
1178 | $method = 'aes-256-ofb'; |
1178 | $method = 'aes-256-ofb'; |
1179 | $iv = substr(hash('sha256', openssl_random_pseudo_bytes(32)), 0, 16); |
1179 | $iv = substr(hash('sha256', openssl_random_pseudo_bytes(32)), 0, 16); |
1180 | $salt = openssl_random_pseudo_bytes(32); |
1180 | $salt = openssl_random_pseudo_bytes(32); |
1181 | 1181 | ||
1182 | $cryptInfo = array(); |
1182 | $cryptInfo = array(); |
1183 | $cryptInfo['method'] = $method; |
1183 | $cryptInfo['method'] = $method; |
1184 | $cryptInfo['iv'] = $iv; |
1184 | $cryptInfo['iv'] = $iv; |
1185 | $cryptInfo['salt'] = base64_encode($salt); |
1185 | $cryptInfo['salt'] = base64_encode($salt); |
1186 | $cryptInfo['hash'] = hash('sha256', $salt.$password); |
1186 | $cryptInfo['hash'] = hash('sha256', $salt.$password); |
1187 | 1187 | ||
1188 | $payload = openssl_encrypt($payload, $method, $password, 0, $iv); |
1188 | $payload = openssl_encrypt($payload, $method, $password, 0, $iv); |
1189 | $dataset['encryption'] = $cryptInfo; |
1189 | $dataset['encryption'] = $cryptInfo; |
1190 | } |
1190 | } |
1191 | 1191 | ||
1192 | $dataset['payload'] = base64_encode($payload); |
1192 | $dataset['payload'] = base64_encode($payload); |
1193 | 1193 | ||
1194 | // 3. Encode everything as JSON+Base64 (again) and put it into the data block |
1194 | // 3. Encode everything as JSON+Base64 (again) and put it into the data block |
1195 | 1195 | ||
1196 | $json = array(); |
1196 | $json = array(); |
1197 | $json['type'] = VNAG_JSONDATA_V1; |
1197 | $json['type'] = VNAG_JSONDATA_V1; |
1198 | $json['datasets'] = array($dataset); // we only output 1 dataset. We could technically output more than one into this data block. |
1198 | $json['datasets'] = array($dataset); // we only output 1 dataset. We could technically output more than one into this data block. |
1199 | 1199 | ||
1200 | // Include the machine-readable information as data block |
1200 | // Include the machine-readable information as data block |
1201 | // This method was chosen to support HTML 4.01, XHTML and HTML5 as well without breaking the standards |
1201 | // This method was chosen to support HTML 4.01, XHTML and HTML5 as well without breaking the standards |
1202 | // see https://stackoverflow.com/questions/51222713/using-an-individual-tag-without-breaking-the-standards/51223609#51223609 |
1202 | // see https://stackoverflow.com/questions/51222713/using-an-individual-tag-without-breaking-the-standards/51223609#51223609 |
1203 | return '<script type="application/json">'. |
1203 | return '<script type="application/json">'. |
1204 | json_encode($json). |
1204 | json_encode($json). |
1205 | '</script>'; |
1205 | '</script>'; |
1206 | } |
1206 | } |
1207 | 1207 | ||
1208 | protected function appendHeadline($msg) { |
1208 | protected function appendHeadline($msg) { |
1209 | $this->checkInitialized(); // if (!$this->initialized) return; |
1209 | $this->checkInitialized(); // if (!$this->initialized) return; |
1210 | 1210 | ||
1211 | if (_empty($msg)) return false; |
1211 | if (_empty($msg)) return false; |
1212 | $this->messages[] = $msg; |
1212 | $this->messages[] = $msg; |
1213 | 1213 | ||
1214 | return true; |
1214 | return true; |
1215 | } |
1215 | } |
1216 | 1216 | ||
1217 | protected function changeHeadline($msg) { |
1217 | protected function changeHeadline($msg) { |
1218 | $this->checkInitialized(); // if (!$this->initialized) return; |
1218 | $this->checkInitialized(); // if (!$this->initialized) return; |
1219 | 1219 | ||
1220 | if (_empty($msg)) { |
1220 | if (_empty($msg)) { |
1221 | $this->messages = array(); |
1221 | $this->messages = array(); |
1222 | } else { |
1222 | } else { |
1223 | $this->messages = array($msg); |
1223 | $this->messages = array($msg); |
1224 | } |
1224 | } |
1225 | 1225 | ||
1226 | return true; |
1226 | return true; |
1227 | } |
1227 | } |
1228 | 1228 | ||
1229 | public function setHeadline($msg, $append=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
1229 | public function setHeadline($msg, $append=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
1230 | $this->checkInitialized(); // if (!$this->initialized) return; |
1230 | $this->checkInitialized(); // if (!$this->initialized) return; |
1231 | 1231 | ||
1232 | if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v'); |
1232 | if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v'); |
1233 | if (self::getVerbosityLevel() < $verbosityLevel) $msg = ''; |
1233 | if (self::getVerbosityLevel() < $verbosityLevel) $msg = ''; |
1234 | 1234 | ||
1235 | if ($append) { |
1235 | if ($append) { |
1236 | return $this->appendHeadline($msg); |
1236 | return $this->appendHeadline($msg); |
1237 | } else { |
1237 | } else { |
1238 | return $this->changeHeadline($msg); |
1238 | return $this->changeHeadline($msg); |
1239 | } |
1239 | } |
1240 | } |
1240 | } |
1241 | 1241 | ||
1242 | public function getHeadline() { |
1242 | public function getHeadline() { |
1243 | $this->checkInitialized(); // if (!$this->initialized) return ''; |
1243 | $this->checkInitialized(); // if (!$this->initialized) return ''; |
1244 | 1244 | ||
1245 | return implode(', ', $this->messages); |
1245 | return implode(', ', $this->messages); |
1246 | } |
1246 | } |
1247 | 1247 | ||
1248 | public function addVerboseMessage($msg, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
1248 | public function addVerboseMessage($msg, $verbosityLevel=VNag::VERBOSITY_SUMMARY) { |
1249 | $this->checkInitialized(); // if (!$this->initialized) return; |
1249 | $this->checkInitialized(); // if (!$this->initialized) return; |
1250 | 1250 | ||
1251 | if (self::getVerbosityLevel() >= $verbosityLevel) { |
1251 | if (self::getVerbosityLevel() >= $verbosityLevel) { |
1252 | $this->verbose_info .= $msg."\n"; |
1252 | $this->verbose_info .= $msg."\n"; |
1253 | } |
1253 | } |
1254 | } |
1254 | } |
1255 | 1255 | ||
1256 | public function setStatus($status, $force=false) { |
1256 | public function setStatus($status, $force=false) { |
1257 | $this->checkInitialized(); // if (!$this->initialized) return; |
1257 | $this->checkInitialized(); // if (!$this->initialized) return; |
1258 | 1258 | ||
1259 | if (($force) || is_null($this->status) || ($status > $this->status)) { |
1259 | if (($force) || is_null($this->status) || ($status > $this->status)) { |
1260 | $this->status = $status; |
1260 | $this->status = $status; |
1261 | } |
1261 | } |
1262 | } |
1262 | } |
1263 | 1263 | ||
1264 | public function getStatus() { |
1264 | public function getStatus() { |
1265 | $this->checkInitialized(); // if (!$this->initialized) return; |
1265 | $this->checkInitialized(); // if (!$this->initialized) return; |
1266 | 1266 | ||
1267 | return $this->status; |
1267 | return $this->status; |
1268 | } |
1268 | } |
1269 | 1269 | ||
1270 | protected static function exceptionText($exception) { |
1270 | protected static function exceptionText($exception) { |
1271 | // $this->checkInitialized(); // if (!$this->initialized) return false; |
1271 | // $this->checkInitialized(); // if (!$this->initialized) return false; |
1272 | 1272 | ||
1273 | $class = get_class($exception); |
1273 | $class = get_class($exception); |
1274 | $msg = $exception->getMessage(); |
1274 | $msg = $exception->getMessage(); |
1275 | 1275 | ||
1276 | if (!_empty($msg)) { |
1276 | if (!_empty($msg)) { |
1277 | return sprintf(VNagLang::$exception_x, $msg, $class); |
1277 | return sprintf(VNagLang::$exception_x, $msg, $class); |
1278 | } else { |
1278 | } else { |
1279 | return sprintf(VNagLang::$unhandled_exception_without_msg, $class); |
1279 | return sprintf(VNagLang::$unhandled_exception_without_msg, $class); |
1280 | } |
1280 | } |
1281 | } |
1281 | } |
1282 | 1282 | ||
1283 | protected function handleException($exception) { |
1283 | protected function handleException($exception) { |
1284 | $this->checkInitialized(); // if (!$this->initialized) return; |
1284 | $this->checkInitialized(); // if (!$this->initialized) return; |
1285 | 1285 | ||
1286 | if (!VNag::is_http_mode()) { |
1286 | if (!VNag::is_http_mode()) { |
1287 | // On console output, remove anything we have written so far! |
1287 | // On console output, remove anything we have written so far! |
1288 | while (ob_get_level() > 0) @ob_end_clean(); |
1288 | while (ob_get_level() > 0) @ob_end_clean(); |
1289 | } |
1289 | } |
1290 | $this->clearVerboseInfo(); |
1290 | $this->clearVerboseInfo(); |
1291 | $this->clearPerformanceData(); |
1291 | $this->clearPerformanceData(); |
1292 | 1292 | ||
1293 | if ($exception instanceof VNagException) { |
1293 | if ($exception instanceof VNagException) { |
1294 | $this->setStatus($exception->getStatus()); |
1294 | $this->setStatus($exception->getStatus()); |
1295 | } else { |
1295 | } else { |
1296 | $this->setStatus(self::STATUS_ERROR); |
1296 | $this->setStatus(self::STATUS_ERROR); |
1297 | } |
1297 | } |
1298 | 1298 | ||
1299 | $this->setHeadline($this->exceptionText($exception), false); |
1299 | $this->setHeadline($this->exceptionText($exception), false); |
1300 | 1300 | ||
1301 | if ($exception instanceof VNagImplementationErrorException) { |
1301 | if ($exception instanceof VNagImplementationErrorException) { |
1302 | $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY); |
1302 | $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY); |
1303 | } else { |
1303 | } else { |
1304 | if (isset($this->argVerbosity)) { |
1304 | if (isset($this->argVerbosity)) { |
1305 | $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
1305 | $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
1306 | } else { |
1306 | } else { |
1307 | // $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY); |
1307 | // $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY); |
1308 | } |
1308 | } |
1309 | } |
1309 | } |
1310 | } |
1310 | } |
- | 1311 | ||
- | 1312 | // This is not used by the framework itself, but can be useful for plugins |
|
- | 1313 | // Note: For icinga2, the path is /var/lib/nagios/.vnag/cache/ |
|
- | 1314 | protected function get_cache_dir() { |
|
- | 1315 | $homedir = @getenv('HOME'); |
|
- | 1316 | if ($homedir && is_dir($homedir)) { |
|
- | 1317 | $try = "${homedir}/.vnag/cache"; |
|
- | 1318 | if (is_dir($try)) return $try; |
|
- | 1319 | if (@mkdir($try,0777,true)) return $try; |
|
- | 1320 | } |
|
- | 1321 | ||
- | 1322 | $user = posix_getpwuid(posix_geteuid()); |
|
- | 1323 | if (isset($user['dir']) && is_dir($user['dir'])) { |
|
- | 1324 | $homedir = $user['dir']; |
|
- | 1325 | $try = "${homedir}/.vnag/cache"; |
|
- | 1326 | if (is_dir($try)) return $try; |
|
- | 1327 | if (@mkdir($try,0777,true)) return $try; |
|
- | 1328 | } |
|
- | 1329 | ||
- | 1330 | if (isset($user['name']) && is_dir($user['name'])) { |
|
- | 1331 | $username = $user['name']; |
|
- | 1332 | $try = "/tmp/vnag/cache"; |
|
- | 1333 | if (is_dir($try)) return $try; |
|
- | 1334 | if (@mkdir($try,0777,true)) return $try; |
|
- | 1335 | } |
|
- | 1336 | ||
- | 1337 | throw new VNagException("Cannot get cache dir"); // TODO: translate and own exception type |
|
- | 1338 | } |
|
1311 | } |
1339 | } |
1312 | 1340 | ||
1313 | 1341 | ||
1314 | class VNagException extends Exception { |
1342 | class VNagException extends Exception { |
1315 | public function getStatus() { |
1343 | public function getStatus() { |
1316 | return VNag::STATUS_ERROR; |
1344 | return VNag::STATUS_ERROR; |
1317 | } |
1345 | } |
1318 | } |
1346 | } |
1319 | 1347 | ||
1320 | class VNagTimeoutException extends VNagException {} |
1348 | class VNagTimeoutException extends VNagException {} |
1321 | 1349 | ||
1322 | class VNagWebInfoException extends VNagException {} |
1350 | class VNagWebInfoException extends VNagException {} |
1323 | class VNagSignatureException extends VNagException {} |
1351 | class VNagSignatureException extends VNagException {} |
1324 | class VNagPublicKeyException extends VNagException {} |
1352 | class VNagPublicKeyException extends VNagException {} |
1325 | class VNagPrivateKeyException extends VNagException {} |
1353 | class VNagPrivateKeyException extends VNagException {} |
1326 | 1354 | ||
1327 | // VNagInvalidArgumentException are exceptions which result from a wrong use |
1355 | // VNagInvalidArgumentException are exceptions which result from a wrong use |
1328 | // of arguments by the USER (CLI arguments or HTTP parameters) |
1356 | // of arguments by the USER (CLI arguments or HTTP parameters) |
1329 | class VNagInvalidArgumentException extends VNagException { |
1357 | class VNagInvalidArgumentException extends VNagException { |
1330 | public function getStatus() { |
1358 | public function getStatus() { |
1331 | return VNag::STATUS_UNKNOWN; |
1359 | return VNag::STATUS_UNKNOWN; |
1332 | } |
1360 | } |
1333 | } |
1361 | } |
1334 | 1362 | ||
1335 | class VNagValueUomPairSyntaxException extends VNagInvalidArgumentException { |
1363 | class VNagValueUomPairSyntaxException extends VNagInvalidArgumentException { |
1336 | public function __construct($str) { |
1364 | public function __construct($str) { |
1337 | $e_msg = sprintf(VNagLang::$valueUomPairSyntaxError, $str); |
1365 | $e_msg = sprintf(VNagLang::$valueUomPairSyntaxError, $str); |
1338 | parent::__construct($e_msg); |
1366 | parent::__construct($e_msg); |
1339 | } |
1367 | } |
1340 | } |
1368 | } |
1341 | 1369 | ||
1342 | class VNagInvalidTimeoutException extends VNagInvalidArgumentException {} |
1370 | class VNagInvalidTimeoutException extends VNagInvalidArgumentException {} |
1343 | 1371 | ||
1344 | class VNagInvalidRangeException extends VNagInvalidArgumentException { |
1372 | class VNagInvalidRangeException extends VNagInvalidArgumentException { |
1345 | public function __construct($msg) { |
1373 | public function __construct($msg) { |
1346 | $e_msg = VNagLang::$range_is_invalid; |
1374 | $e_msg = VNagLang::$range_is_invalid; |
1347 | if (!_empty($msg)) $e_msg .= ': '.trim($msg); |
1375 | if (!_empty($msg)) $e_msg .= ': '.trim($msg); |
1348 | parent::__construct($e_msg); |
1376 | parent::__construct($e_msg); |
1349 | } |
1377 | } |
1350 | } |
1378 | } |
1351 | 1379 | ||
1352 | class VNagInvalidShortOpt extends VNagImplementationErrorException {} |
1380 | class VNagInvalidShortOpt extends VNagImplementationErrorException {} |
1353 | class VNagInvalidLongOpt extends VNagImplementationErrorException {} |
1381 | class VNagInvalidLongOpt extends VNagImplementationErrorException {} |
1354 | class VNagInvalidValuePolicy extends VNagImplementationErrorException {} |
1382 | class VNagInvalidValuePolicy extends VNagImplementationErrorException {} |
1355 | class VNagIllegalStatusModel extends VNagImplementationErrorException {} |
1383 | class VNagIllegalStatusModel extends VNagImplementationErrorException {} |
1356 | class VNagNotConstructed extends VNagImplementationErrorException {} |
1384 | class VNagNotConstructed extends VNagImplementationErrorException {} |
1357 | 1385 | ||
1358 | // To enforce that people use the API correctly, we report flaws in the implementation |
1386 | // To enforce that people use the API correctly, we report flaws in the implementation |
1359 | // as Exception. |
1387 | // as Exception. |
1360 | class VNagImplementationErrorException extends VNagException {} |
1388 | class VNagImplementationErrorException extends VNagException {} |
1361 | 1389 | ||
1362 | class VNagInvalidStandardArgument extends VNagImplementationErrorException {} |
1390 | class VNagInvalidStandardArgument extends VNagImplementationErrorException {} |
1363 | class VNagFunctionCallOutsideSession extends VNagImplementationErrorException {} |
1391 | class VNagFunctionCallOutsideSession extends VNagImplementationErrorException {} |
1364 | class VNagIllegalArgumentValuesException extends VNagImplementationErrorException {} |
1392 | class VNagIllegalArgumentValuesException extends VNagImplementationErrorException {} |
1365 | 1393 | ||
1366 | class VNagRequiredArgumentNotRegistered extends VNagImplementationErrorException { |
1394 | class VNagRequiredArgumentNotRegistered extends VNagImplementationErrorException { |
1367 | // Developer's mistake: The argument is not in the list of expected arguments |
1395 | // Developer's mistake: The argument is not in the list of expected arguments |
1368 | public function __construct($required_argument) { |
1396 | public function __construct($required_argument) { |
1369 | $e_msg = sprintf(VNagLang::$query_without_expected_argument, $required_argument); |
1397 | $e_msg = sprintf(VNagLang::$query_without_expected_argument, $required_argument); |
1370 | parent::__construct($e_msg); |
1398 | parent::__construct($e_msg); |
1371 | } |
1399 | } |
1372 | } |
1400 | } |
1373 | 1401 | ||
1374 | class VNagRequiredArgumentMissing extends VNagInvalidArgumentException { |
1402 | class VNagRequiredArgumentMissing extends VNagInvalidArgumentException { |
1375 | // User's mistake: They did not pass the argument to the plugin |
1403 | // User's mistake: They did not pass the argument to the plugin |
1376 | public function __construct($required_argument) { |
1404 | public function __construct($required_argument) { |
1377 | $e_msg = sprintf(VNagLang::$required_argument_missing, $required_argument); |
1405 | $e_msg = sprintf(VNagLang::$required_argument_missing, $required_argument); |
1378 | parent::__construct($e_msg); |
1406 | parent::__construct($e_msg); |
1379 | } |
1407 | } |
1380 | } |
1408 | } |
1381 | 1409 | ||
1382 | class VNagUnknownUomException extends VNagInvalidArgumentException { |
1410 | class VNagUnknownUomException extends VNagInvalidArgumentException { |
1383 | public function __construct($uom) { |
1411 | public function __construct($uom) { |
1384 | $e_msg = sprintf(VNagLang::$perfdata_uom_not_recognized, $uom); |
1412 | $e_msg = sprintf(VNagLang::$perfdata_uom_not_recognized, $uom); |
1385 | parent::__construct($e_msg); |
1413 | parent::__construct($e_msg); |
1386 | } |
1414 | } |
1387 | } |
1415 | } |
1388 | 1416 | ||
1389 | class VNagNoCompatibleRangeUomFoundException extends VNagException {} |
1417 | class VNagNoCompatibleRangeUomFoundException extends VNagException {} |
1390 | 1418 | ||
1391 | class VNagMixedUomsNotImplemented extends VNagInvalidArgumentException { |
1419 | class VNagMixedUomsNotImplemented extends VNagInvalidArgumentException { |
1392 | public function __construct($uom1, $uom2) { |
1420 | public function __construct($uom1, $uom2) { |
1393 | if (_empty($uom1)) $uom1 = VNagLang::$none; |
1421 | if (_empty($uom1)) $uom1 = VNagLang::$none; |
1394 | if (_empty($uom2)) $uom2 = VNagLang::$none; |
1422 | if (_empty($uom2)) $uom2 = VNagLang::$none; |
1395 | $e_msg = sprintf(VNagLang::$perfdata_mixed_uom_not_implemented, $uom1, $uom2); |
1423 | $e_msg = sprintf(VNagLang::$perfdata_mixed_uom_not_implemented, $uom1, $uom2); |
1396 | parent::__construct($e_msg); |
1424 | parent::__construct($e_msg); |
1397 | } |
1425 | } |
1398 | } |
1426 | } |
1399 | 1427 | ||
1400 | class VNagUomConvertException extends VNagInvalidArgumentException { |
1428 | class VNagUomConvertException extends VNagInvalidArgumentException { |
1401 | // It is unknown where the invalid UOM that was passed to the normalize() function came from, |
1429 | // It is unknown where the invalid UOM that was passed to the normalize() function came from, |
1402 | // so it is not clear what parent this Exception class should have... |
1430 | // so it is not clear what parent this Exception class should have... |
1403 | // If the value comes from the developer: VNagImplementationErrorException |
1431 | // If the value comes from the developer: VNagImplementationErrorException |
1404 | // If the value came from the user: VNagInvalidArgumentException |
1432 | // If the value came from the user: VNagInvalidArgumentException |
1405 | 1433 | ||
1406 | public function __construct($uom1, $uom2) { |
1434 | public function __construct($uom1, $uom2) { |
1407 | if (_empty($uom1)) $uom1 = VNagLang::$none; |
1435 | if (_empty($uom1)) $uom1 = VNagLang::$none; |
1408 | if (_empty($uom2)) $uom2 = VNagLang::$none; |
1436 | if (_empty($uom2)) $uom2 = VNagLang::$none; |
1409 | $e_msg = sprintf(VNagLang::$convert_x_y_error, $uom1, $uom2); |
1437 | $e_msg = sprintf(VNagLang::$convert_x_y_error, $uom1, $uom2); |
1410 | parent::__construct($e_msg); |
1438 | parent::__construct($e_msg); |
1411 | } |
1439 | } |
1412 | } |
1440 | } |
1413 | 1441 | ||
1414 | class VNagInvalidPerformanceDataException extends VNagInvalidArgumentException { |
1442 | class VNagInvalidPerformanceDataException extends VNagInvalidArgumentException { |
1415 | public function __construct($msg) { |
1443 | public function __construct($msg) { |
1416 | $e_msg = VNagLang::$performance_data_invalid; |
1444 | $e_msg = VNagLang::$performance_data_invalid; |
1417 | if (!_empty($msg)) $e_msg .= ': '.trim($msg); |
1445 | if (!_empty($msg)) $e_msg .= ': '.trim($msg); |
1418 | parent::__construct($e_msg); |
1446 | parent::__construct($e_msg); |
1419 | } |
1447 | } |
1420 | } |
1448 | } |
1421 | 1449 | ||
1422 | class Timeouter { |
1450 | class Timeouter { |
1423 | // based on http://stackoverflow.com/questions/7493676/detecting-a-timeout-for-a-block-of-code-in-php |
1451 | // based on http://stackoverflow.com/questions/7493676/detecting-a-timeout-for-a-block-of-code-in-php |
1424 | 1452 | ||
1425 | private static $start_time = false; |
1453 | private static $start_time = false; |
1426 | private static $timeout; |
1454 | private static $timeout; |
1427 | private static $fired = false; |
1455 | private static $fired = false; |
1428 | private static $registered = false; |
1456 | private static $registered = false; |
1429 | 1457 | ||
1430 | private function __construct() { |
1458 | private function __construct() { |
1431 | } |
1459 | } |
1432 | 1460 | ||
1433 | public static function start($timeout) { |
1461 | public static function start($timeout) { |
1434 | if (!is_numeric($timeout) || ($timeout <= 0)) { |
1462 | if (!is_numeric($timeout) || ($timeout <= 0)) { |
1435 | throw new VNagInvalidTimeoutException(sprintf(VNagLang::$timeout_value_invalid, $timeout)); |
1463 | throw new VNagInvalidTimeoutException(sprintf(VNagLang::$timeout_value_invalid, $timeout)); |
1436 | } |
1464 | } |
1437 | 1465 | ||
1438 | self::$start_time = microtime(true); |
1466 | self::$start_time = microtime(true); |
1439 | self::$timeout = (float) $timeout; |
1467 | self::$timeout = (float) $timeout; |
1440 | self::$fired = false; |
1468 | self::$fired = false; |
1441 | if (!self::$registered) { |
1469 | if (!self::$registered) { |
1442 | self::$registered = true; |
1470 | self::$registered = true; |
1443 | register_tick_function(array('Timeouter', 'tick')); |
1471 | register_tick_function(array('Timeouter', 'tick')); |
1444 | } |
1472 | } |
1445 | } |
1473 | } |
1446 | 1474 | ||
1447 | public static function started() { |
1475 | public static function started() { |
1448 | return self::$registered; |
1476 | return self::$registered; |
1449 | } |
1477 | } |
1450 | 1478 | ||
1451 | public static function end() { |
1479 | public static function end() { |
1452 | if (self::$registered) { |
1480 | if (self::$registered) { |
1453 | unregister_tick_function(array('Timeouter', 'tick')); |
1481 | unregister_tick_function(array('Timeouter', 'tick')); |
1454 | self::$registered = false; |
1482 | self::$registered = false; |
1455 | } |
1483 | } |
1456 | } |
1484 | } |
1457 | 1485 | ||
1458 | public static function tick() { |
1486 | public static function tick() { |
1459 | if ((!self::$fired) && ((microtime(true) - self::$start_time) > self::$timeout)) { |
1487 | if ((!self::$fired) && ((microtime(true) - self::$start_time) > self::$timeout)) { |
1460 | self::$fired = true; // do not fire again |
1488 | self::$fired = true; // do not fire again |
1461 | throw new VNagTimeoutException(VNagLang::$timeout_exception); |
1489 | throw new VNagTimeoutException(VNagLang::$timeout_exception); |
1462 | } |
1490 | } |
1463 | } |
1491 | } |
1464 | } |
1492 | } |
1465 | 1493 | ||
1466 | class VNagArgument { |
1494 | class VNagArgument { |
1467 | const VALUE_FORBIDDEN = 0; |
1495 | const VALUE_FORBIDDEN = 0; |
1468 | const VALUE_REQUIRED = 1; |
1496 | const VALUE_REQUIRED = 1; |
1469 | const VALUE_OPTIONAL = 2; |
1497 | const VALUE_OPTIONAL = 2; |
1470 | 1498 | ||
1471 | protected $shortopt; |
1499 | protected $shortopt; |
1472 | protected $longopts; |
1500 | protected $longopts; |
1473 | protected $valuePolicy; |
1501 | protected $valuePolicy; |
1474 | protected $valueName; |
1502 | protected $valueName; |
1475 | protected $helpText; |
1503 | protected $helpText; |
1476 | protected $defaultValue = null; |
1504 | protected $defaultValue = null; |
1477 | 1505 | ||
1478 | protected static $all_short = ''; |
1506 | protected static $all_short = ''; |
1479 | protected static $all_long = array(); |
1507 | protected static $all_long = array(); |
1480 | 1508 | ||
1481 | public function getShortOpt() { |
1509 | public function getShortOpt() { |
1482 | return $this->shortopt; |
1510 | return $this->shortopt; |
1483 | } |
1511 | } |
1484 | 1512 | ||
1485 | public function getLongOpts() { |
1513 | public function getLongOpts() { |
1486 | return $this->longopts; |
1514 | return $this->longopts; |
1487 | } |
1515 | } |
1488 | 1516 | ||
1489 | public function getValuePolicy() { |
1517 | public function getValuePolicy() { |
1490 | return $this->valuePolicy; |
1518 | return $this->valuePolicy; |
1491 | } |
1519 | } |
1492 | 1520 | ||
1493 | public function getValueName() { |
1521 | public function getValueName() { |
1494 | return $this->valueName; |
1522 | return $this->valueName; |
1495 | } |
1523 | } |
1496 | 1524 | ||
1497 | public function getHelpText() { |
1525 | public function getHelpText() { |
1498 | return $this->helpText; |
1526 | return $this->helpText; |
1499 | } |
1527 | } |
1500 | 1528 | ||
1501 | static private function validateShortOpt($shortopt) { |
1529 | static private function validateShortOpt($shortopt) { |
1502 | $m = array(); |
1530 | $m = array(); |
1503 | return preg_match('@^[a-zA-Z0-9\\+\\-\\?]$@', $shortopt, $m); |
1531 | return preg_match('@^[a-zA-Z0-9\\+\\-\\?]$@', $shortopt, $m); |
1504 | } |
1532 | } |
1505 | 1533 | ||
1506 | static private function validateLongOpt($longopt) { |
1534 | static private function validateLongOpt($longopt) { |
1507 | // FUT: Check if this is accurate |
1535 | // FUT: Check if this is accurate |
1508 | $m = array(); |
1536 | $m = array(); |
1509 | return preg_match('@^[a-zA-Z0-9\\+\\-\\?]+$@', $longopt, $m); |
1537 | return preg_match('@^[a-zA-Z0-9\\+\\-\\?]+$@', $longopt, $m); |
1510 | } |
1538 | } |
1511 | 1539 | ||
1512 | // Note: Currently, we do not support following: |
1540 | // Note: Currently, we do not support following: |
1513 | // 1. How many times may a value be defined (it needs to be manually described in $helpText) |
1541 | // 1. How many times may a value be defined (it needs to be manually described in $helpText) |
1514 | // 2. Is this argument mandatory? (No exception will be thrown if the plugin will be started without this argument) |
1542 | // 2. Is this argument mandatory? (No exception will be thrown if the plugin will be started without this argument) |
1515 | public function __construct($shortopt, $longopts, $valuePolicy, $valueName, $helpText, $defaultValue=null) { |
1543 | public function __construct($shortopt, $longopts, $valuePolicy, $valueName, $helpText, $defaultValue=null) { |
1516 | // Check if $valueName is defined correctly in regards to the policy $valuePolicy |
1544 | // Check if $valueName is defined correctly in regards to the policy $valuePolicy |
1517 | switch ($valuePolicy) { |
1545 | switch ($valuePolicy) { |
1518 | case VNagArgument::VALUE_FORBIDDEN: |
1546 | case VNagArgument::VALUE_FORBIDDEN: |
1519 | if (!_empty($valueName)) { |
1547 | if (!_empty($valueName)) { |
1520 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_forbidden)); |
1548 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_forbidden)); |
1521 | } |
1549 | } |
1522 | break; |
1550 | break; |
1523 | case VNagArgument::VALUE_REQUIRED: |
1551 | case VNagArgument::VALUE_REQUIRED: |
1524 | if (_empty($valueName)) { |
1552 | if (_empty($valueName)) { |
1525 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required)); |
1553 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required)); |
1526 | } |
1554 | } |
1527 | break; |
1555 | break; |
1528 | case VNagArgument::VALUE_OPTIONAL: |
1556 | case VNagArgument::VALUE_OPTIONAL: |
1529 | if (_empty($valueName)) { |
1557 | if (_empty($valueName)) { |
1530 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required)); |
1558 | throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required)); |
1531 | } |
1559 | } |
1532 | break; |
1560 | break; |
1533 | default: |
1561 | default: |
1534 | throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy)); |
1562 | throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy)); |
1535 | } |
1563 | } |
1536 | 1564 | ||
1537 | // We'll check: Does the shortopt contain illegal characters? |
1565 | // We'll check: Does the shortopt contain illegal characters? |
1538 | // http://stackoverflow.com/questions/28522387/which-chars-are-valid-shortopts-for-gnu-getopt |
1566 | // http://stackoverflow.com/questions/28522387/which-chars-are-valid-shortopts-for-gnu-getopt |
1539 | // We do not filter +, - and ?, since we might need it for other methods, e.g. VNagArgumentHandler::_addExpectedArgument |
1567 | // We do not filter +, - and ?, since we might need it for other methods, e.g. VNagArgumentHandler::_addExpectedArgument |
1540 | if (!_empty($shortopt)) { |
1568 | if (!_empty($shortopt)) { |
1541 | if (!self::validateShortOpt($shortopt)) { |
1569 | if (!self::validateShortOpt($shortopt)) { |
1542 | throw new VNagInvalidShortOpt(sprintf(VNagLang::$illegal_shortopt, $shortopt)); |
1570 | throw new VNagInvalidShortOpt(sprintf(VNagLang::$illegal_shortopt, $shortopt)); |
1543 | } |
1571 | } |
1544 | } |
1572 | } |
1545 | 1573 | ||
1546 | if (is_array($longopts)) { // $longopts is an array |
1574 | if (is_array($longopts)) { // $longopts is an array |
1547 | foreach ($longopts as $longopt) { |
1575 | foreach ($longopts as $longopt) { |
1548 | if (!self::validateLongOpt($longopt)) { |
1576 | if (!self::validateLongOpt($longopt)) { |
1549 | throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopt)); |
1577 | throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopt)); |
1550 | } |
1578 | } |
1551 | } |
1579 | } |
1552 | } else if (!_empty($longopts)) { // $longopts is a string |
1580 | } else if (!_empty($longopts)) { // $longopts is a string |
1553 | if (!self::validateLongOpt($longopts)) { |
1581 | if (!self::validateLongOpt($longopts)) { |
1554 | throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopts)); |
1582 | throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopts)); |
1555 | } |
1583 | } |
1556 | $longopts = array($longopts); |
1584 | $longopts = array($longopts); |
1557 | } else { |
1585 | } else { |
1558 | $longopts = array(); |
1586 | $longopts = array(); |
1559 | } |
1587 | } |
1560 | 1588 | ||
1561 | # valuePolicy must be between 0..2 and being int |
1589 | # valuePolicy must be between 0..2 and being int |
1562 | switch ($valuePolicy) { |
1590 | switch ($valuePolicy) { |
1563 | case VNagArgument::VALUE_FORBIDDEN: |
1591 | case VNagArgument::VALUE_FORBIDDEN: |
1564 | $policyApdx = ''; |
1592 | $policyApdx = ''; |
1565 | break; |
1593 | break; |
1566 | case VNagArgument::VALUE_REQUIRED: |
1594 | case VNagArgument::VALUE_REQUIRED: |
1567 | $policyApdx = ':'; |
1595 | $policyApdx = ':'; |
1568 | break; |
1596 | break; |
1569 | case VNagArgument::VALUE_OPTIONAL: |
1597 | case VNagArgument::VALUE_OPTIONAL: |
1570 | $policyApdx = '::'; |
1598 | $policyApdx = '::'; |
1571 | break; |
1599 | break; |
1572 | default: |
1600 | default: |
1573 | throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy)); |
1601 | throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy)); |
1574 | } |
1602 | } |
1575 | 1603 | ||
1576 | if ((!is_null($shortopt)) && ($shortopt != '?')) self::$all_short .= $shortopt.$policyApdx; |
1604 | if ((!is_null($shortopt)) && ($shortopt != '?')) self::$all_short .= $shortopt.$policyApdx; |
1577 | if (is_array($longopts)) { |
1605 | if (is_array($longopts)) { |
1578 | foreach ($longopts as $longopt) { |
1606 | foreach ($longopts as $longopt) { |
1579 | self::$all_long[] = $longopt.$policyApdx; |
1607 | self::$all_long[] = $longopt.$policyApdx; |
1580 | } |
1608 | } |
1581 | } |
1609 | } |
1582 | 1610 | ||
1583 | $this->shortopt = $shortopt; |
1611 | $this->shortopt = $shortopt; |
1584 | $this->longopts = $longopts; |
1612 | $this->longopts = $longopts; |
1585 | $this->valuePolicy = $valuePolicy; |
1613 | $this->valuePolicy = $valuePolicy; |
1586 | $this->valueName = $valueName; |
1614 | $this->valueName = $valueName; |
1587 | $this->helpText = $helpText; |
1615 | $this->helpText = $helpText; |
1588 | $this->defaultValue = $defaultValue; |
1616 | $this->defaultValue = $defaultValue; |
1589 | } |
1617 | } |
1590 | 1618 | ||
1591 | protected static function getOptions() { |
1619 | protected static function getOptions() { |
1592 | // Attention: In PHP 5.6.19-0+deb8u1 (cli), $_REQUEST is always set, so we need is_http_mode() instead of isset($_REQUEST)! |
1620 | // Attention: In PHP 5.6.19-0+deb8u1 (cli), $_REQUEST is always set, so we need is_http_mode() instead of isset($_REQUEST)! |
1593 | global $OVERWRITE_ARGUMENTS; |
1621 | global $OVERWRITE_ARGUMENTS; |
1594 | 1622 | ||
1595 | if (!is_null($OVERWRITE_ARGUMENTS)) { |
1623 | if (!is_null($OVERWRITE_ARGUMENTS)) { |
1596 | return $OVERWRITE_ARGUMENTS; |
1624 | return $OVERWRITE_ARGUMENTS; |
1597 | } else if (VNag::is_http_mode()) { |
1625 | } else if (VNag::is_http_mode()) { |
1598 | return $_REQUEST; |
1626 | return $_REQUEST; |
1599 | } else { |
1627 | } else { |
1600 | return getopt(self::$all_short, self::$all_long); |
1628 | return getopt(self::$all_short, self::$all_long); |
1601 | } |
1629 | } |
1602 | } |
1630 | } |
1603 | 1631 | ||
1604 | public function count() { |
1632 | public function count() { |
1605 | $options = self::getOptions(); |
1633 | $options = self::getOptions(); |
1606 | 1634 | ||
1607 | $count = 0; |
1635 | $count = 0; |
1608 | 1636 | ||
1609 | if (isset($options[$this->shortopt])) { |
1637 | if (isset($options[$this->shortopt])) { |
1610 | if (is_array($options[$this->shortopt])) { |
1638 | if (is_array($options[$this->shortopt])) { |
1611 | // e.g. -vvv |
1639 | // e.g. -vvv |
1612 | $count += count($options[$this->shortopt]); |
1640 | $count += count($options[$this->shortopt]); |
1613 | } else { |
1641 | } else { |
1614 | // e.g. -v |
1642 | // e.g. -v |
1615 | $count += 1; |
1643 | $count += 1; |
1616 | } |
1644 | } |
1617 | } |
1645 | } |
1618 | 1646 | ||
1619 | if (!is_null($this->longopts)) { |
1647 | if (!is_null($this->longopts)) { |
1620 | foreach ($this->longopts as $longopt) { |
1648 | foreach ($this->longopts as $longopt) { |
1621 | if (isset($options[$longopt])) { |
1649 | if (isset($options[$longopt])) { |
1622 | if (is_array($options[$longopt])) { |
1650 | if (is_array($options[$longopt])) { |
1623 | // e.g. --verbose --verbose --verbose |
1651 | // e.g. --verbose --verbose --verbose |
1624 | $count += count($options[$longopt]); |
1652 | $count += count($options[$longopt]); |
1625 | } else { |
1653 | } else { |
1626 | // e.g. --verbose |
1654 | // e.g. --verbose |
1627 | $count += 1; |
1655 | $count += 1; |
1628 | } |
1656 | } |
1629 | } |
1657 | } |
1630 | } |
1658 | } |
1631 | } |
1659 | } |
1632 | 1660 | ||
1633 | return $count; |
1661 | return $count; |
1634 | } |
1662 | } |
1635 | 1663 | ||
1636 | public function available() { |
1664 | public function available() { |
1637 | $options = self::getOptions(); |
1665 | $options = self::getOptions(); |
1638 | 1666 | ||
1639 | if (isset($options[$this->shortopt])) return true; |
1667 | if (isset($options[$this->shortopt])) return true; |
1640 | if (!is_null($this->longopts)) { |
1668 | if (!is_null($this->longopts)) { |
1641 | foreach ($this->longopts as $longopt) { |
1669 | foreach ($this->longopts as $longopt) { |
1642 | if (isset($options[$longopt])) return true; |
1670 | if (isset($options[$longopt])) return true; |
1643 | } |
1671 | } |
1644 | } |
1672 | } |
1645 | return false; |
1673 | return false; |
1646 | } |
1674 | } |
1647 | 1675 | ||
1648 | public function require() { |
1676 | public function require() { |
1649 | if (!$this->available() && is_null($this->defaultValue)) { |
1677 | if (!$this->available() && is_null($this->defaultValue)) { |
1650 | $opt = $this->shortopt; |
1678 | $opt = $this->shortopt; |
1651 | $opt = !_empty($opt) ? '-'.$opt : (isset($this->longopts[0]) ? '--'.$this->longopts[0] : '?'); |
1679 | $opt = !_empty($opt) ? '-'.$opt : (isset($this->longopts[0]) ? '--'.$this->longopts[0] : '?'); |
1652 | throw new VNagRequiredArgumentMissing($opt); |
1680 | throw new VNagRequiredArgumentMissing($opt); |
1653 | } |
1681 | } |
1654 | } |
1682 | } |
1655 | 1683 | ||
1656 | public function getValue() { |
1684 | public function getValue() { |
1657 | $options = self::getOptions(); |
1685 | $options = self::getOptions(); |
1658 | 1686 | ||
1659 | if (isset($options[$this->shortopt])) { |
1687 | if (isset($options[$this->shortopt])) { |
1660 | $x = $options[$this->shortopt]; |
1688 | $x = $options[$this->shortopt]; |
1661 | if (is_array($x) && (count($x) <= 1)) $options[$this->shortopt] = $options[$this->shortopt][0]; |
1689 | if (is_array($x) && (count($x) <= 1)) $options[$this->shortopt] = $options[$this->shortopt][0]; |
1662 | return $options[$this->shortopt]; |
1690 | return $options[$this->shortopt]; |
1663 | } |
1691 | } |
1664 | 1692 | ||
1665 | if (!is_null($this->longopts)) { |
1693 | if (!is_null($this->longopts)) { |
1666 | foreach ($this->longopts as $longopt) { |
1694 | foreach ($this->longopts as $longopt) { |
1667 | if (isset($options[$longopt])) { |
1695 | if (isset($options[$longopt])) { |
1668 | $x = $options[$longopt]; |
1696 | $x = $options[$longopt]; |
1669 | if (is_array($x) && (count($x) <= 1)) $options[$longopt] = $options[$longopt][0]; |
1697 | if (is_array($x) && (count($x) <= 1)) $options[$longopt] = $options[$longopt][0]; |
1670 | return $options[$longopt]; |
1698 | return $options[$longopt]; |
1671 | } |
1699 | } |
1672 | } |
1700 | } |
1673 | } |
1701 | } |
1674 | 1702 | ||
1675 | return $this->defaultValue; |
1703 | return $this->defaultValue; |
1676 | } |
1704 | } |
1677 | } |
1705 | } |
1678 | 1706 | ||
1679 | class VNagArgumentHandler { |
1707 | class VNagArgumentHandler { |
1680 | protected $expectedArgs = array(); |
1708 | protected $expectedArgs = array(); |
1681 | 1709 | ||
1682 | // Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually. |
1710 | // Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually. |
1683 | // Use VNag's function instead (since it adds to the helpObj too) |
1711 | // Use VNag's function instead (since it adds to the helpObj too) |
1684 | protected function _addExpectedArgument($argObj) { |
1712 | protected function _addExpectedArgument($argObj) { |
1685 | // -? is always illegal, so it will trigger illegalUsage(). So we don't add it to the list of |
1713 | // -? is always illegal, so it will trigger illegalUsage(). So we don't add it to the list of |
1686 | // expected arguments, otherwise illegalUsage() would be true. |
1714 | // expected arguments, otherwise illegalUsage() would be true. |
1687 | if ($argObj->getShortOpt() == '?') return false; |
1715 | if ($argObj->getShortOpt() == '?') return false; |
1688 | 1716 | ||
1689 | // GNU extensions with a special meaning |
1717 | // GNU extensions with a special meaning |
1690 | if ($argObj->getShortOpt() == '-') return false; // cancel parsing |
1718 | if ($argObj->getShortOpt() == '-') return false; // cancel parsing |
1691 | if ($argObj->getShortOpt() == '+') return false; // enable POSIXLY_CORRECT |
1719 | if ($argObj->getShortOpt() == '+') return false; // enable POSIXLY_CORRECT |
1692 | 1720 | ||
1693 | $this->expectedArgs[] = $argObj; |
1721 | $this->expectedArgs[] = $argObj; |
1694 | return true; |
1722 | return true; |
1695 | } |
1723 | } |
1696 | 1724 | ||
1697 | public function getArgumentObj($shortopt) { |
1725 | public function getArgumentObj($shortopt) { |
1698 | foreach ($this->expectedArgs as $argObj) { |
1726 | foreach ($this->expectedArgs as $argObj) { |
1699 | if ($argObj->getShortOpt() == $shortopt) return $argObj; |
1727 | if ($argObj->getShortOpt() == $shortopt) return $argObj; |
1700 | } |
1728 | } |
1701 | return null; |
1729 | return null; |
1702 | } |
1730 | } |
1703 | 1731 | ||
1704 | public function isArgRegistered($shortopt) { |
1732 | public function isArgRegistered($shortopt) { |
1705 | return !is_null($this->getArgumentObj($shortopt)); |
1733 | return !is_null($this->getArgumentObj($shortopt)); |
1706 | } |
1734 | } |
1707 | 1735 | ||
1708 | public function illegalUsage() { |
1736 | public function illegalUsage() { |
1709 | // In this function, we should check if $argv (resp. getopts) contains stuff which is not expected or illegal, |
1737 | // In this function, we should check if $argv (resp. getopts) contains stuff which is not expected or illegal, |
1710 | // so the script can show a usage information and quit the program. |
1738 | // so the script can show a usage information and quit the program. |
1711 | 1739 | ||
1712 | // WONTFIX: PHP's horrible implementation of GNU's getopt does not allow following intended tasks: |
1740 | // WONTFIX: PHP's horrible implementation of GNU's getopt does not allow following intended tasks: |
1713 | // - check for illegal values/arguments (e.g. the argument -? which is always illegal) |
1741 | // - check for illegal values/arguments (e.g. the argument -? which is always illegal) |
1714 | // - check for missing values (e.g. -H instead of -H localhost ) |
1742 | // - check for missing values (e.g. -H instead of -H localhost ) |
1715 | // - check for unexpected arguments (e.g. -x if only -a -b -c are defined in $expectedArgs as expected arguments) |
1743 | // - check for unexpected arguments (e.g. -x if only -a -b -c are defined in $expectedArgs as expected arguments) |
1716 | // - Of course, everything behind "--" may not be evaluated |
1744 | // - Of course, everything behind "--" may not be evaluated |
1717 | // see also http://stackoverflow.com/questions/25388130/catch-unexpected-options-with-getopt |
1745 | // see also http://stackoverflow.com/questions/25388130/catch-unexpected-options-with-getopt |
1718 | 1746 | ||
1719 | // So the only way is to do this stupid hard coded check for '-?' |
1747 | // So the only way is to do this stupid hard coded check for '-?' |
1720 | // PHP sucks... |
1748 | // PHP sucks... |
1721 | global $argv; |
1749 | global $argv; |
1722 | return (isset($argv[1])) && (($argv[1] == '-?') || ($argv[1] == '/?')); |
1750 | return (isset($argv[1])) && (($argv[1] == '-?') || ($argv[1] == '/?')); |
1723 | } |
1751 | } |
1724 | } |
1752 | } |
1725 | 1753 | ||
1726 | class VNagRange { |
1754 | class VNagRange { |
1727 | // see https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT |
1755 | // see https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT |
1728 | // We allow UOMs inside the range definition, e.g. "-w @10M:50M" |
1756 | // We allow UOMs inside the range definition, e.g. "-w @10M:50M" |
1729 | 1757 | ||
1730 | public /*VNagValueUomPair|'-inf'*/ $start; |
1758 | public /*VNagValueUomPair|'-inf'*/ $start; |
1731 | public /*VNagValueUomPair|'inf'*/ $end; |
1759 | public /*VNagValueUomPair|'inf'*/ $end; |
1732 | public /*boolean*/ $warnInsideRange; |
1760 | public /*boolean*/ $warnInsideRange; |
1733 | 1761 | ||
1734 | public function __construct($rangeDef, $singleValueBehavior=VNag::SINGLEVALUE_RANGE_DEFAULT) { |
1762 | public function __construct($rangeDef, $singleValueBehavior=VNag::SINGLEVALUE_RANGE_DEFAULT) { |
1735 | $m = array(); |
1763 | $m = array(); |
1736 | //if (!preg_match('|(@){0,1}(\d+)(:){0,1}(\d+){0,1}|', $rangeDef, $m)) { |
1764 | //if (!preg_match('|(@){0,1}(\d+)(:){0,1}(\d+){0,1}|', $rangeDef, $m)) { |
1737 | if (!preg_match('|^(@){0,1}([^:]+)(:){0,1}(.*)$|', $rangeDef, $m)) { |
1765 | if (!preg_match('|^(@){0,1}([^:]+)(:){0,1}(.*)$|', $rangeDef, $m)) { |
1738 | throw new VNagInvalidRangeException(sprintf(VNagLang::$range_invalid_syntax, $rangeDef)); |
1766 | throw new VNagInvalidRangeException(sprintf(VNagLang::$range_invalid_syntax, $rangeDef)); |
1739 | } |
1767 | } |
1740 | 1768 | ||
1741 | $this->warnInsideRange = $m[1] === '@'; |
1769 | $this->warnInsideRange = $m[1] === '@'; |
1742 | 1770 | ||
1743 | $this->start = null; |
1771 | $this->start = null; |
1744 | $this->end = null; |
1772 | $this->end = null; |
1745 | 1773 | ||
1746 | if ($m[3] === ':') { |
1774 | if ($m[3] === ':') { |
1747 | if ($m[2] === '~') { |
1775 | if ($m[2] === '~') { |
1748 | $this->start = '-inf'; |
1776 | $this->start = '-inf'; |
1749 | } else { |
1777 | } else { |
1750 | $this->start = new VNagValueUomPair($m[2]); |
1778 | $this->start = new VNagValueUomPair($m[2]); |
1751 | } |
1779 | } |
1752 | 1780 | ||
1753 | if (_empty($m[4])) { |
1781 | if (_empty($m[4])) { |
1754 | $this->end = 'inf'; |
1782 | $this->end = 'inf'; |
1755 | } else { |
1783 | } else { |
1756 | $this->end = new VNagValueUomPair($m[4]); |
1784 | $this->end = new VNagValueUomPair($m[4]); |
1757 | } |
1785 | } |
1758 | } else { |
1786 | } else { |
1759 | assert(_empty($m[4])); |
1787 | assert(_empty($m[4])); |
1760 | assert(!_empty($m[2])); |
1788 | assert(!_empty($m[2])); |
1761 | 1789 | ||
1762 | $x = $m[2]; |
1790 | $x = $m[2]; |
1763 | 1791 | ||
1764 | if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_DEFAULT) { |
1792 | if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_DEFAULT) { |
1765 | // Default behavior according to the development guidelines: |
1793 | // Default behavior according to the development guidelines: |
1766 | // x means 0:x, which means, x>10 is bad |
1794 | // x means 0:x, which means, x>10 is bad |
1767 | // @x means @0:x, which means, x<=10 is bad |
1795 | // @x means @0:x, which means, x<=10 is bad |
1768 | $this->start = new VNagValueUomPair('0'.((new VNagValueUomPair($x))->getUom())); |
1796 | $this->start = new VNagValueUomPair('0'.((new VNagValueUomPair($x))->getUom())); |
1769 | $this->end = new VNagValueUomPair($x); |
1797 | $this->end = new VNagValueUomPair($x); |
1770 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GT_X_BAD) { |
1798 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GT_X_BAD) { |
1771 | // The single value x means, everything > x is bad. @x is not defined. |
1799 | // The single value x means, everything > x is bad. @x is not defined. |
1772 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1800 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1773 | $this->warnInsideRange = 0; |
1801 | $this->warnInsideRange = 0; |
1774 | $this->start = '-inf'; |
1802 | $this->start = '-inf'; |
1775 | $this->end = new VNagValueUomPair($x); |
1803 | $this->end = new VNagValueUomPair($x); |
1776 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GE_X_BAD) { |
1804 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GE_X_BAD) { |
1777 | // The single value x means, everything >= x is bad. @x is not defined. |
1805 | // The single value x means, everything >= x is bad. @x is not defined. |
1778 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1806 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1779 | $this->warnInsideRange = 1; |
1807 | $this->warnInsideRange = 1; |
1780 | $this->start = new VNagValueUomPair($x); |
1808 | $this->start = new VNagValueUomPair($x); |
1781 | $this->end = 'inf'; |
1809 | $this->end = 'inf'; |
1782 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD) { |
1810 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD) { |
1783 | // The single value x means, everything < x is bad. @x is not defined. |
1811 | // The single value x means, everything < x is bad. @x is not defined. |
1784 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1812 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1785 | $this->warnInsideRange = 0; |
1813 | $this->warnInsideRange = 0; |
1786 | $this->start = new VNagValueUomPair($x); |
1814 | $this->start = new VNagValueUomPair($x); |
1787 | $this->end = 'inf'; |
1815 | $this->end = 'inf'; |
1788 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LE_X_BAD) { |
1816 | } else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LE_X_BAD) { |
1789 | // The single value x means, everything <= x is bad. @x is not defined. |
1817 | // The single value x means, everything <= x is bad. @x is not defined. |
1790 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1818 | if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol); |
1791 | $this->warnInsideRange = 1; |
1819 | $this->warnInsideRange = 1; |
1792 | $this->start = '-inf'; |
1820 | $this->start = '-inf'; |
1793 | $this->end = new VNagValueUomPair($x); |
1821 | $this->end = new VNagValueUomPair($x); |
1794 | } else { |
1822 | } else { |
1795 | throw new VNagException(VNagLang::$illegalSingleValueBehavior); |
1823 | throw new VNagException(VNagLang::$illegalSingleValueBehavior); |
1796 | } |
1824 | } |
1797 | } |
1825 | } |
1798 | 1826 | ||
1799 | // Check if range is valid |
1827 | // Check if range is valid |
1800 | if (is_null($this->start)) { |
1828 | if (is_null($this->start)) { |
1801 | throw new VNagInvalidRangeException(VNagLang::$invalid_start_value); |
1829 | throw new VNagInvalidRangeException(VNagLang::$invalid_start_value); |
1802 | } |
1830 | } |
1803 | if (is_null($this->end)) { |
1831 | if (is_null($this->end)) { |
1804 | throw new VNagInvalidRangeException(VNagLang::$invalid_end_value); |
1832 | throw new VNagInvalidRangeException(VNagLang::$invalid_end_value); |
1805 | } |
1833 | } |
1806 | if (($this->start instanceof VNagValueUomPair) && ($this->end instanceof VNagValueUomPair) && |
1834 | if (($this->start instanceof VNagValueUomPair) && ($this->end instanceof VNagValueUomPair) && |
1807 | (VNagValueUomPair::compare($this->start,$this->end) > 0)) { |
1835 | (VNagValueUomPair::compare($this->start,$this->end) > 0)) { |
1808 | throw new VNagInvalidRangeException(VNagLang::$start_is_greater_than_end); |
1836 | throw new VNagInvalidRangeException(VNagLang::$start_is_greater_than_end); |
1809 | } |
1837 | } |
1810 | } |
1838 | } |
1811 | 1839 | ||
1812 | public function __toString() { |
1840 | public function __toString() { |
1813 | // Attention: |
1841 | // Attention: |
1814 | // - this function assumes that $start and $end are valid. |
1842 | // - this function assumes that $start and $end are valid. |
1815 | // - not the shortest result will be chosen |
1843 | // - not the shortest result will be chosen |
1816 | 1844 | ||
1817 | $ret = ''; |
1845 | $ret = ''; |
1818 | if ($this->warnInsideRange) { |
1846 | if ($this->warnInsideRange) { |
1819 | $ret = '@'; |
1847 | $ret = '@'; |
1820 | } |
1848 | } |
1821 | 1849 | ||
1822 | if ($this->start === '-inf') { |
1850 | if ($this->start === '-inf') { |
1823 | $ret .= '~'; |
1851 | $ret .= '~'; |
1824 | } else { |
1852 | } else { |
1825 | $ret .= $this->start; |
1853 | $ret .= $this->start; |
1826 | } |
1854 | } |
1827 | 1855 | ||
1828 | $ret .= ':'; |
1856 | $ret .= ':'; |
1829 | 1857 | ||
1830 | if ($this->end !== 'inf') { |
1858 | if ($this->end !== 'inf') { |
1831 | $ret .= $this->end; |
1859 | $ret .= $this->end; |
1832 | } |
1860 | } |
1833 | 1861 | ||
1834 | return $ret; |
1862 | return $ret; |
1835 | } |
1863 | } |
1836 | 1864 | ||
1837 | public function checkAlert($values) { |
1865 | public function checkAlert($values) { |
1838 | $compatibleCount = 0; |
1866 | $compatibleCount = 0; |
1839 | 1867 | ||
1840 | if (!is_array($values)) $values = array($values); |
1868 | if (!is_array($values)) $values = array($values); |
1841 | foreach ($values as $value) { |
1869 | foreach ($values as $value) { |
1842 | if (!($value instanceof VNagValueUomPair)) $value = new VNagValueUomPair($value); |
1870 | if (!($value instanceof VNagValueUomPair)) $value = new VNagValueUomPair($value); |
1843 | 1871 | ||
1844 | assert(($this->start === '-inf') || ($this->start instanceof VNagValueUomPair)); |
1872 | assert(($this->start === '-inf') || ($this->start instanceof VNagValueUomPair)); |
1845 | assert(($this->end === 'inf' ) || ($this->end instanceof VNagValueUomPair)); |
1873 | assert(($this->end === 'inf' ) || ($this->end instanceof VNagValueUomPair)); |
1846 | 1874 | ||
1847 | if (($this->start !== '-inf') && (!$this->start->compatibleWith($value))) continue; |
1875 | if (($this->start !== '-inf') && (!$this->start->compatibleWith($value))) continue; |
1848 | if (($this->end !== 'inf') && (!$this->end->compatibleWith($value))) continue; |
1876 | if (($this->end !== 'inf') && (!$this->end->compatibleWith($value))) continue; |
1849 | $compatibleCount++; |
1877 | $compatibleCount++; |
1850 | 1878 | ||
1851 | if ($this->warnInsideRange) { |
1879 | if ($this->warnInsideRange) { |
1852 | return (($this->start === '-inf') || (VNagValueUomPair::compare($value,$this->start) >= 0)) && |
1880 | return (($this->start === '-inf') || (VNagValueUomPair::compare($value,$this->start) >= 0)) && |
1853 | (($this->end === 'inf') || (VNagValueUomPair::compare($value,$this->end) <= 0)); |
1881 | (($this->end === 'inf') || (VNagValueUomPair::compare($value,$this->end) <= 0)); |
1854 | } else { |
1882 | } else { |
1855 | return (($this->start !== '-inf') && (VNagValueUomPair::compare($value,$this->start) < 0)) || |
1883 | return (($this->start !== '-inf') && (VNagValueUomPair::compare($value,$this->start) < 0)) || |
1856 | (($this->end !== 'inf') && (VNagValueUomPair::compare($value,$this->end) > 0)); |
1884 | (($this->end !== 'inf') && (VNagValueUomPair::compare($value,$this->end) > 0)); |
1857 | } |
1885 | } |
1858 | } |
1886 | } |
1859 | 1887 | ||
1860 | if ((count($values) > 0) and ($compatibleCount == 0)) { |
1888 | if ((count($values) > 0) and ($compatibleCount == 0)) { |
1861 | throw new VNagNoCompatibleRangeUomFoundException(VNagLang::$no_compatible_range_uom_found); |
1889 | throw new VNagNoCompatibleRangeUomFoundException(VNagLang::$no_compatible_range_uom_found); |
1862 | } |
1890 | } |
1863 | 1891 | ||
1864 | return false; |
1892 | return false; |
1865 | } |
1893 | } |
1866 | } |
1894 | } |
1867 | 1895 | ||
1868 | class VNagValueUomPair { |
1896 | class VNagValueUomPair { |
1869 | protected $value; |
1897 | protected $value; |
1870 | protected $uom; |
1898 | protected $uom; |
1871 | public $roundTo = -1; |
1899 | public $roundTo = -1; |
1872 | 1900 | ||
1873 | public function isRelative() { |
1901 | public function isRelative() { |
1874 | return $this->uom === '%'; |
1902 | return $this->uom === '%'; |
1875 | } |
1903 | } |
1876 | 1904 | ||
1877 | public function getValue() { |
1905 | public function getValue() { |
1878 | return $this->value; |
1906 | return $this->value; |
1879 | } |
1907 | } |
1880 | 1908 | ||
1881 | public function getUom() { |
1909 | public function getUom() { |
1882 | return $this->uom; |
1910 | return $this->uom; |
1883 | } |
1911 | } |
1884 | 1912 | ||
1885 | public function __toString() { |
1913 | public function __toString() { |
1886 | if ($this->roundTo == -1) { |
1914 | if ($this->roundTo == -1) { |
1887 | return $this->value.$this->uom; |
1915 | return $this->value.$this->uom; |
1888 | } else { |
1916 | } else { |
1889 | return round($this->value,$this->roundTo).$this->uom; |
1917 | return round($this->value,$this->roundTo).$this->uom; |
1890 | } |
1918 | } |
1891 | } |
1919 | } |
1892 | 1920 | ||
1893 | public function __construct($str) { |
1921 | public function __construct($str) { |
1894 | $m = array(); |
1922 | $m = array(); |
1895 | if (!preg_match('/^([\d\.]+)(.*)$/ism', $str, $m)) { |
1923 | if (!preg_match('/^([\d\.]+)(.*)$/ism', $str, $m)) { |
1896 | throw new VNagValueUomPairSyntaxException($str); |
1924 | throw new VNagValueUomPairSyntaxException($str); |
1897 | } |
1925 | } |
1898 | $this->value = $m[1]; |
1926 | $this->value = $m[1]; |
1899 | $this->uom = isset($m[2]) ? $m[2] : ''; |
1927 | $this->uom = isset($m[2]) ? $m[2] : ''; |
1900 | 1928 | ||
1901 | if (!self::isKnownUOM($this->uom)) { |
1929 | if (!self::isKnownUOM($this->uom)) { |
1902 | throw new VNagUnknownUomException($this->uom); |
1930 | throw new VNagUnknownUomException($this->uom); |
1903 | } |
1931 | } |
1904 | } |
1932 | } |
1905 | 1933 | ||
1906 | public static function isKnownUOM(string $uom) { |
1934 | public static function isKnownUOM(string $uom) { |
1907 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
1935 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
1908 | // 10. UOM (unit of measurement) is one of: |
1936 | // 10. UOM (unit of measurement) is one of: |
1909 | 1937 | ||
1910 | // no unit specified - assume a number (int or float) of things (eg, users, processes, load averages) |
1938 | // no unit specified - assume a number (int or float) of things (eg, users, processes, load averages) |
1911 | $no_unit = ($uom === ''); |
1939 | $no_unit = ($uom === ''); |
1912 | // s - seconds (also us, ms) |
1940 | // s - seconds (also us, ms) |
1913 | $seconds = ($uom === 's') || ($uom === 'ms') || ($uom === 'us'); |
1941 | $seconds = ($uom === 's') || ($uom === 'ms') || ($uom === 'us'); |
1914 | // % - percentage |
1942 | // % - percentage |
1915 | $percentage = ($uom === '%'); |
1943 | $percentage = ($uom === '%'); |
1916 | // B - bytes (also KB, MB, TB) |
1944 | // B - bytes (also KB, MB, TB) |
1917 | // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway |
1945 | // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway |
1918 | $bytes = ($uom === 'B') || ($uom === 'KB') || ($uom === 'MB') || ($uom === 'GB') || ($uom === 'TB'); |
1946 | $bytes = ($uom === 'B') || ($uom === 'KB') || ($uom === 'MB') || ($uom === 'GB') || ($uom === 'TB'); |
1919 | // c - a continous counter (such as bytes transmitted on an interface) |
1947 | // c - a continous counter (such as bytes transmitted on an interface) |
1920 | $counter = ($uom === 'c'); |
1948 | $counter = ($uom === 'c'); |
1921 | 1949 | ||
1922 | return ($no_unit || $seconds || $percentage || $bytes || $counter); |
1950 | return ($no_unit || $seconds || $percentage || $bytes || $counter); |
1923 | } |
1951 | } |
1924 | 1952 | ||
1925 | public function normalize($target=null) { |
1953 | public function normalize($target=null) { |
1926 | $res = clone $this; |
1954 | $res = clone $this; |
1927 | 1955 | ||
1928 | // The value is normalized to seconds or megabytes |
1956 | // The value is normalized to seconds or megabytes |
1929 | if ($res->uom === 'ms') { |
1957 | if ($res->uom === 'ms') { |
1930 | $res->uom = 's'; |
1958 | $res->uom = 's'; |
1931 | $res->value /= 1000; |
1959 | $res->value /= 1000; |
1932 | } |
1960 | } |
1933 | if ($res->uom === 'us') { |
1961 | if ($res->uom === 'us') { |
1934 | $res->uom = 's'; |
1962 | $res->uom = 's'; |
1935 | $res->value /= 1000 * 1000; |
1963 | $res->value /= 1000 * 1000; |
1936 | } |
1964 | } |
1937 | if ($res->uom === 'B') { |
1965 | if ($res->uom === 'B') { |
1938 | $res->uom = 'MB'; |
1966 | $res->uom = 'MB'; |
1939 | $res->value /= 1024 * 1024; |
1967 | $res->value /= 1024 * 1024; |
1940 | } |
1968 | } |
1941 | if ($res->uom === 'KB') { |
1969 | if ($res->uom === 'KB') { |
1942 | $res->uom = 'MB'; |
1970 | $res->uom = 'MB'; |
1943 | $res->value /= 1024; |
1971 | $res->value /= 1024; |
1944 | } |
1972 | } |
1945 | if ($res->uom === 'GB') { |
1973 | if ($res->uom === 'GB') { |
1946 | $res->uom = 'MB'; |
1974 | $res->uom = 'MB'; |
1947 | $res->value *= 1024; |
1975 | $res->value *= 1024; |
1948 | } |
1976 | } |
1949 | if ($res->uom === 'TB') { |
1977 | if ($res->uom === 'TB') { |
1950 | $res->uom = 'MB'; |
1978 | $res->uom = 'MB'; |
1951 | $res->value *= 1024 * 1024; |
1979 | $res->value *= 1024 * 1024; |
1952 | } |
1980 | } |
1953 | if ($res->uom === 'c') { |
1981 | if ($res->uom === 'c') { |
1954 | $res->uom = ''; |
1982 | $res->uom = ''; |
1955 | } |
1983 | } |
1956 | 1984 | ||
1957 | // Now, if the user wishes, convert to another unit |
1985 | // Now, if the user wishes, convert to another unit |
1958 | if (!is_null($target)) { |
1986 | if (!is_null($target)) { |
1959 | if ($res->uom == 'MB') { |
1987 | if ($res->uom == 'MB') { |
1960 | if ($target == 'B') { |
1988 | if ($target == 'B') { |
1961 | $res->uom = 'B'; |
1989 | $res->uom = 'B'; |
1962 | $res->value *= 1024 * 1024; |
1990 | $res->value *= 1024 * 1024; |
1963 | } else if ($target == 'KB') { |
1991 | } else if ($target == 'KB') { |
1964 | $res->uom = 'KB'; |
1992 | $res->uom = 'KB'; |
1965 | $res->value *= 1024; |
1993 | $res->value *= 1024; |
1966 | } else if ($target == 'MB') { |
1994 | } else if ($target == 'MB') { |
1967 | $res->uom = 'MB'; |
1995 | $res->uom = 'MB'; |
1968 | $res->value *= 1; |
1996 | $res->value *= 1; |
1969 | } else if ($target == 'GB') { |
1997 | } else if ($target == 'GB') { |
1970 | $res->uom = 'GB'; |
1998 | $res->uom = 'GB'; |
1971 | $res->value /= 1024; |
1999 | $res->value /= 1024; |
1972 | } else if ($target == 'TB') { |
2000 | } else if ($target == 'TB') { |
1973 | $res->uom = 'TB'; |
2001 | $res->uom = 'TB'; |
1974 | $res->value /= 1024 * 1024; |
2002 | $res->value /= 1024 * 1024; |
1975 | } else { |
2003 | } else { |
1976 | throw new VNagUomConvertException($res->uom, $target); |
2004 | throw new VNagUomConvertException($res->uom, $target); |
1977 | } |
2005 | } |
1978 | } else if ($res->uom == 's') { |
2006 | } else if ($res->uom == 's') { |
1979 | if ($target == 's') { |
2007 | if ($target == 's') { |
1980 | $res->uom = 's'; |
2008 | $res->uom = 's'; |
1981 | $res->value /= 1; |
2009 | $res->value /= 1; |
1982 | } else if ($target == 'ms') { |
2010 | } else if ($target == 'ms') { |
1983 | $res->uom = 'ms'; |
2011 | $res->uom = 'ms'; |
1984 | $res->value /= 1000; |
2012 | $res->value /= 1000; |
1985 | } else if ($target == 'us') { |
2013 | } else if ($target == 'us') { |
1986 | $res->uom = 'us'; |
2014 | $res->uom = 'us'; |
1987 | $res->value /= 1000 * 1000; |
2015 | $res->value /= 1000 * 1000; |
1988 | } else { |
2016 | } else { |
1989 | throw new VNagUomConvertException($res->uom, $target); |
2017 | throw new VNagUomConvertException($res->uom, $target); |
1990 | } |
2018 | } |
1991 | } else { |
2019 | } else { |
1992 | throw new VNagUomConvertException($res->uom, $target); |
2020 | throw new VNagUomConvertException($res->uom, $target); |
1993 | } |
2021 | } |
1994 | } |
2022 | } |
1995 | 2023 | ||
1996 | return $res; |
2024 | return $res; |
1997 | } |
2025 | } |
1998 | 2026 | ||
1999 | public function compatibleWith(VNagValueUomPair $other) { |
2027 | public function compatibleWith(VNagValueUomPair $other) { |
2000 | $a = $this->normalize(); |
2028 | $a = $this->normalize(); |
2001 | $b = $other->normalize(); |
2029 | $b = $other->normalize(); |
2002 | 2030 | ||
2003 | return ($a->uom == $b->uom); |
2031 | return ($a->uom == $b->uom); |
2004 | } |
2032 | } |
2005 | 2033 | ||
2006 | public static function compare(VNagValueUomPair $left, VNagValueUomPair $right) { |
2034 | public static function compare(VNagValueUomPair $left, VNagValueUomPair $right) { |
2007 | $a = $left->normalize(); |
2035 | $a = $left->normalize(); |
2008 | $b = $right->normalize(); |
2036 | $b = $right->normalize(); |
2009 | 2037 | ||
2010 | // FUT: Also accept mixed UOMs, e.g. MB and % |
2038 | // FUT: Also accept mixed UOMs, e.g. MB and % |
2011 | // To translate between an absolute and a relative value, the |
2039 | // To translate between an absolute and a relative value, the |
2012 | // reference value (100%=?) needs to be passed through this comparison |
2040 | // reference value (100%=?) needs to be passed through this comparison |
2013 | // function somehow. |
2041 | // function somehow. |
2014 | if ($a->uom != $b->uom) throw new VNagMixedUomsNotImplemented($a->uom, $b->uom); |
2042 | if ($a->uom != $b->uom) throw new VNagMixedUomsNotImplemented($a->uom, $b->uom); |
2015 | 2043 | ||
2016 | if ($a->value > $b->value) return 1; |
2044 | if ($a->value > $b->value) return 1; |
2017 | if ($a->value == $b->value) return 0; |
2045 | if ($a->value == $b->value) return 0; |
2018 | if ($a->value < $b->value) return -1; |
2046 | if ($a->value < $b->value) return -1; |
2019 | } |
2047 | } |
2020 | } |
2048 | } |
2021 | 2049 | ||
2022 | class VNagPerformanceData { |
2050 | class VNagPerformanceData { |
2023 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
2051 | // see https://nagios-plugins.org/doc/guidelines.html#AEN200 |
2024 | // https://www.icinga.com/docs/icinga1/latest/en/perfdata.html#formatperfdata |
2052 | // https://www.icinga.com/docs/icinga1/latest/en/perfdata.html#formatperfdata |
2025 | 2053 | ||
2026 | protected $label; |
2054 | protected $label; |
2027 | protected /*VNagValueUomPair*/ $value; |
2055 | protected /*VNagValueUomPair*/ $value; |
2028 | protected $warn = null; |
2056 | protected $warn = null; |
2029 | protected $crit = null; |
2057 | protected $crit = null; |
2030 | protected $min = null; |
2058 | protected $min = null; |
2031 | protected $max = null; |
2059 | protected $max = null; |
2032 | 2060 | ||
2033 | public static function createByString($perfdata) { |
2061 | public static function createByString($perfdata) { |
2034 | $perfdata = trim($perfdata); |
2062 | $perfdata = trim($perfdata); |
2035 | 2063 | ||
2036 | $ary = explode('=',$perfdata); |
2064 | $ary = explode('=',$perfdata); |
2037 | if (count($ary) != 2) { |
2065 | if (count($ary) != 2) { |
2038 | throw new VNagInvalidPerformanceDataException(sprintf(VNagLang::$perfdata_line_invalid, $perfdata)); |
2066 | throw new VNagInvalidPerformanceDataException(sprintf(VNagLang::$perfdata_line_invalid, $perfdata)); |
2039 | } |
2067 | } |
2040 | $label = $ary[0]; |
2068 | $label = $ary[0]; |
2041 | $bry = explode(';',$ary[1]); |
2069 | $bry = explode(';',$ary[1]); |
2042 | if (substr($label,0,1) === "'") $label = substr($label, 1, strlen($label)-2); |
2070 | if (substr($label,0,1) === "'") $label = substr($label, 1, strlen($label)-2); |
2043 | $value = $bry[0]; |
2071 | $value = $bry[0]; |
2044 | $warn = isset($bry[1]) ? $bry[1] : null; |
2072 | $warn = isset($bry[1]) ? $bry[1] : null; |
2045 | $crit = isset($bry[2]) ? $bry[2] : null; |
2073 | $crit = isset($bry[2]) ? $bry[2] : null; |
2046 | $min = isset($bry[3]) ? $bry[3] : null; |
2074 | $min = isset($bry[3]) ? $bry[3] : null; |
2047 | $max = isset($bry[4]) ? $bry[4] : null; |
2075 | $max = isset($bry[4]) ? $bry[4] : null; |
2048 | 2076 | ||
2049 | // Guideline "7. min and max are not required if UOM=%" makes no sense, because |
2077 | // Guideline "7. min and max are not required if UOM=%" makes no sense, because |
2050 | // actually, all fields (except label and value) are optional. |
2078 | // actually, all fields (except label and value) are optional. |
2051 | 2079 | ||
2052 | return new self($label, $value, $warn, $crit, $min, $max); |
2080 | return new self($label, $value, $warn, $crit, $min, $max); |
2053 | } |
2081 | } |
2054 | 2082 | ||
2055 | public function __construct($label, $value/*may include UOM*/, $warn=null, $crit=null, $min=null, $max=null) { |
2083 | public function __construct($label, $value/*may include UOM*/, $warn=null, $crit=null, $min=null, $max=null) { |
2056 | // Not checked / Nothing to check: |
2084 | // Not checked / Nothing to check: |
2057 | // - 4. label length is arbitrary, but ideally the first 19 characters are unique (due to a limitation in RRD). Be aware of a limitation in the amount of data that NRPE returns to Nagios |
2085 | // - 4. label length is arbitrary, but ideally the first 19 characters are unique (due to a limitation in RRD). Be aware of a limitation in the amount of data that NRPE returns to Nagios |
2058 | // - 6. warn, crit, min or max may be null (for example, if the threshold is not defined or min and max do not apply). Trailing unfilled semicolons can be dropped |
2086 | // - 6. warn, crit, min or max may be null (for example, if the threshold is not defined or min and max do not apply). Trailing unfilled semicolons can be dropped |
2059 | // - 9. warn and crit are in the range format (see the Section called Threshold and ranges). Must be the same UOM |
2087 | // - 9. warn and crit are in the range format (see the Section called Threshold and ranges). Must be the same UOM |
2060 | // - 7. min and max are not required if UOM=% |
2088 | // - 7. min and max are not required if UOM=% |
2061 | 2089 | ||
2062 | // 2. label can contain any characters except the equals sign or single quote (') |
2090 | // 2. label can contain any characters except the equals sign or single quote (') |
2063 | if (strpos($label, '=') !== false) throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_label_equal_sign_forbidden); |
2091 | if (strpos($label, '=') !== false) throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_label_equal_sign_forbidden); |
2064 | 2092 | ||
2065 | // 5. to specify a quote character, use two single quotes |
2093 | // 5. to specify a quote character, use two single quotes |
2066 | $label = str_replace("'", "''", $label); |
2094 | $label = str_replace("'", "''", $label); |
2067 | 2095 | ||
2068 | // 8. value, min and max in class [-0-9.]. Must all be the same UOM. |
2096 | // 8. value, min and max in class [-0-9.]. Must all be the same UOM. |
2069 | // value may be a literal "U" instead, this would indicate that the actual value couldn't be determined |
2097 | // value may be a literal "U" instead, this would indicate that the actual value couldn't be determined |
2070 | /* |
2098 | /* |
2071 | if (($value != 'U') && (!preg_match('|^[-0-9\\.]+$|', $value, $m))) { |
2099 | if (($value != 'U') && (!preg_match('|^[-0-9\\.]+$|', $value, $m))) { |
2072 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_value_must_be_in_class); |
2100 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_value_must_be_in_class); |
2073 | } |
2101 | } |
2074 | */ |
2102 | */ |
2075 | $m = array(); |
2103 | $m = array(); |
2076 | if ((!_empty($min)) && (!preg_match('|^[-0-9\\.]+$|', $min, $m))) { |
2104 | if ((!_empty($min)) && (!preg_match('|^[-0-9\\.]+$|', $min, $m))) { |
2077 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_min_must_be_in_class); |
2105 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_min_must_be_in_class); |
2078 | } |
2106 | } |
2079 | if ((!_empty($max)) && (!preg_match('|^[-0-9\\.]+$|', $max, $m))) { |
2107 | if ((!_empty($max)) && (!preg_match('|^[-0-9\\.]+$|', $max, $m))) { |
2080 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_max_must_be_in_class); |
2108 | throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_max_must_be_in_class); |
2081 | } |
2109 | } |
2082 | 2110 | ||
2083 | // 10. UOM (unit of measurement) is one of .... |
2111 | // 10. UOM (unit of measurement) is one of .... |
2084 | // => This rule is checked in the VNagValueUomPair constructor. |
2112 | // => This rule is checked in the VNagValueUomPair constructor. |
2085 | 2113 | ||
2086 | $this->label = $label; |
2114 | $this->label = $label; |
2087 | $this->value = ($value == 'U') ? 'U' : new VNagValueUomPair($value); |
2115 | $this->value = ($value == 'U') ? 'U' : new VNagValueUomPair($value); |
2088 | $this->warn = $warn; |
2116 | $this->warn = $warn; |
2089 | $this->crit = $crit; |
2117 | $this->crit = $crit; |
2090 | $this->min = $min; |
2118 | $this->min = $min; |
2091 | $this->max = $max; |
2119 | $this->max = $max; |
2092 | } |
2120 | } |
2093 | 2121 | ||
2094 | public function __toString() { |
2122 | public function __toString() { |
2095 | $label = $this->label; |
2123 | $label = $this->label; |
2096 | $value = $this->value; |
2124 | $value = $this->value; |
2097 | $warn = $this->warn; |
2125 | $warn = $this->warn; |
2098 | $crit = $this->crit; |
2126 | $crit = $this->crit; |
2099 | $min = $this->min; |
2127 | $min = $this->min; |
2100 | $max = $this->max; |
2128 | $max = $this->max; |
2101 | 2129 | ||
2102 | // 5. to specify a quote character, use two single quotes |
2130 | // 5. to specify a quote character, use two single quotes |
2103 | $label = str_replace("''", "'", $label); |
2131 | $label = str_replace("''", "'", $label); |
2104 | 2132 | ||
2105 | // 'label'=value[UOM];[warn];[crit];[min];[max] |
2133 | // 'label'=value[UOM];[warn];[crit];[min];[max] |
2106 | // 3. the single quotes for the label are optional. Required if spaces are in the label |
2134 | // 3. the single quotes for the label are optional. Required if spaces are in the label |
2107 | return "'$label'=$value". |
2135 | return "'$label'=$value". |
2108 | ';'.(is_null($warn) ? '' : $warn). |
2136 | ';'.(is_null($warn) ? '' : $warn). |
2109 | ';'.(is_null($crit) ? '' : $crit). |
2137 | ';'.(is_null($crit) ? '' : $crit). |
2110 | ';'.(is_null($min) ? '' : $min). |
2138 | ';'.(is_null($min) ? '' : $min). |
2111 | ';'.(is_null($max) ? '' : $max); |
2139 | ';'.(is_null($max) ? '' : $max); |
2112 | } |
2140 | } |
2113 | } |
2141 | } |
2114 | 2142 | ||
2115 | class VNagHelp { |
2143 | class VNagHelp { |
2116 | public $word_wrap_width = 80; // -1 = disable |
2144 | public $word_wrap_width = 80; // -1 = disable |
2117 | public $argument_indent = 7; |
2145 | public $argument_indent = 7; |
2118 | 2146 | ||
2119 | public function printUsagePage() { |
2147 | public function printUsagePage() { |
2120 | $usage = $this->getUsage(); |
2148 | $usage = $this->getUsage(); |
2121 | 2149 | ||
2122 | if (_empty($usage)) { |
2150 | if (_empty($usage)) { |
2123 | $usage = VNagLang::$no_syntax_defined; |
2151 | $usage = VNagLang::$no_syntax_defined; |
2124 | } |
2152 | } |
2125 | 2153 | ||
2126 | return trim($usage)."\n"; |
2154 | return trim($usage)."\n"; |
2127 | } |
2155 | } |
2128 | 2156 | ||
2129 | public function printVersionPage() { |
2157 | public function printVersionPage() { |
2130 | $out = trim($this->getNameAndVersion())."\n"; |
2158 | $out = trim($this->getNameAndVersion())."\n"; |
2131 | 2159 | ||
2132 | if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false); |
2160 | if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false); |
2133 | 2161 | ||
2134 | return $out; |
2162 | return $out; |
2135 | } |
2163 | } |
2136 | 2164 | ||
2137 | static private function _conditionalLine($line, $terminator='', $prefix='') { |
2165 | static private function _conditionalLine($line, $terminator='', $prefix='') { |
2138 | if (!_empty($line)) { |
2166 | if (!_empty($line)) { |
2139 | return trim($line).$terminator; |
2167 | return trim($line).$terminator; |
2140 | } |
2168 | } |
2141 | return ''; |
2169 | return ''; |
2142 | } |
2170 | } |
2143 | 2171 | ||
2144 | public function printHelpPage() { |
2172 | public function printHelpPage() { |
2145 | $out = ''; |
2173 | $out = ''; |
2146 | $out .= self::_conditionalLine($this->getNameAndVersion(), "\n"); |
2174 | $out .= self::_conditionalLine($this->getNameAndVersion(), "\n"); |
2147 | $out .= self::_conditionalLine($this->getCopyright(), "\n"); |
2175 | $out .= self::_conditionalLine($this->getCopyright(), "\n"); |
2148 | $out .= ($out != '') ? "\n" : ''; |
2176 | $out .= ($out != '') ? "\n" : ''; |
2149 | $out .= self::_conditionalLine($this->getShortDescription(), "\n\n\n"); |
2177 | $out .= self::_conditionalLine($this->getShortDescription(), "\n\n\n"); |
2150 | $out .= self::_conditionalLine($this->getUsage(), "\n\n"); |
2178 | $out .= self::_conditionalLine($this->getUsage(), "\n\n"); |
2151 | 2179 | ||
2152 | $out .= VNagLang::$options."\n"; |
2180 | $out .= VNagLang::$options."\n"; |
2153 | foreach ($this->options as $argObj) { |
2181 | foreach ($this->options as $argObj) { |
2154 | $out .= $this->printArgumentHelp($argObj); |
2182 | $out .= $this->printArgumentHelp($argObj); |
2155 | } |
2183 | } |
2156 | 2184 | ||
2157 | $out .= self::_conditionalLine($this->getFootNotes(), "\n\n", "\n"); |
2185 | $out .= self::_conditionalLine($this->getFootNotes(), "\n\n", "\n"); |
2158 | 2186 | ||
2159 | if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false); |
2187 | if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false); |
2160 | 2188 | ||
2161 | return $out; |
2189 | return $out; |
2162 | } |
2190 | } |
2163 | 2191 | ||
2164 | protected /* VNagArgument[] */ $options = array(); |
2192 | protected /* VNagArgument[] */ $options = array(); |
2165 | 2193 | ||
2166 | // Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually. |
2194 | // Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually. |
2167 | // Use VNag's function instead (since it adds to the argHandler too) |
2195 | // Use VNag's function instead (since it adds to the argHandler too) |
2168 | protected function _addOption($argObj) { |
2196 | protected function _addOption($argObj) { |
2169 | $this->options[] = $argObj; |
2197 | $this->options[] = $argObj; |
2170 | } |
2198 | } |
2171 | 2199 | ||
2172 | # FUT: Automatic creation of usage page. Which arguments are necessary? |
2200 | # FUT: Automatic creation of usage page. Which arguments are necessary? |
2173 | protected function printArgumentHelp($argObj) { |
2201 | protected function printArgumentHelp($argObj) { |
2174 | $identifiers = array(); |
2202 | $identifiers = array(); |
2175 | 2203 | ||
2176 | $shortopt = $argObj->getShortopt(); |
2204 | $shortopt = $argObj->getShortopt(); |
2177 | if (!_empty($shortopt)) $identifiers[] = '-'.$shortopt; |
2205 | if (!_empty($shortopt)) $identifiers[] = '-'.$shortopt; |
2178 | 2206 | ||
2179 | $longopts = $argObj->getLongopts(); |
2207 | $longopts = $argObj->getLongopts(); |
2180 | if (!is_null($longopts)) { |
2208 | if (!is_null($longopts)) { |
2181 | foreach ($longopts as $longopt) { |
2209 | foreach ($longopts as $longopt) { |
2182 | if (!_empty($longopt)) $identifiers[] = '--'.$longopt; |
2210 | if (!_empty($longopt)) $identifiers[] = '--'.$longopt; |
2183 | } |
2211 | } |
2184 | } |
2212 | } |
2185 | 2213 | ||
2186 | if (count($identifiers) == 0) return; |
2214 | if (count($identifiers) == 0) return; |
2187 | 2215 | ||
2188 | $valueName = $argObj->getValueName(); |
2216 | $valueName = $argObj->getValueName(); |
2189 | 2217 | ||
2190 | $arginfo = ''; |
2218 | $arginfo = ''; |
2191 | switch ($argObj->getValuePolicy()) { |
2219 | switch ($argObj->getValuePolicy()) { |
2192 | case VNagArgument::VALUE_FORBIDDEN: |
2220 | case VNagArgument::VALUE_FORBIDDEN: |
2193 | $arginfo = ''; |
2221 | $arginfo = ''; |
2194 | break; |
2222 | break; |
2195 | case VNagArgument::VALUE_REQUIRED: |
2223 | case VNagArgument::VALUE_REQUIRED: |
2196 | $arginfo = '='.$valueName; |
2224 | $arginfo = '='.$valueName; |
2197 | break; |
2225 | break; |
2198 | case VNagArgument::VALUE_OPTIONAL: |
2226 | case VNagArgument::VALUE_OPTIONAL: |
2199 | $arginfo = '[='.$valueName.']'; |
2227 | $arginfo = '[='.$valueName.']'; |
2200 | break; |
2228 | break; |
2201 | } |
2229 | } |
2202 | 2230 | ||
2203 | $out = ''; |
2231 | $out = ''; |
2204 | $out .= implode(', ', $identifiers).$arginfo."\n"; |
2232 | $out .= implode(', ', $identifiers).$arginfo."\n"; |
2205 | 2233 | ||
2206 | // https://nagios-plugins.org/doc/guidelines.html#AEN302 recommends supporting a 80x23 screen resolution. |
2234 | // https://nagios-plugins.org/doc/guidelines.html#AEN302 recommends supporting a 80x23 screen resolution. |
2207 | // While we cannot guarantee the vertical height, we can limit the width at least... |
2235 | // While we cannot guarantee the vertical height, we can limit the width at least... |
2208 | 2236 | ||
2209 | $content = trim($argObj->getHelpText()); |
2237 | $content = trim($argObj->getHelpText()); |
2210 | if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width-$this->argument_indent, "\n", false); |
2238 | if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width-$this->argument_indent, "\n", false); |
2211 | $lines = explode("\n", $content); |
2239 | $lines = explode("\n", $content); |
2212 | 2240 | ||
2213 | foreach ($lines as $line) { |
2241 | foreach ($lines as $line) { |
2214 | $out .= str_repeat(' ', $this->argument_indent).$line."\n"; |
2242 | $out .= str_repeat(' ', $this->argument_indent).$line."\n"; |
2215 | } |
2243 | } |
2216 | $out .= "\n"; |
2244 | $out .= "\n"; |
2217 | 2245 | ||
2218 | return $out; |
2246 | return $out; |
2219 | } |
2247 | } |
2220 | 2248 | ||
2221 | // $pluginName should contain the name of the plugin, without version. |
2249 | // $pluginName should contain the name of the plugin, without version. |
2222 | protected $pluginName; |
2250 | protected $pluginName; |
2223 | public function setPluginName($pluginName) { |
2251 | public function setPluginName($pluginName) { |
2224 | $this->pluginName = $this->replaceStuff($pluginName); |
2252 | $this->pluginName = $this->replaceStuff($pluginName); |
2225 | } |
2253 | } |
2226 | public function getPluginName() { |
2254 | public function getPluginName() { |
2227 | if (_empty($this->pluginName)) { |
2255 | if (_empty($this->pluginName)) { |
2228 | global $argv; |
2256 | global $argv; |
2229 | return basename($argv[0]); |
2257 | return basename($argv[0]); |
2230 | } else { |
2258 | } else { |
2231 | return $this->pluginName; |
2259 | return $this->pluginName; |
2232 | } |
2260 | } |
2233 | } |
2261 | } |
2234 | 2262 | ||
2235 | private static function isCertified($file) { |
2263 | private static function isCertified($file) { |
2236 | $cont = file_get_contents($file); |
2264 | $cont = file_get_contents($file); |
2237 | 2265 | ||
2238 | $regex = '@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU'; |
2266 | $regex = '@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU'; |
2239 | 2267 | ||
2240 | $m = array(); |
2268 | $m = array(); |
2241 | if (!preg_match($regex, $cont, $m)) { |
2269 | if (!preg_match($regex, $cont, $m)) { |
2242 | return false; |
2270 | return false; |
2243 | } |
2271 | } |
2244 | $signature = base64_decode($m[1]); |
2272 | $signature = base64_decode($m[1]); |
2245 | 2273 | ||
2246 | $naked = preg_replace($regex, '', $cont); |
2274 | $naked = preg_replace($regex, '', $cont); |
2247 | $hash = hash("sha256", $naked.basename($file)); |
2275 | $hash = hash("sha256", $naked.basename($file)); |
2248 | 2276 | ||
2249 | $public_key = <<<'VTSKEY' |
2277 | $public_key = <<<'VTSKEY' |
2250 | -----BEGIN PUBLIC KEY----- |
2278 | -----BEGIN PUBLIC KEY----- |
2251 | MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA4UEmad2KHWzfGLcAzbOD |
2279 | MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA4UEmad2KHWzfGLcAzbOD |
2252 | IhqWyoPA1Cg4zN5YK/CWUiE7sh2CNinIwYqGnIOhZLp54/Iyv3H05QeWJU7kD+jQ |
2280 | IhqWyoPA1Cg4zN5YK/CWUiE7sh2CNinIwYqGnIOhZLp54/Iyv3H05QeWJU7kD+jQ |
2253 | 5JwR8+pqk8ZGBfqlxXUBJ2bZhYIBJZYfilSROa7jgPPrrw0CjdGLmM3wmc8ztQRv |
2281 | 5JwR8+pqk8ZGBfqlxXUBJ2bZhYIBJZYfilSROa7jgPPrrw0CjdGLmM3wmc8ztQRv |
2254 | 4GpP7MaKVyVOsRz5xEcpzghWZ+Cl8Nxq1Vo02RkMYOOPA16abxZ65lVM8Vv2EKGf |
2282 | 4GpP7MaKVyVOsRz5xEcpzghWZ+Cl8Nxq1Vo02RkMYOOPA16abxZ65lVM8Vv2EKGf |
2255 | /VAVViTFvLWPxggvt1fbJJniC0cwt8gjzFXt6IJJSRlqc1lOO9ZIa/EWDKuHKQ1n |
2283 | /VAVViTFvLWPxggvt1fbJJniC0cwt8gjzFXt6IJJSRlqc1lOO9ZIa/EWDKuHKQ1n |
2256 | ENQCqnuVPFDZU3lU20Z+6+EA0YngcvNYi3ucdIvgBd4Yv5FetzuxiOZUoDRfh/3R |
2284 | ENQCqnuVPFDZU3lU20Z+6+EA0YngcvNYi3ucdIvgBd4Yv5FetzuxiOZUoDRfh/3R |
2257 | 6dCJ8CvRiq0BSZcynTIWNmF3AVsH7vjxZe8kMDbwZNnR0suZ5MfBh6L/s1lCEWlS |
2285 | 6dCJ8CvRiq0BSZcynTIWNmF3AVsH7vjxZe8kMDbwZNnR0suZ5MfBh6L/s1lCEWlS |
2258 | GwmCLc3MnOLxq3JLnfmbVa509YxlUamdSswnvzes28AjnzQ3LQchspP2a8bSXH6/ |
2286 | GwmCLc3MnOLxq3JLnfmbVa509YxlUamdSswnvzes28AjnzQ3LQchspP2a8bSXH6/ |
2259 | qpbwvmV5WiNgwJck04VhaXrRRy3XFSwuk7KU/L4aqadXP26kgDqIYNvPXSa9JyGc |
2287 | qpbwvmV5WiNgwJck04VhaXrRRy3XFSwuk7KU/L4aqadXP26kgDqIYNvPXSa9JyGc |
2260 | 14zwdmAtn36o8vpXM/A7GhdWqgPLlJbdTdK6IfwpBs8P/JB6y3t6RzAGiEOITdj9 |
2288 | 14zwdmAtn36o8vpXM/A7GhdWqgPLlJbdTdK6IfwpBs8P/JB6y3t6RzAGiEOITdj9 |
2261 | QUhW+sAoKno0j4WT7s80vWNWz37WoFJcvVLnVEYitnW6DqM+GOt2od3g6WgI6dOa |
2289 | QUhW+sAoKno0j4WT7s80vWNWz37WoFJcvVLnVEYitnW6DqM+GOt2od3g6WgI6dOa |
2262 | MESA4J44Y4x1gXBw/M6F/ZngP4EJoAUG0GbzsaZ6HKLt4pDTZmw8PnNcXrOMYkr/ |
2290 | MESA4J44Y4x1gXBw/M6F/ZngP4EJoAUG0GbzsaZ6HKLt4pDTZmw8PnNcXrOMYkr/ |
2263 | N5EliTXil45DCaLkgNJmpdXjNpIvShW4ogq2osw+SQUalnAbW8ddiaOVCdgXkDFq |
2291 | N5EliTXil45DCaLkgNJmpdXjNpIvShW4ogq2osw+SQUalnAbW8ddiaOVCdgXkDFq |
2264 | gvnl5QSeUrKPF5v+vlnwWar6Rp7iInQpnA+PTSbAlO3Dd9WqbWx+uNoI/kXUlN0O |
2292 | gvnl5QSeUrKPF5v+vlnwWar6Rp7iInQpnA+PTSbAlO3Dd9WqbWx+uNoI/kXUlN0O |
2265 | a/vi5Uwat2Bz3N+jIpnBqg4+O+SG0z3UCVmT6Leg+kqO/rXbzoVv/DV7E30vTqdo |
2293 | a/vi5Uwat2Bz3N+jIpnBqg4+O+SG0z3UCVmT6Leg+kqO/rXbzoVv/DV7E30vTqdo |
2266 | wsswdJEM1BI7Wyid6HPwBek+rdv77gUg3W37vUcdfKxsYRcoHriXLHpmENznJcEx |
2294 | wsswdJEM1BI7Wyid6HPwBek+rdv77gUg3W37vUcdfKxsYRcoHriXLHpmENznJcEx |
2267 | /nvilw6To1zx2LKmM/p56MQriKkXnqoOBpkpn3PaWyXZKY9xJNTAbcSP3haE7z9p |
2295 | /nvilw6To1zx2LKmM/p56MQriKkXnqoOBpkpn3PaWyXZKY9xJNTAbcSP3haE7z9p |
2268 | PzJw88KI8dnYuFg4yS/AgmVGAUtu3bhDG4qF9URu2ck868zViH996lraYkmFIWJG |
2296 | PzJw88KI8dnYuFg4yS/AgmVGAUtu3bhDG4qF9URu2ck868zViH996lraYkmFIWJG |
2269 | r7h1LImhrwDEJvb/rOW8QvOZBX9H6pcSKs/LQbeoy6HMIOTlny+S15xtiS4t6Ayv |
2297 | r7h1LImhrwDEJvb/rOW8QvOZBX9H6pcSKs/LQbeoy6HMIOTlny+S15xtiS4t6Ayv |
2270 | 3m0ry5c0qkl/mgKvGpeRnNlrcr6mb2fzxxGvcuBzi25wgIbRLPgJoqsmeBvW1OLU |
2298 | 3m0ry5c0qkl/mgKvGpeRnNlrcr6mb2fzxxGvcuBzi25wgIbRLPgJoqsmeBvW1OLU |
2271 | +9DpkNvitEJnPRo86v0VF86aou12Sm8Wb4mtrQ7h3qLIYvw2LN2mYh4WlgrSwPpx |
2299 | +9DpkNvitEJnPRo86v0VF86aou12Sm8Wb4mtrQ7h3qLIYvw2LN2mYh4WlgrSwPpx |
2272 | YvE2+vWapilnnDWoiu2ZmDWa7WW/ihqvX9fmp/qzxQvJmBYIN8dFpgcNLqSx526N |
2300 | YvE2+vWapilnnDWoiu2ZmDWa7WW/ihqvX9fmp/qzxQvJmBYIN8dFpgcNLqSx526N |
2273 | bwIDAQAB |
2301 | bwIDAQAB |
2274 | -----END PUBLIC KEY----- |
2302 | -----END PUBLIC KEY----- |
2275 | VTSKEY; |
2303 | VTSKEY; |
2276 | 2304 | ||
2277 | if (!function_exists('openssl_verify')) return null; |
2305 | if (!function_exists('openssl_verify')) return null; |
2278 | 2306 | ||
2279 | if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) { |
2307 | if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) { |
2280 | return false; |
2308 | return false; |
2281 | } |
2309 | } |
2282 | 2310 | ||
2283 | return true; |
2311 | return true; |
2284 | } |
2312 | } |
2285 | 2313 | ||
2286 | // $version should contain the version, not the program name or copyright. |
2314 | // $version should contain the version, not the program name or copyright. |
2287 | protected $version; |
2315 | protected $version; |
2288 | public function setVersion($version) { |
2316 | public function setVersion($version) { |
2289 | $this->version = $this->replaceStuff($version); |
2317 | $this->version = $this->replaceStuff($version); |
2290 | } |
2318 | } |
2291 | public function getVersion() { |
2319 | public function getVersion() { |
2292 | return $this->version; |
2320 | return $this->version; |
2293 | } |
2321 | } |
2294 | public function getNameAndVersion() { |
2322 | public function getNameAndVersion() { |
2295 | $ret = $this->getPluginName(); |
2323 | $ret = $this->getPluginName(); |
2296 | if (_empty($ret)) return null; |
2324 | if (_empty($ret)) return null; |
2297 | 2325 | ||
2298 | $ver = $this->getVersion(); |
2326 | $ver = $this->getVersion(); |
2299 | if (!_empty($ver)) { |
2327 | if (!_empty($ver)) { |
2300 | $ret = sprintf(VNagLang::$x_version_x, $ret, $ver); |
2328 | $ret = sprintf(VNagLang::$x_version_x, $ret, $ver); |
2301 | } |
2329 | } |
2302 | $ret = trim($ret); |
2330 | $ret = trim($ret); |
2303 | 2331 | ||
2304 | $certified = true; |
2332 | $certified = true; |
2305 | foreach (get_included_files() as $file) { |
2333 | foreach (get_included_files() as $file) { |
2306 | $certified &= self::isCertified($file); |
2334 | $certified &= self::isCertified($file); |
2307 | } |
2335 | } |
2308 | if ($certified) { |
2336 | if ($certified) { |
2309 | $ret .= ' (' . VNagLang::$certified . ')'; |
2337 | $ret .= ' (' . VNagLang::$certified . ')'; |
2310 | } |
2338 | } |
2311 | 2339 | ||
2312 | return $ret; |
2340 | return $ret; |
2313 | } |
2341 | } |
2314 | 2342 | ||
2315 | // $copyright should contain the copyright only, no program name or version. |
2343 | // $copyright should contain the copyright only, no program name or version. |
2316 | // $CURYEAR$ will be replaced by the current year |
2344 | // $CURYEAR$ will be replaced by the current year |
2317 | protected $copyright; |
2345 | protected $copyright; |
2318 | public function setCopyright($copyright) { |
2346 | public function setCopyright($copyright) { |
2319 | $this->copyright = $this->replaceStuff($copyright); |
2347 | $this->copyright = $this->replaceStuff($copyright); |
2320 | } |
2348 | } |
2321 | 2349 | ||
2322 | private function getVNagCopyright() { |
2350 | private function getVNagCopyright() { |
2323 | if (VNag::is_http_mode()) { |
2351 | if (VNag::is_http_mode()) { |
2324 | $vts_email = 'www.viathinksoft.com'; // don't publish email address at web services because of spam bots |
2352 | $vts_email = 'www.viathinksoft.com'; // don't publish email address at web services because of spam bots |
2325 | } else { |
2353 | } else { |
2326 | $vts_email = base64_decode('aW5mb0B2aWF0aGlua3NvZnQuZGU='); // protect email address from spambots which might parse this code |
2354 | $vts_email = base64_decode('aW5mb0B2aWF0aGlua3NvZnQuZGU='); // protect email address from spambots which might parse this code |
2327 | } |
2355 | } |
2328 | return "VNag Framework ".VNag::VNAG_VERSION." (C) 2014-".date('Y')." ViaThinkSoft <$vts_email>"; |
2356 | return "VNag Framework ".VNag::VNAG_VERSION." (C) 2014-".date('Y')." ViaThinkSoft <$vts_email>"; |
2329 | } |
2357 | } |
2330 | 2358 | ||
2331 | public function getCopyright() { |
2359 | public function getCopyright() { |
2332 | if (_empty($this->copyright)) { |
2360 | if (_empty($this->copyright)) { |
2333 | return sprintf(VNagLang::$plugin_uses, $this->getVNagCopyright()); |
2361 | return sprintf(VNagLang::$plugin_uses, $this->getVNagCopyright()); |
2334 | } else { |
2362 | } else { |
2335 | return trim($this->copyright)."\n".sprintf(VNagLang::$uses, $this->getVNagCopyright()); |
2363 | return trim($this->copyright)."\n".sprintf(VNagLang::$uses, $this->getVNagCopyright()); |
2336 | } |
2364 | } |
2337 | } |
2365 | } |
2338 | 2366 | ||
2339 | // $shortDescription should describe what this plugin does. |
2367 | // $shortDescription should describe what this plugin does. |
2340 | protected $shortDescription; |
2368 | protected $shortDescription; |
2341 | public function setShortDescription($shortDescription) { |
2369 | public function setShortDescription($shortDescription) { |
2342 | $this->shortDescription = $this->replaceStuff($shortDescription); |
2370 | $this->shortDescription = $this->replaceStuff($shortDescription); |
2343 | } |
2371 | } |
2344 | public function getShortDescription() { |
2372 | public function getShortDescription() { |
2345 | if (_empty($this->shortDescription)) { |
2373 | if (_empty($this->shortDescription)) { |
2346 | return null; |
2374 | return null; |
2347 | } else { |
2375 | } else { |
2348 | $content = $this->shortDescription; |
2376 | $content = $this->shortDescription; |
2349 | if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width, "\n", false); |
2377 | if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width, "\n", false); |
2350 | return $content; |
2378 | return $content; |
2351 | } |
2379 | } |
2352 | } |
2380 | } |
2353 | 2381 | ||
2354 | protected function replaceStuff($text) { |
2382 | protected function replaceStuff($text) { |
2355 | global $argv; |
2383 | global $argv; |
2356 | $text = str_replace('$SCRIPTNAME$', $argv[0], $text); |
2384 | $text = str_replace('$SCRIPTNAME$', $argv[0], $text); |
2357 | $text = str_replace('$CURYEAR$', date('Y'), $text); |
2385 | $text = str_replace('$CURYEAR$', date('Y'), $text); |
2358 | return $text; |
2386 | return $text; |
2359 | } |
2387 | } |
2360 | 2388 | ||
2361 | // $syntax should contain the option syntax only, no explanations. |
2389 | // $syntax should contain the option syntax only, no explanations. |
2362 | // $SCRIPTNAME$ will be replaced by the actual script name |
2390 | // $SCRIPTNAME$ will be replaced by the actual script name |
2363 | // $CURYEAR$ will be replaced by the current year |
2391 | // $CURYEAR$ will be replaced by the current year |
2364 | # FUT: Automatically generate syntax? |
2392 | # FUT: Automatically generate syntax? |
2365 | protected $syntax; |
2393 | protected $syntax; |
2366 | public function setSyntax($syntax) { |
2394 | public function setSyntax($syntax) { |
2367 | $syntax = $this->replaceStuff($syntax); |
2395 | $syntax = $this->replaceStuff($syntax); |
2368 | $this->syntax = $syntax; |
2396 | $this->syntax = $syntax; |
2369 | } |
2397 | } |
2370 | public function getUsage() { |
2398 | public function getUsage() { |
2371 | if (_empty($this->syntax)) { |
2399 | if (_empty($this->syntax)) { |
2372 | return null; |
2400 | return null; |
2373 | } else { |
2401 | } else { |
2374 | return sprintf(VNagLang::$usage_x, $this->syntax); |
2402 | return sprintf(VNagLang::$usage_x, $this->syntax); |
2375 | } |
2403 | } |
2376 | } |
2404 | } |
2377 | 2405 | ||
2378 | // $footNotes can be contact information or other notes which should appear in --help |
2406 | // $footNotes can be contact information or other notes which should appear in --help |
2379 | protected $footNotes; |
2407 | protected $footNotes; |
2380 | public function setFootNotes($footNotes) { |
2408 | public function setFootNotes($footNotes) { |
2381 | $this->footNotes = $this->replaceStuff($footNotes); |
2409 | $this->footNotes = $this->replaceStuff($footNotes); |
2382 | } |
2410 | } |
2383 | public function getFootNotes() { |
2411 | public function getFootNotes() { |
2384 | return $this->footNotes; |
2412 | return $this->footNotes; |
2385 | } |
2413 | } |
2386 | } |
2414 | } |
2387 | 2415 | ||
2388 | class VNagLang { |
2416 | class VNagLang { |
2389 | public static function status($code, $statusmodel) { |
2417 | public static function status($code, $statusmodel) { |
2390 | switch ($statusmodel) { |
2418 | switch ($statusmodel) { |
2391 | case VNag::STATUSMODEL_SERVICE: |
2419 | case VNag::STATUSMODEL_SERVICE: |
2392 | switch ($code) { |
2420 | switch ($code) { |
2393 | case VNag::STATUS_OK: |
2421 | case VNag::STATUS_OK: |
2394 | return 'OK'; |
2422 | return 'OK'; |
2395 | #break; |
2423 | #break; |
2396 | case VNag::STATUS_WARNING: |
2424 | case VNag::STATUS_WARNING: |
2397 | return 'Warning'; |
2425 | return 'Warning'; |
2398 | #break; |
2426 | #break; |
2399 | case VNag::STATUS_CRITICAL: |
2427 | case VNag::STATUS_CRITICAL: |
2400 | return 'Critical'; |
2428 | return 'Critical'; |
2401 | #break; |
2429 | #break; |
2402 | case VNag::STATUS_UNKNOWN: |
2430 | case VNag::STATUS_UNKNOWN: |
2403 | return 'Unknown'; |
2431 | return 'Unknown'; |
2404 | #break; |
2432 | #break; |
2405 | default: |
2433 | default: |
2406 | return sprintf('Error (%d)', $code); |
2434 | return sprintf('Error (%d)', $code); |
2407 | #break; |
2435 | #break; |
2408 | } |
2436 | } |
2409 | #break; |
2437 | #break; |
2410 | case VNag::STATUSMODEL_HOST: |
2438 | case VNag::STATUSMODEL_HOST: |
2411 | switch ($code) { |
2439 | switch ($code) { |
2412 | case VNag::STATUS_UP: |
2440 | case VNag::STATUS_UP: |
2413 | return 'Up'; |
2441 | return 'Up'; |
2414 | #break; |
2442 | #break; |
2415 | case VNag::STATUS_DOWN: |
2443 | case VNag::STATUS_DOWN: |
2416 | return 'Down'; |
2444 | return 'Down'; |
2417 | #break; |
2445 | #break; |
2418 | default: |
2446 | default: |
2419 | return sprintf('Maintain last state (%d)', $code); |
2447 | return sprintf('Maintain last state (%d)', $code); |
2420 | #break; |
2448 | #break; |
2421 | } |
2449 | } |
2422 | #break; |
2450 | #break; |
2423 | default: |
2451 | default: |
2424 | throw new VNagIllegalStatusModel(sprintf(self::$illegal_statusmodel, $statusmodel)); |
2452 | throw new VNagIllegalStatusModel(sprintf(self::$illegal_statusmodel, $statusmodel)); |
2425 | #break; |
2453 | #break; |
2426 | } |
2454 | } |
2427 | } |
2455 | } |
2428 | 2456 | ||
2429 | static $nagios_output = 'VNag-Output'; |
2457 | static $nagios_output = 'VNag-Output'; |
2430 | static $verbose_info = 'Verbose information'; |
2458 | static $verbose_info = 'Verbose information'; |
2431 | static $status = 'Status'; |
2459 | static $status = 'Status'; |
2432 | static $message = 'Message'; |
2460 | static $message = 'Message'; |
2433 | static $performance_data = 'Performance data'; |
2461 | static $performance_data = 'Performance data'; |
2434 | static $status_ok = 'OK'; |
2462 | static $status_ok = 'OK'; |
2435 | static $status_warn = 'Warning'; |
2463 | static $status_warn = 'Warning'; |
2436 | static $status_critical = 'Critical'; |
2464 | static $status_critical = 'Critical'; |
2437 | static $status_unknown = 'Unknown'; |
2465 | static $status_unknown = 'Unknown'; |
2438 | static $status_error = 'Error'; |
2466 | static $status_error = 'Error'; |
2439 | static $unhandled_exception_without_msg = "Unhandled exception of type %s"; |
2467 | static $unhandled_exception_without_msg = "Unhandled exception of type %s"; |
2440 | static $plugin_uses = 'This plugin uses %s'; |
2468 | static $plugin_uses = 'This plugin uses %s'; |
2441 | static $uses = 'uses %s'; |
2469 | static $uses = 'uses %s'; |
2442 | static $x_version_x = '%s, version %s'; |
2470 | static $x_version_x = '%s, version %s'; |
2443 | 2471 | ||
2444 | // Argument names (help page) |
2472 | // Argument names (help page) |
2445 | static $argname_value = 'value'; |
2473 | static $argname_value = 'value'; |
2446 | static $argname_seconds = 'seconds'; |
2474 | static $argname_seconds = 'seconds'; |
2447 | static $certified = 'Certified by ViaThinkSoft'; |
2475 | static $certified = 'Certified by ViaThinkSoft'; |
2448 | 2476 | ||
2449 | // Exceptions |
2477 | // Exceptions |
2450 | static $query_without_expected_argument = "The argument '%s' is queried, but was not added to the list of expected arguments. Please contact the plugin author."; |
2478 | static $query_without_expected_argument = "The argument '%s' is queried, but was not added to the list of expected arguments. Please contact the plugin author."; |
2451 | static $required_argument_missing = "The argument '%s' is required."; |
2479 | static $required_argument_missing = "The argument '%s' is required."; |
2452 | static $performance_data_invalid = 'Performance data invalid.'; |
2480 | static $performance_data_invalid = 'Performance data invalid.'; |
2453 | static $no_standard_arguments_with_letter = "No standard argument with letter '%s' exists."; |
2481 | static $no_standard_arguments_with_letter = "No standard argument with letter '%s' exists."; |
2454 | static $invalid_start_value = 'Invalid start value.'; |
2482 | static $invalid_start_value = 'Invalid start value.'; |
2455 | static $invalid_end_value = 'Invalid end value.'; |
2483 | static $invalid_end_value = 'Invalid end value.'; |
2456 | static $start_is_greater_than_end = 'Start is greater than end value.'; |
2484 | static $start_is_greater_than_end = 'Start is greater than end value.'; |
2457 | static $value_name_forbidden = "Implementation error: You may not define a value name for the argument, because the value policy is VALUE_FORBIDDEN."; |
2485 | static $value_name_forbidden = "Implementation error: You may not define a value name for the argument, because the value policy is VALUE_FORBIDDEN."; |
2458 | static $value_name_required = "Implementation error: Please define a name for the argument (so it can be shown in the help page)."; |
2486 | static $value_name_required = "Implementation error: Please define a name for the argument (so it can be shown in the help page)."; |
2459 | static $illegal_shortopt = "Illegal shortopt '-%s'."; |
2487 | static $illegal_shortopt = "Illegal shortopt '-%s'."; |
2460 | static $illegal_longopt = "Illegal longopt '--%s'."; |
2488 | static $illegal_longopt = "Illegal longopt '--%s'."; |
2461 | static $illegal_valuepolicy = "valuePolicy has illegal value '%s'."; |
2489 | static $illegal_valuepolicy = "valuePolicy has illegal value '%s'."; |
2462 | static $range_invalid_syntax = "Syntax error in range '%s'."; |
2490 | static $range_invalid_syntax = "Syntax error in range '%s'."; |
2463 | static $timeout_value_invalid = "Timeout value '%s' is invalid."; |
2491 | static $timeout_value_invalid = "Timeout value '%s' is invalid."; |
2464 | static $range_is_invalid = 'Range is invalid.'; |
2492 | static $range_is_invalid = 'Range is invalid.'; |
2465 | static $timeout_exception = 'Timeout!'; |
2493 | static $timeout_exception = 'Timeout!'; |
2466 | static $perfdata_label_equal_sign_forbidden = 'Label may not contain an equal sign.'; |
2494 | static $perfdata_label_equal_sign_forbidden = 'Label may not contain an equal sign.'; |
2467 | static $perfdata_value_must_be_in_class = 'Value must be in class [-0-9.] or be \'U\' if the actual value can\'t be determined.'; |
2495 | static $perfdata_value_must_be_in_class = 'Value must be in class [-0-9.] or be \'U\' if the actual value can\'t be determined.'; |
2468 | static $perfdata_min_must_be_in_class = 'Min must be in class [-0-9.] or empty.'; |
2496 | static $perfdata_min_must_be_in_class = 'Min must be in class [-0-9.] or empty.'; |
2469 | static $perfdata_max_must_be_in_class = 'Max must be in class [-0-9.] or empty.'; |
2497 | static $perfdata_max_must_be_in_class = 'Max must be in class [-0-9.] or empty.'; |
2470 | static $perfdata_uom_not_recognized = 'UOM (unit of measurement) "%s" is not recognized.'; |
2498 | static $perfdata_uom_not_recognized = 'UOM (unit of measurement) "%s" is not recognized.'; |
2471 | static $perfdata_mixed_uom_not_implemented = 'Mixed UOMs (%s and %s) are currently not supported.'; |
2499 | static $perfdata_mixed_uom_not_implemented = 'Mixed UOMs (%s and %s) are currently not supported.'; |
2472 | static $no_compatible_range_uom_found = 'Measured values are not compatible with the provided warning/critical parameter. Most likely, the UOM is incompatible.'; |
2500 | static $no_compatible_range_uom_found = 'Measured values are not compatible with the provided warning/critical parameter. Most likely, the UOM is incompatible.'; |
2473 | static $exception_x = '%s (%s)'; |
2501 | static $exception_x = '%s (%s)'; |
2474 | static $no_syntax_defined = 'The author of this plugin has not defined a syntax for this plugin.'; |
2502 | static $no_syntax_defined = 'The author of this plugin has not defined a syntax for this plugin.'; |
2475 | static $usage_x = "Usage:\n%s"; |
2503 | static $usage_x = "Usage:\n%s"; |
2476 | static $options = "Options:"; |
2504 | static $options = "Options:"; |
2477 | static $illegal_statusmodel = "Invalid statusmodel %d."; |
2505 | static $illegal_statusmodel = "Invalid statusmodel %d."; |
2478 | static $none = '[none]'; |
2506 | static $none = '[none]'; |
2479 | static $valueUomPairSyntaxError = 'Syntax error at "%s". Syntax must be Value[UOM].'; |
2507 | static $valueUomPairSyntaxError = 'Syntax error at "%s". Syntax must be Value[UOM].'; |
2480 | static $too_few_warning_ranges = "You have too few warning ranges (currently trying to get element %d)."; |
2508 | static $too_few_warning_ranges = "You have too few warning ranges (currently trying to get element %d)."; |
2481 | static $too_few_critical_ranges = "You have too few critical ranges (currently trying to get element %d)."; |
2509 | static $too_few_critical_ranges = "You have too few critical ranges (currently trying to get element %d)."; |
2482 | static $dataset_missing = 'Dataset missing.'; |
2510 | static $dataset_missing = 'Dataset missing.'; |
2483 | static $payload_not_base64 = 'The payload is not valid Base64.'; |
2511 | static $payload_not_base64 = 'The payload is not valid Base64.'; |
2484 | static $payload_not_json = 'The payload is not valid JSON.'; |
2512 | static $payload_not_json = 'The payload is not valid JSON.'; |
2485 | static $signature_missing = 'The signature is missing.'; |
2513 | static $signature_missing = 'The signature is missing.'; |
2486 | static $signature_not_bas64 = 'The signature is not valid Base64.'; |
2514 | static $signature_not_bas64 = 'The signature is not valid Base64.'; |
2487 | static $signature_invalid = 'The signature is invalid. The connection might have been tampered, or a different key is used.'; |
2515 | static $signature_invalid = 'The signature is invalid. The connection might have been tampered, or a different key is used.'; |
2488 | static $pubkey_file_not_found = "Public key file %s was not found."; |
2516 | static $pubkey_file_not_found = "Public key file %s was not found."; |
2489 | static $pubkey_file_not_readable = "Public key file %s is not readable."; |
2517 | static $pubkey_file_not_readable = "Public key file %s is not readable."; |
2490 | static $privkey_file_not_found = "Private key file %s was not found."; |
2518 | static $privkey_file_not_found = "Private key file %s was not found."; |
2491 | static $privkey_not_readable = "Private key is not readable."; |
2519 | static $privkey_not_readable = "Private key is not readable."; |
2492 | static $privkey_file_not_readable = "Private key file %s is not readable."; |
2520 | static $privkey_file_not_readable = "Private key file %s is not readable."; |
2493 | static $signature_failed = "Signature failed."; |
2521 | static $signature_failed = "Signature failed."; |
2494 | static $perfdata_line_invalid = "Performance data line %s is invalid."; |
2522 | static $perfdata_line_invalid = "Performance data line %s is invalid."; |
2495 | static $singlevalue_unexpected_at_symbol = 'This plugin does not allow the @-symbol at ranges for single values.'; |
2523 | static $singlevalue_unexpected_at_symbol = 'This plugin does not allow the @-symbol at ranges for single values.'; |
2496 | static $illegalSingleValueBehavior = "Illegal value for 'singleValueBehavior'. Please contact the creator of the plugin."; |
2524 | static $illegalSingleValueBehavior = "Illegal value for 'singleValueBehavior'. Please contact the creator of the plugin."; |
2497 | static $dataset_encryption_no_array = 'Dataset encryption information invalid.'; |
2525 | static $dataset_encryption_no_array = 'Dataset encryption information invalid.'; |
2498 | static $require_password = 'This resource is protected with a password. Please provide a password.'; |
2526 | static $require_password = 'This resource is protected with a password. Please provide a password.'; |
2499 | static $wrong_password = 'This resource is protected with a password. You have provided the wrong password, or it was changed.'; |
2527 | static $wrong_password = 'This resource is protected with a password. You have provided the wrong password, or it was changed.'; |
2500 | static $convert_x_y_error = 'Cannot convert from UOM %s to UOM %s.'; |
2528 | static $convert_x_y_error = 'Cannot convert from UOM %s to UOM %s.'; |
2501 | static $php_error = 'PHP has detected an error in the plugin. Please contact the plugin author.'; |
2529 | static $php_error = 'PHP has detected an error in the plugin. Please contact the plugin author.'; |
2502 | static $output_level_lowered = "Output Buffer level lowered during cbRun(). Please contact the plugin author."; |
2530 | static $output_level_lowered = "Output Buffer level lowered during cbRun(). Please contact the plugin author."; |
2503 | static $openssl_missing = "OpenSSL is missing. Therefore, encryption and signatures are not available."; |
2531 | static $openssl_missing = "OpenSSL is missing. Therefore, encryption and signatures are not available."; |
2504 | 2532 | ||
2505 | // Help texts |
2533 | // Help texts |
2506 | static $warning_range = 'Warning range'; |
2534 | static $warning_range = 'Warning range'; |
2507 | static $critical_range = 'Critical range'; |
2535 | static $critical_range = 'Critical range'; |
2508 | static $prints_version = 'Prints version'; |
2536 | static $prints_version = 'Prints version'; |
2509 | static $verbosity_helptext = 'Verbosity -v, -vv or -vvv'; |
2537 | static $verbosity_helptext = 'Verbosity -v, -vv or -vvv'; |
2510 | static $timeout_helptext = 'Sets timeout in seconds'; |
2538 | static $timeout_helptext = 'Sets timeout in seconds'; |
2511 | static $help_helptext = 'Prints help page'; |
2539 | static $help_helptext = 'Prints help page'; |
2512 | static $prints_usage = 'Prints usage'; |
2540 | static $prints_usage = 'Prints usage'; |
2513 | 2541 | ||
2514 | static $notConstructed = 'Parent constructor not called with parent::__construct().'; |
2542 | static $notConstructed = 'Parent constructor not called with parent::__construct().'; |
2515 | } |
2543 | } |
2516 | 2544 | ||
2517 | function vnagErrorHandler($errorkind, $errortext, $file, $line) { |
2545 | function vnagErrorHandler($errorkind, $errortext, $file, $line) { |
2518 | // This function "converts" PHP runtime errors into Exceptions, which can then be handled by VNag::handleException() |
2546 | // This function "converts" PHP runtime errors into Exceptions, which can then be handled by VNag::handleException() |
2519 | global $inside_vnag_run; |
2547 | global $inside_vnag_run; |
2520 | 2548 | ||
2521 | if (!$inside_vnag_run && VNag::is_http_mode()) { |
2549 | if (!$inside_vnag_run && VNag::is_http_mode()) { |
2522 | // We want to avoid that the VNag-Exception will show up in a website that contains |
2550 | // We want to avoid that the VNag-Exception will show up in a website that contains |
2523 | // an embedded VNag monitor, so if we are not inside a running VNag code, |
2551 | // an embedded VNag monitor, so if we are not inside a running VNag code, |
2524 | // we will call the normal PHP error handler. |
2552 | // we will call the normal PHP error handler. |
2525 | return false; |
2553 | return false; |
2526 | } |
2554 | } |
2527 | 2555 | ||
2528 | if (!(error_reporting() & $errorkind)) { |
2556 | if (!(error_reporting() & $errorkind)) { |
2529 | // Code is not included in error_reporting. Don't do anything. |
2557 | // Code is not included in error_reporting. Don't do anything. |
2530 | return true; |
2558 | return true; |
2531 | } |
2559 | } |
2532 | 2560 | ||
2533 | // We want 100% clean scripts, so any error, warning or notice will shutdown the script |
2561 | // We want 100% clean scripts, so any error, warning or notice will shutdown the script |
2534 | // This also fixes the issue that PHP will end with result code 0, showing an error. |
2562 | // This also fixes the issue that PHP will end with result code 0, showing an error. |
2535 | 2563 | ||
2536 | // Error kinds see http://php.net/manual/en/errorfunc.constants.php |
2564 | // Error kinds see http://php.net/manual/en/errorfunc.constants.php |
2537 | if (defined('E_ERROR') && ($errorkind == E_ERROR)) $errorkind = 'Error'; |
2565 | if (defined('E_ERROR') && ($errorkind == E_ERROR)) $errorkind = 'Error'; |
2538 | if (defined('E_WARNING') && ($errorkind == E_WARNING)) $errorkind = 'Warning'; |
2566 | if (defined('E_WARNING') && ($errorkind == E_WARNING)) $errorkind = 'Warning'; |
2539 | if (defined('E_PARSE') && ($errorkind == E_PARSE)) $errorkind = 'Parse'; |
2567 | if (defined('E_PARSE') && ($errorkind == E_PARSE)) $errorkind = 'Parse'; |
2540 | if (defined('E_NOTICE') && ($errorkind == E_NOTICE)) $errorkind = 'Notice'; |
2568 | if (defined('E_NOTICE') && ($errorkind == E_NOTICE)) $errorkind = 'Notice'; |
2541 | if (defined('E_CORE_ERROR') && ($errorkind == E_CORE_ERROR)) $errorkind = 'Core Error'; |
2569 | if (defined('E_CORE_ERROR') && ($errorkind == E_CORE_ERROR)) $errorkind = 'Core Error'; |
2542 | if (defined('E_CORE_WARNING') && ($errorkind == E_CORE_WARNING)) $errorkind = 'Core Warning'; |
2570 | if (defined('E_CORE_WARNING') && ($errorkind == E_CORE_WARNING)) $errorkind = 'Core Warning'; |
2543 | if (defined('E_COMPILE_ERROR') && ($errorkind == E_COMPILE_ERROR)) $errorkind = 'Compile Error'; |
2571 | if (defined('E_COMPILE_ERROR') && ($errorkind == E_COMPILE_ERROR)) $errorkind = 'Compile Error'; |
2544 | if (defined('E_COMPILE_WARNING') && ($errorkind == E_COMPILE_WARNING)) $errorkind = 'Compile Warning'; |
2572 | if (defined('E_COMPILE_WARNING') && ($errorkind == E_COMPILE_WARNING)) $errorkind = 'Compile Warning'; |
2545 | if (defined('E_USER_ERROR') && ($errorkind == E_USER_ERROR)) $errorkind = 'User Error'; |
2573 | if (defined('E_USER_ERROR') && ($errorkind == E_USER_ERROR)) $errorkind = 'User Error'; |
2546 | if (defined('E_USER_WARNING') && ($errorkind == E_USER_WARNING)) $errorkind = 'User Warning'; |
2574 | if (defined('E_USER_WARNING') && ($errorkind == E_USER_WARNING)) $errorkind = 'User Warning'; |
2547 | if (defined('E_USER_NOTICE') && ($errorkind == E_USER_NOTICE)) $errorkind = 'User Notice'; |
2575 | if (defined('E_USER_NOTICE') && ($errorkind == E_USER_NOTICE)) $errorkind = 'User Notice'; |
2548 | if (defined('E_STRICT') && ($errorkind == E_STRICT)) $errorkind = 'Strict'; |
2576 | if (defined('E_STRICT') && ($errorkind == E_STRICT)) $errorkind = 'Strict'; |
2549 | if (defined('E_RECOVERABLE_ERROR') && ($errorkind == E_RECOVERABLE_ERROR)) $errorkind = 'Recoverable Error'; |
2577 | if (defined('E_RECOVERABLE_ERROR') && ($errorkind == E_RECOVERABLE_ERROR)) $errorkind = 'Recoverable Error'; |
2550 | if (defined('E_DEPRECATED') && ($errorkind == E_DEPRECATED)) $errorkind = 'Deprecated'; |
2578 | if (defined('E_DEPRECATED') && ($errorkind == E_DEPRECATED)) $errorkind = 'Deprecated'; |
2551 | if (defined('E_USER_DEPRECATED') && ($errorkind == E_USER_DEPRECATED)) $errorkind = 'User Deprecated'; |
2579 | if (defined('E_USER_DEPRECATED') && ($errorkind == E_USER_DEPRECATED)) $errorkind = 'User Deprecated'; |
2552 | throw new VNagException(VNagLang::$php_error . " $errortext at $file:$line (kind $errorkind)"); |
2580 | throw new VNagException(VNagLang::$php_error . " $errortext at $file:$line (kind $errorkind)"); |
2553 | 2581 | ||
2554 | // true = the PHP internal error handling will NOT be called. |
2582 | // true = the PHP internal error handling will NOT be called. |
2555 | #return true; |
2583 | #return true; |
2556 | } |
2584 | } |
2557 | 2585 | ||
2558 | $inside_vnag_run = false; |
2586 | $inside_vnag_run = false; |
2559 | $old_error_handler = set_error_handler("vnagErrorHandler"); |
2587 | $old_error_handler = set_error_handler("vnagErrorHandler"); |
2560 | 2588 | ||
2561 | // === End of document === |
2589 | // === End of document === |
2562 | 2590 |