diff options
-rw-r--r-- | plugins/negate.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/plugins/negate.c b/plugins/negate.c new file mode 100644 index 0000000..b6effe3 --- /dev/null +++ b/plugins/negate.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Program: Inverting plugin wrapper for Nagios | ||
4 | * License: GPL | ||
5 | * | ||
6 | * License Information: | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * $Id$ | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | #define PROGNAME "negate" | ||
27 | #define REVISION "$Revision$" | ||
28 | #define COPYRIGHT "2002" | ||
29 | #define AUTHOR "Karl DeBisschop" | ||
30 | #define EMAIL "kdebisschop@users.sourceforge.net" | ||
31 | #define SUMMARY "Negates the status of a plugin (returns OK for CRITICAL, and vice-versa).\n" | ||
32 | |||
33 | #define OPTIONS "\ | ||
34 | \[-t timeout] <definition of wrapped plugin>" | ||
35 | |||
36 | #define LONGOPTIONS "\ | ||
37 | -t, --timeout=INTEGER\n\ | ||
38 | Terminate test if timeout limit is exceeded (default: %d)\n\ | ||
39 | [keep this less than the plugin timeout to retain CRITICAL status]\n" | ||
40 | |||
41 | #define DESCRIPTION "\ | ||
42 | This plugin is a wrapper to take the output of another plugin and invert it.\n\ | ||
43 | If the wrapped plugin returns STATE_OK, the wrapper will return STATE_CRITICAL.\n\ | ||
44 | If the wrapped plugin returns STATE_CRITICAL, the wrapper will return STATE_OK.\n\ | ||
45 | Otherwise, the output state of the wrapped plugin is unchanged.\n" | ||
46 | |||
47 | #define DEFAULT_TIMEOUT 9 | ||
48 | |||
49 | #include "common.h" | ||
50 | #include "utils.h" | ||
51 | #include "popen.h" | ||
52 | |||
53 | char *command_line; | ||
54 | |||
55 | static int process_arguments (int, char **); | ||
56 | static int validate_arguments (void); | ||
57 | static void print_usage (void); | ||
58 | static void print_help (void); | ||
59 | |||
60 | /****************************************************************************** | ||
61 | |||
62 | The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ | ||
63 | tags in the comments. With in the tags, the XML is assembled sequentially. | ||
64 | You can define entities in tags. You also have all the #defines available as | ||
65 | entities. | ||
66 | |||
67 | Please note that all tags must be lowercase to use the DocBook XML DTD. | ||
68 | |||
69 | @@-<article> | ||
70 | |||
71 | <sect1> | ||
72 | <title>Quick Reference</title> | ||
73 | <!-- The refentry forms a manpage --> | ||
74 | <refentry> | ||
75 | <refmeta> | ||
76 | <manvolnum>5<manvolnum> | ||
77 | </refmeta> | ||
78 | <refnamdiv> | ||
79 | <refname>&PROGNAME;</refname> | ||
80 | <refpurpose>&SUMMARY;</refpurpose> | ||
81 | </refnamdiv> | ||
82 | </refentry> | ||
83 | </sect1> | ||
84 | |||
85 | <sect1> | ||
86 | <title>FAQ</title> | ||
87 | </sect1> | ||
88 | |||
89 | <sect1> | ||
90 | <title>Theory, Installation, and Operation</title> | ||
91 | |||
92 | <sect2> | ||
93 | <title>General Description</title> | ||
94 | <para> | ||
95 | &DESCRIPTION; | ||
96 | </para> | ||
97 | </sect2> | ||
98 | |||
99 | <sect2> | ||
100 | <title>Future Enhancements</title> | ||
101 | <para>ToDo List</para> | ||
102 | <itemizedlist> | ||
103 | <listitem>Add option to do regex substitution in output text</listitem> | ||
104 | </itemizedlist> | ||
105 | </sect2> | ||
106 | |||
107 | |||
108 | <sect2> | ||
109 | <title>Functions</title> | ||
110 | -@@ | ||
111 | ******************************************************************************/ | ||
112 | |||
113 | int | ||
114 | main (int argc, char **argv) | ||
115 | { | ||
116 | int found = 0, result = STATE_UNKNOWN; | ||
117 | char input_buffer[MAX_INPUT_BUFFER]; | ||
118 | |||
119 | if (process_arguments (argc, argv) == ERROR) | ||
120 | usage ("Could not parse arguments"); | ||
121 | |||
122 | /* Set signal handling and alarm */ | ||
123 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | ||
124 | printf ("Cannot catch SIGALRM"); | ||
125 | return STATE_UNKNOWN; | ||
126 | } | ||
127 | alarm (timeout_interval); | ||
128 | |||
129 | child_process = spopen (command_line); | ||
130 | if (child_process == NULL) { | ||
131 | printf ("Could not open pipe: %s\n", command_line); | ||
132 | exit (STATE_UNKNOWN); | ||
133 | } | ||
134 | |||
135 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
136 | if (child_stderr == NULL) { | ||
137 | printf ("Could not open stderr for %s\n", command_line); | ||
138 | } | ||
139 | |||
140 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
141 | found++; | ||
142 | if (index (input_buffer, '\n')) { | ||
143 | input_buffer[strcspn (input_buffer, "\n")] = 0; | ||
144 | printf ("%s\n", input_buffer); | ||
145 | } | ||
146 | else { | ||
147 | printf ("%s\n", input_buffer); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (!found) { | ||
152 | printf ("%s problem - No data recieved from host\nCMD: %s\n", argv[0], | ||
153 | command_line); | ||
154 | exit (STATE_UNKNOWN); | ||
155 | } | ||
156 | |||
157 | /* close the pipe */ | ||
158 | result = spclose (child_process); | ||
159 | |||
160 | /* WARNING if output found on stderr */ | ||
161 | if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) | ||
162 | result = max_state (result, STATE_WARNING); | ||
163 | |||
164 | /* close stderr */ | ||
165 | (void) fclose (child_stderr); | ||
166 | |||
167 | if (result == STATE_OK) | ||
168 | return STATE_CRITICAL; | ||
169 | else if (result == STATE_CRITICAL) | ||
170 | return STATE_OK; | ||
171 | else | ||
172 | return result; | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | |||
178 | void | ||
179 | print_help (void) | ||
180 | { | ||
181 | print_revision (PROGNAME, REVISION); | ||
182 | printf | ||
183 | ("Copyright (c) %s %s <%s>\n\n%s\n", | ||
184 | COPYRIGHT, AUTHOR, EMAIL, SUMMARY); | ||
185 | print_usage (); | ||
186 | printf | ||
187 | ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", | ||
188 | DEFAULT_TIMEOUT); | ||
189 | support (); | ||
190 | } | ||
191 | |||
192 | void | ||
193 | print_usage (void) | ||
194 | { | ||
195 | printf ("Usage:\n" " %s %s\n" | ||
196 | #ifdef HAVE_GETOPT_H | ||
197 | " %s (-h | --help) for detailed help\n" | ||
198 | " %s (-V | --version) for version information\n", | ||
199 | #else | ||
200 | " %s -h for detailed help\n" | ||
201 | " %s -V for version information\n", | ||
202 | #endif | ||
203 | PROGNAME, OPTIONS, PROGNAME, PROGNAME); | ||
204 | } | ||
205 | |||
206 | |||
207 | |||
208 | /****************************************************************************** | ||
209 | @@- | ||
210 | <sect3> | ||
211 | <title>process_arguments</title> | ||
212 | |||
213 | <para>This function parses the command line into the needed | ||
214 | variables.</para> | ||
215 | |||
216 | <para>Aside from the standard 'help' and 'version' options, there | ||
217 | is a only a 'timeout' option.No validation is currently done.</para> | ||
218 | |||
219 | </sect3> | ||
220 | -@@ | ||
221 | ******************************************************************************/ | ||
222 | |||
223 | /* process command-line arguments */ | ||
224 | int | ||
225 | process_arguments (int argc, char **argv) | ||
226 | { | ||
227 | int c; | ||
228 | |||
229 | #ifdef HAVE_GETOPT_H | ||
230 | int option_index = 0; | ||
231 | static struct option long_options[] = { | ||
232 | {"help", no_argument, 0, 'h'}, | ||
233 | {"version", no_argument, 0, 'V'}, | ||
234 | {"timeout", required_argument, 0, 't'}, | ||
235 | {0, 0, 0, 0} | ||
236 | }; | ||
237 | #endif | ||
238 | |||
239 | while (1) { | ||
240 | #ifdef HAVE_GETOPT_H | ||
241 | c = getopt_long (argc, argv, "+?hVt:", | ||
242 | long_options, &option_index); | ||
243 | #else | ||
244 | c = getopt (argc, argv, "+?hVt:"); | ||
245 | #endif | ||
246 | if (c == -1 || c == EOF) | ||
247 | break; | ||
248 | |||
249 | switch (c) { | ||
250 | case '?': /* help */ | ||
251 | usage2 ("Unknown argument", optarg); | ||
252 | case 'h': /* help */ | ||
253 | print_help (); | ||
254 | exit (STATE_OK); | ||
255 | case 'V': /* version */ | ||
256 | print_revision (PROGNAME, REVISION); | ||
257 | exit (STATE_OK); | ||
258 | case 't': /* timeout period */ | ||
259 | if (!is_integer (optarg)) | ||
260 | usage2 ("Timeout Interval must be an integer", optarg); | ||
261 | timeout_interval = atoi (optarg); | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | command_line = strscpy (command_line, argv[optind]); | ||
267 | for (c = optind+1; c <= argc; c++) { | ||
268 | command_line = ssprintf (command_line, "%s %s", command_line, argv[c]); | ||
269 | } | ||
270 | |||
271 | return validate_arguments (); | ||
272 | } | ||
273 | |||
274 | |||
275 | /****************************************************************************** | ||
276 | @@- | ||
277 | <sect3> | ||
278 | <title>validate_arguments</title> | ||
279 | |||
280 | <para>No validation is currently done.</para> | ||
281 | |||
282 | </sect3> | ||
283 | -@@ | ||
284 | ******************************************************************************/ | ||
285 | |||
286 | int | ||
287 | validate_arguments () | ||
288 | { | ||
289 | return OK; | ||
290 | } | ||
291 | |||
292 | |||
293 | /****************************************************************************** | ||
294 | @@- | ||
295 | </sect2> | ||
296 | </sect1> | ||
297 | </article> | ||
298 | -@@ | ||
299 | ******************************************************************************/ | ||