diff options
Diffstat (limited to 'plugins/check_dig.c')
-rw-r--r-- | plugins/check_dig.c | 168 |
1 files changed, 69 insertions, 99 deletions
diff --git a/plugins/check_dig.c b/plugins/check_dig.c index 4394490..bc4dcd5 100644 --- a/plugins/check_dig.c +++ b/plugins/check_dig.c | |||
@@ -18,6 +18,12 @@ | |||
18 | 18 | ||
19 | *****************************************************************************/ | 19 | *****************************************************************************/ |
20 | 20 | ||
21 | /* Hackers note: | ||
22 | * There are typecasts to (char *) from _("foo bar") in this file. | ||
23 | * They prevent compiler warnings. Never (ever), permute strings obtained | ||
24 | * that are typecast from (const char *) (which happens when --disable-nls) | ||
25 | * because on some architectures those strings are in non-writable memory */ | ||
26 | |||
21 | const char *progname = "check_dig"; | 27 | const char *progname = "check_dig"; |
22 | const char *revision = "$Revision$"; | 28 | const char *revision = "$Revision$"; |
23 | const char *copyright = "2002-2004"; | 29 | const char *copyright = "2002-2004"; |
@@ -26,17 +32,15 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
26 | #include "common.h" | 32 | #include "common.h" |
27 | #include "netutils.h" | 33 | #include "netutils.h" |
28 | #include "utils.h" | 34 | #include "utils.h" |
29 | #include "popen.h" | 35 | #include "runcmd.h" |
30 | 36 | ||
31 | int process_arguments (int, char **); | 37 | int process_arguments (int, char **); |
32 | int validate_arguments (void); | 38 | int validate_arguments (void); |
33 | void print_help (void); | 39 | void print_help (void); |
34 | void print_usage (void); | 40 | void print_usage (void); |
35 | 41 | ||
36 | enum { | 42 | #define UNDEFINED 0 |
37 | UNDEFINED = 0, | 43 | #define DEFAULT_PORT 53 |
38 | DEFAULT_PORT = 53 | ||
39 | }; | ||
40 | 44 | ||
41 | char *query_address = NULL; | 45 | char *query_address = NULL; |
42 | char *record_type = "A"; | 46 | char *record_type = "A"; |
@@ -51,26 +55,25 @@ struct timeval tv; | |||
51 | int | 55 | int |
52 | main (int argc, char **argv) | 56 | main (int argc, char **argv) |
53 | { | 57 | { |
54 | char input_buffer[MAX_INPUT_BUFFER]; | ||
55 | char *command_line; | 58 | char *command_line; |
56 | char *output; | 59 | output chld_out, chld_err; |
60 | char *msg = NULL; | ||
61 | size_t i; | ||
57 | char *t; | 62 | char *t; |
58 | long microsec; | 63 | long microsec; |
59 | double elapsed_time; | 64 | double elapsed_time; |
60 | int result = STATE_UNKNOWN; | 65 | int result = STATE_UNKNOWN; |
61 | 66 | ||
62 | output = strdup (""); | ||
63 | |||
64 | setlocale (LC_ALL, ""); | 67 | setlocale (LC_ALL, ""); |
65 | bindtextdomain (PACKAGE, LOCALEDIR); | 68 | bindtextdomain (PACKAGE, LOCALEDIR); |
66 | textdomain (PACKAGE); | 69 | textdomain (PACKAGE); |
67 | 70 | ||
68 | /* Set signal handling and alarm */ | 71 | /* Set signal handling and alarm */ |
69 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) | 72 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) |
70 | usage4 (_("Cannot catch SIGALRM")); | 73 | usage_va(_("Cannot catch SIGALRM")); |
71 | 74 | ||
72 | if (process_arguments (argc, argv) == ERROR) | 75 | if (process_arguments (argc, argv) == ERROR) |
73 | usage4 (_("Could not parse arguments")); | 76 | usage_va(_("Could not parse arguments")); |
74 | 77 | ||
75 | /* get the command to run */ | 78 | /* get the command to run */ |
76 | asprintf (&command_line, "%s @%s -p %d %s -t %s", | 79 | asprintf (&command_line, "%s @%s -p %d %s -t %s", |
@@ -89,100 +92,75 @@ main (int argc, char **argv) | |||
89 | } | 92 | } |
90 | 93 | ||
91 | /* run the command */ | 94 | /* run the command */ |
92 | child_process = spopen (command_line); | 95 | if(np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) { |
93 | if (child_process == NULL) { | 96 | result = STATE_WARNING; |
94 | printf (_("Could not open pipe: %s\n"), command_line); | 97 | msg = (char *)_("dig returned an error status"); |
95 | return STATE_UNKNOWN; | ||
96 | } | 98 | } |
97 | 99 | ||
98 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | 100 | for(i = 0; i < chld_out.lines; i++) { |
99 | if (child_stderr == NULL) | ||
100 | printf (_("Could not open stderr for %s\n"), command_line); | ||
101 | |||
102 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
103 | |||
104 | /* the server is responding, we just got the host name... */ | 101 | /* the server is responding, we just got the host name... */ |
105 | if (strstr (input_buffer, ";; ANSWER SECTION:")) { | 102 | if (strstr (chld_out.line[i], ";; ANSWER SECTION:")) { |
106 | 103 | ||
107 | /* loop through the whole 'ANSWER SECTION' */ | 104 | /* loop through the whole 'ANSWER SECTION' */ |
108 | do { | 105 | for(; i < chld_out.lines; i++) { |
109 | /* get the host address */ | 106 | /* get the host address */ |
110 | if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) | 107 | if (verbose) |
111 | break; | 108 | printf ("%s\n", chld_out.line[i]); |
112 | |||
113 | if (strpbrk (input_buffer, "\r\n")) | ||
114 | input_buffer[strcspn (input_buffer, "\r\n")] = '\0'; | ||
115 | 109 | ||
116 | if (verbose && !strstr (input_buffer, ";; ")) | 110 | if (strstr (chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) { |
117 | printf ("%s\n", input_buffer); | 111 | msg = chld_out.line[i]; |
118 | |||
119 | if (expected_address==NULL && strstr (input_buffer, query_address) != NULL) { | ||
120 | output = strdup(input_buffer); | ||
121 | result = STATE_OK; | 112 | result = STATE_OK; |
122 | } | ||
123 | else if (expected_address != NULL && strstr (input_buffer, expected_address) != NULL) { | ||
124 | output = strdup(input_buffer); | ||
125 | result = STATE_OK; | ||
126 | } | ||
127 | |||
128 | /* Translate output TAB -> SPACE */ | ||
129 | t = output; | ||
130 | while ((t = index(t, '\t')) != NULL) | ||
131 | *t = ' '; | ||
132 | 113 | ||
133 | } while (!strstr (input_buffer, ";; ")); | 114 | /* Translate output TAB -> SPACE */ |
115 | t = msg; | ||
116 | while ((t = strchr(t, '\t')) != NULL) *t = ' '; | ||
117 | break; | ||
118 | } | ||
119 | } | ||
134 | 120 | ||
135 | if (result == STATE_UNKNOWN) { | 121 | if (result == STATE_UNKNOWN) { |
136 | asprintf (&output, _("Server not found in ANSWER SECTION")); | 122 | msg = (char *)_("Server not found in ANSWER SECTION"); |
137 | result = STATE_WARNING; | 123 | result = STATE_WARNING; |
138 | } | 124 | } |
139 | } | ||
140 | |||
141 | } | ||
142 | |||
143 | if (result == STATE_UNKNOWN) { | ||
144 | asprintf (&output, _("No ANSWER SECTION found")); | ||
145 | } | ||
146 | 125 | ||
147 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | 126 | /* we found the answer section, so break out of the loop */ |
148 | /* If we get anything on STDERR, at least set warning */ | 127 | break; |
149 | result = max_state (result, STATE_WARNING); | 128 | } |
150 | printf ("%s", input_buffer); | ||
151 | if (strlen (output) == 0) | ||
152 | output = strdup (1 + index (input_buffer, ':')); | ||
153 | } | 129 | } |
154 | 130 | ||
155 | (void) fclose (child_stderr); | 131 | if (result == STATE_UNKNOWN) |
156 | 132 | msg = (char *)_("No ANSWER SECTION found"); | |
157 | /* close the pipe */ | 133 | |
158 | if (spclose (child_process)) { | 134 | /* If we get anything on STDERR, at least set warning */ |
159 | result = max_state (result, STATE_WARNING); | 135 | if(chld_err.buflen > 0) { |
160 | if (strlen (output) == 0) | 136 | result = max_state(result, STATE_WARNING); |
161 | asprintf (&output, _("dig returned an error status")); | 137 | if(!msg) for(i = 0; i < chld_err.lines; i++) { |
138 | msg = strchr(chld_err.line[0], ':'); | ||
139 | if(msg) { | ||
140 | msg++; | ||
141 | break; | ||
142 | } | ||
143 | } | ||
162 | } | 144 | } |
163 | 145 | ||
164 | microsec = deltime (tv); | 146 | microsec = deltime (tv); |
165 | elapsed_time = (double)microsec / 1.0e6; | 147 | elapsed_time = (double)microsec / 1.0e6; |
166 | 148 | ||
167 | if (output == NULL || strlen (output) == 0) | ||
168 | asprintf (&output, _(" Probably a non-existent host/domain")); | ||
169 | |||
170 | if (critical_interval > UNDEFINED && elapsed_time > critical_interval) | 149 | if (critical_interval > UNDEFINED && elapsed_time > critical_interval) |
171 | result = STATE_CRITICAL; | 150 | result = STATE_CRITICAL; |
172 | 151 | ||
173 | else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) | 152 | else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) |
174 | result = STATE_WARNING; | 153 | result = STATE_WARNING; |
175 | 154 | ||
176 | asprintf (&output, _("%.3f seconds response time (%s)"), elapsed_time, output); | 155 | printf ("DNS %s - %.3f seconds response time (%s)|%s\n", |
177 | 156 | state_text (result), elapsed_time, | |
178 | printf ("DNS %s - %s|%s\n", | 157 | msg ? msg : _("Probably a non-existent host/domain"), |
179 | state_text (result), output, | ||
180 | fperfdata("time", elapsed_time, "s", | 158 | fperfdata("time", elapsed_time, "s", |
181 | (warning_interval>UNDEFINED?TRUE:FALSE), | 159 | (warning_interval>UNDEFINED?TRUE:FALSE), |
182 | warning_interval, | 160 | warning_interval, |
183 | (critical_interval>UNDEFINED?TRUE:FALSE), | 161 | (critical_interval>UNDEFINED?TRUE:FALSE), |
184 | critical_interval, | 162 | critical_interval, |
185 | TRUE, 0, FALSE, 0)); | 163 | TRUE, 0, FALSE, 0)); |
186 | return result; | 164 | return result; |
187 | } | 165 | } |
188 | 166 | ||
@@ -219,8 +197,6 @@ process_arguments (int argc, char **argv) | |||
219 | break; | 197 | break; |
220 | 198 | ||
221 | switch (c) { | 199 | switch (c) { |
222 | case '?': /* help */ | ||
223 | usage2 (_("Unknown argument"), optarg); | ||
224 | case 'h': /* help */ | 200 | case 'h': /* help */ |
225 | print_help (); | 201 | print_help (); |
226 | exit (STATE_OK); | 202 | exit (STATE_OK); |
@@ -228,19 +204,15 @@ process_arguments (int argc, char **argv) | |||
228 | print_revision (progname, revision); | 204 | print_revision (progname, revision); |
229 | exit (STATE_OK); | 205 | exit (STATE_OK); |
230 | case 'H': /* hostname */ | 206 | case 'H': /* hostname */ |
231 | if (is_host (optarg)) { | 207 | host_or_die(optarg); |
232 | dns_server = optarg; | 208 | dns_server = optarg; |
233 | } | ||
234 | else { | ||
235 | usage2 (_("Invalid hostname/address"), optarg); | ||
236 | } | ||
237 | break; | 209 | break; |
238 | case 'p': /* server port */ | 210 | case 'p': /* server port */ |
239 | if (is_intpos (optarg)) { | 211 | if (is_intpos (optarg)) { |
240 | server_port = atoi (optarg); | 212 | server_port = atoi (optarg); |
241 | } | 213 | } |
242 | else { | 214 | else { |
243 | usage2 (_("Port must be a positive integer"), optarg); | 215 | usage_va(_("Port must be a positive integer - %s"), optarg); |
244 | } | 216 | } |
245 | break; | 217 | break; |
246 | case 'l': /* address to lookup */ | 218 | case 'l': /* address to lookup */ |
@@ -251,7 +223,7 @@ process_arguments (int argc, char **argv) | |||
251 | warning_interval = strtod (optarg, NULL); | 223 | warning_interval = strtod (optarg, NULL); |
252 | } | 224 | } |
253 | else { | 225 | else { |
254 | usage2 (_("Warning interval must be a positive integer"), optarg); | 226 | usage_va(_("Warning interval must be a positive integer - %s"), optarg); |
255 | } | 227 | } |
256 | break; | 228 | break; |
257 | case 'c': /* critical */ | 229 | case 'c': /* critical */ |
@@ -259,7 +231,7 @@ process_arguments (int argc, char **argv) | |||
259 | critical_interval = strtod (optarg, NULL); | 231 | critical_interval = strtod (optarg, NULL); |
260 | } | 232 | } |
261 | else { | 233 | else { |
262 | usage2 (_("Critical interval must be a positive integer"), optarg); | 234 | usage_va(_("Critical interval must be a positive integer - %s"), optarg); |
263 | } | 235 | } |
264 | break; | 236 | break; |
265 | case 't': /* timeout */ | 237 | case 't': /* timeout */ |
@@ -267,7 +239,7 @@ process_arguments (int argc, char **argv) | |||
267 | timeout_interval = atoi (optarg); | 239 | timeout_interval = atoi (optarg); |
268 | } | 240 | } |
269 | else { | 241 | else { |
270 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 242 | usage_va(_("Timeout interval must be a positive integer - %s"), optarg); |
271 | } | 243 | } |
272 | break; | 244 | break; |
273 | case 'v': /* verbose */ | 245 | case 'v': /* verbose */ |
@@ -279,18 +251,16 @@ process_arguments (int argc, char **argv) | |||
279 | case 'a': | 251 | case 'a': |
280 | expected_address = optarg; | 252 | expected_address = optarg; |
281 | break; | 253 | break; |
254 | default: /* usage_va */ | ||
255 | usage_va(_("Unknown argument - %s"), optarg); | ||
282 | } | 256 | } |
283 | } | 257 | } |
284 | 258 | ||
285 | c = optind; | 259 | c = optind; |
286 | if (dns_server == NULL) { | 260 | if (dns_server == NULL) { |
287 | if (c < argc) { | 261 | if (c < argc) { |
288 | if (is_host (argv[c])) { | 262 | host_or_die(argv[c]); |
289 | dns_server = argv[c]; | 263 | dns_server = argv[c]; |
290 | } | ||
291 | else { | ||
292 | usage2 (_("Invalid hostname/address"), argv[c]); | ||
293 | } | ||
294 | } | 264 | } |
295 | else { | 265 | else { |
296 | dns_server = strdup ("127.0.0.1"); | 266 | dns_server = strdup ("127.0.0.1"); |
@@ -359,6 +329,6 @@ print_usage (void) | |||
359 | { | 329 | { |
360 | printf ("\ | 330 | printf ("\ |
361 | Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\ | 331 | Usage: %s -H host -l lookup [-p <server port>] [-T <query type>]\n\ |
362 | [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\ | 332 | [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\ |
363 | [-a <expected answer address>] [-v]\n", progname); | 333 | [-a <expected answer address>] [-v]\n", progname); |
364 | } | 334 | } |