summaryrefslogtreecommitdiffstats
path: root/plugins/check_fping.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_fping.c')
-rw-r--r--plugins/check_fping.c309
1 files changed, 158 insertions, 151 deletions
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index c1d03ece..e05056b2 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -38,52 +38,29 @@ const char *email = "devel@monitoring-plugins.org";
38#include "netutils.h" 38#include "netutils.h"
39#include "utils.h" 39#include "utils.h"
40#include <stdbool.h> 40#include <stdbool.h>
41#include "check_fping.d/config.h"
42#include "states.h"
41 43
42enum { 44enum {
43 PACKET_COUNT = 1,
44 PACKET_SIZE = 56,
45 PL = 0, 45 PL = 0,
46 RTA = 1 46 RTA = 1
47}; 47};
48 48
49static int textscan(char *buf); 49static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/, double /*crta*/, bool /*wrta_p*/, double /*wrta*/,
50static int process_arguments(int /*argc*/, char ** /*argv*/); 50 bool /*cpl_p*/, int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/);
51
52typedef struct {
53 int errorcode;
54 check_fping_config config;
55} check_fping_config_wrapper;
56static check_fping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
51static int get_threshold(char *arg, char *rv[2]); 57static int get_threshold(char *arg, char *rv[2]);
52static void print_help(void); 58static void print_help(void);
53void print_usage(void); 59void print_usage(void);
54 60
55static char *server_name = NULL;
56static char *sourceip = NULL;
57static char *sourceif = NULL;
58static int packet_size = PACKET_SIZE;
59static int packet_count = PACKET_COUNT;
60static int target_timeout = 0;
61static int packet_interval = 0;
62static bool verbose = false; 61static bool verbose = false;
63static bool dontfrag = false;
64static bool randomize_packet_data = false;
65static int cpl;
66static int wpl;
67static double crta;
68static double wrta;
69static bool cpl_p = false;
70static bool wpl_p = false;
71static bool alive_p = false;
72static bool crta_p = false;
73static bool wrta_p = false;
74 62
75int main(int argc, char **argv) { 63int main(int argc, char **argv) {
76 /* normally should be int result = STATE_UNKNOWN; */
77
78 int status = STATE_UNKNOWN;
79 int result = 0;
80 char *fping_prog = NULL;
81 char *server = NULL;
82 char *command_line = NULL;
83 char *input_buffer = NULL;
84 char *option_string = "";
85 input_buffer = malloc(MAX_INPUT_BUFFER);
86
87 setlocale(LC_ALL, ""); 64 setlocale(LC_ALL, "");
88 bindtextdomain(PACKAGE, LOCALEDIR); 65 bindtextdomain(PACKAGE, LOCALEDIR);
89 textdomain(PACKAGE); 66 textdomain(PACKAGE);
@@ -91,39 +68,61 @@ int main(int argc, char **argv) {
91 /* Parse extra opts if any */ 68 /* Parse extra opts if any */
92 argv = np_extra_opts(&argc, argv, progname); 69 argv = np_extra_opts(&argc, argv, progname);
93 70
94 if (process_arguments(argc, argv) == ERROR) 71 check_fping_config_wrapper tmp_config = process_arguments(argc, argv);
72 if (tmp_config.errorcode == ERROR) {
95 usage4(_("Could not parse arguments")); 73 usage4(_("Could not parse arguments"));
74 }
96 75
97 server = strscpy(server, server_name); 76 const check_fping_config config = tmp_config.config;
98 77
99 /* compose the command */ 78 char *server = NULL;
100 if (target_timeout) 79 server = strscpy(server, config.server_name);
101 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
102 if (packet_interval)
103 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
104 if (sourceip)
105 xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
106 if (sourceif)
107 xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
108 if (dontfrag)
109 xasprintf(&option_string, "%s-M ", option_string);
110 if (randomize_packet_data)
111 xasprintf(&option_string, "%s-R ", option_string);
112 80
81 char *option_string = "";
82 char *fping_prog = NULL;
113 83
114#ifdef PATH_TO_FPING6 84 /* First determine if the target is dualstack or ipv6 only. */
115 if (address_family != AF_INET && is_inet6_addr(server)) 85 bool server_is_inet6_addr = is_inet6_addr(server);
116 fping_prog = strdup(PATH_TO_FPING6); 86
117 else 87 /*
118 fping_prog = strdup(PATH_TO_FPING); 88 * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack
119#else 89 * -> we use ipv6
90 * If the user requested -4 OR the user made no assertion and the address is v4 ONLY
91 * -> we use ipv4
92 */
93 if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) {
94 xasprintf(&option_string, "%s-6 ", option_string);
95 } else {
96 xasprintf(&option_string, "%s-4 ", option_string);
97 }
120 fping_prog = strdup(PATH_TO_FPING); 98 fping_prog = strdup(PATH_TO_FPING);
121#endif
122 99
123 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server); 100 /* compose the command */
101 if (config.target_timeout) {
102 xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout);
103 }
104 if (config.packet_interval) {
105 xasprintf(&option_string, "%s-p %d ", option_string, config.packet_interval);
106 }
107 if (config.sourceip) {
108 xasprintf(&option_string, "%s-S %s ", option_string, config.sourceip);
109 }
110 if (config.sourceif) {
111 xasprintf(&option_string, "%s-I %s ", option_string, config.sourceif);
112 }
113 if (config.dontfrag) {
114 xasprintf(&option_string, "%s-M ", option_string);
115 }
116 if (config.randomize_packet_data) {
117 xasprintf(&option_string, "%s-R ", option_string);
118 }
119
120 char *command_line = NULL;
121 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server);
124 122
125 if (verbose) 123 if (verbose) {
126 printf("%s\n", command_line); 124 printf("%s\n", command_line);
125 }
127 126
128 /* run the command */ 127 /* run the command */
129 child_process = spopen(command_line); 128 child_process = spopen(command_line);
@@ -137,23 +136,29 @@ int main(int argc, char **argv) {
137 printf(_("Could not open stderr for %s\n"), command_line); 136 printf(_("Could not open stderr for %s\n"), command_line);
138 } 137 }
139 138
139 char *input_buffer = malloc(MAX_INPUT_BUFFER);
140 mp_state_enum status = STATE_UNKNOWN;
140 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 141 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
141 if (verbose) 142 if (verbose) {
142 printf("%s", input_buffer); 143 printf("%s", input_buffer);
143 status = max_state(status, textscan(input_buffer)); 144 }
145 status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta,
146 config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p));
144 } 147 }
145 148
146 /* If we get anything on STDERR, at least set warning */ 149 /* If we get anything on STDERR, at least set warning */
147 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 150 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
148 status = max_state(status, STATE_WARNING); 151 status = max_state(status, STATE_WARNING);
149 if (verbose) 152 if (verbose) {
150 printf("%s", input_buffer); 153 printf("%s", input_buffer);
151 status = max_state(status, textscan(input_buffer)); 154 }
155 status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta,
156 config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p));
152 } 157 }
153 (void)fclose(child_stderr); 158 (void)fclose(child_stderr);
154 159
155 /* close the pipe */ 160 /* close the pipe */
156 result = spclose(child_process); 161 int result = spclose(child_process);
157 if (result) { 162 if (result) {
158 /* need to use max_state not max */ 163 /* need to use max_state not max */
159 status = max_state(status, STATE_WARNING); 164 status = max_state(status, STATE_WARNING);
@@ -172,21 +177,17 @@ int main(int argc, char **argv) {
172 } 177 }
173 } 178 }
174 179
175 printf("FPING %s - %s\n", state_text(status), server_name); 180 printf("FPING %s - %s\n", state_text(status), config.server_name);
176 181
177 return status; 182 return status;
178} 183}
179 184
180int textscan(char *buf) { 185mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p, double wrta, bool cpl_p, int cpl,
181 char *rtastr = NULL; 186 bool wpl_p, int wpl, bool alive_p) {
182 char *losstr = NULL;
183 char *xmtstr = NULL;
184 double loss;
185 double rta;
186 double xmt;
187 int status = STATE_UNKNOWN;
188
189 /* stops testing after the first successful reply. */ 187 /* stops testing after the first successful reply. */
188 double rta;
189 double loss;
190 char *rtastr = NULL;
190 if (alive_p && strstr(buf, "avg, 0% loss)")) { 191 if (alive_p && strstr(buf, "avg, 0% loss)")) {
191 rtastr = strstr(buf, "ms ("); 192 rtastr = strstr(buf, "ms (");
192 rtastr = 1 + index(rtastr, '('); 193 rtastr = 1 + index(rtastr, '(');
@@ -198,6 +199,10 @@ int textscan(char *buf) {
198 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); 199 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
199 } 200 }
200 201
202 mp_state_enum status = STATE_UNKNOWN;
203 char *xmtstr = NULL;
204 double xmt;
205 char *losstr = NULL;
201 if (strstr(buf, "not found")) { 206 if (strstr(buf, "not found")) {
202 die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); 207 die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
203 208
@@ -221,18 +226,19 @@ int textscan(char *buf) {
221 rtastr = 1 + index(rtastr, '/'); 226 rtastr = 1 + index(rtastr, '/');
222 loss = strtod(losstr, NULL); 227 loss = strtod(losstr, NULL);
223 rta = strtod(rtastr, NULL); 228 rta = strtod(rtastr, NULL);
224 if (cpl_p && loss > cpl) 229 if (cpl_p && loss > cpl) {
225 status = STATE_CRITICAL; 230 status = STATE_CRITICAL;
226 else if (crta_p && rta > crta) 231 } else if (crta_p && rta > crta) {
227 status = STATE_CRITICAL; 232 status = STATE_CRITICAL;
228 else if (wpl_p && loss > wpl) 233 } else if (wpl_p && loss > wpl) {
229 status = STATE_WARNING; 234 status = STATE_WARNING;
230 else if (wrta_p && rta > wrta) 235 } else if (wrta_p && rta > wrta) {
231 status = STATE_WARNING; 236 status = STATE_WARNING;
232 else 237 } else {
233 status = STATE_OK; 238 status = STATE_OK;
239 }
234 die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, 240 die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta,
235 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), 241 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0),
236 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); 242 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
237 243
238 } else if (strstr(buf, "xmt/rcv/%loss")) { 244 } else if (strstr(buf, "xmt/rcv/%loss")) {
@@ -241,22 +247,24 @@ int textscan(char *buf) {
241 losstr = strstr(buf, "="); 247 losstr = strstr(buf, "=");
242 xmtstr = 1 + losstr; 248 xmtstr = 1 + losstr;
243 xmt = strtod(xmtstr, NULL); 249 xmt = strtod(xmtstr, NULL);
244 if (xmt == 0) 250 if (xmt == 0) {
245 die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); 251 die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
252 }
246 losstr = 1 + strstr(losstr, "/"); 253 losstr = 1 + strstr(losstr, "/");
247 losstr = 1 + strstr(losstr, "/"); 254 losstr = 1 + strstr(losstr, "/");
248 loss = strtod(losstr, NULL); 255 loss = strtod(losstr, NULL);
249 if (atoi(losstr) == 100) 256 if (atoi(losstr) == 100) {
250 status = STATE_CRITICAL; 257 status = STATE_CRITICAL;
251 else if (cpl_p && loss > cpl) 258 } else if (cpl_p && loss > cpl) {
252 status = STATE_CRITICAL; 259 status = STATE_CRITICAL;
253 else if (wpl_p && loss > wpl) 260 } else if (wpl_p && loss > wpl) {
254 status = STATE_WARNING; 261 status = STATE_WARNING;
255 else 262 } else {
256 status = STATE_OK; 263 status = STATE_OK;
264 }
257 /* loss=%.0f%%;%d;%d;0;100 */ 265 /* loss=%.0f%%;%d;%d;0;100 */
258 die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss, 266 die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss,
259 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); 267 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0));
260 268
261 } else { 269 } else {
262 status = max_state(status, STATE_WARNING); 270 status = max_state(status, STATE_WARNING);
@@ -266,54 +274,50 @@ int textscan(char *buf) {
266} 274}
267 275
268/* process command-line arguments */ 276/* process command-line arguments */
269int process_arguments(int argc, char **argv) { 277check_fping_config_wrapper process_arguments(int argc, char **argv) {
270 int c; 278 static struct option longopts[] = {
279 {"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'},
280 {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'},
281 {"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'},
282 {"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
283 {"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'},
284 {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}};
285
271 char *rv[2]; 286 char *rv[2];
287 rv[PL] = NULL;
288 rv[RTA] = NULL;
272 289
273 int option = 0; 290 int option = 0;
274 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
275 {"sourceip", required_argument, 0, 'S'},
276 {"sourceif", required_argument, 0, 'I'},
277 {"critical", required_argument, 0, 'c'},
278 {"warning", required_argument, 0, 'w'},
279 {"alive", no_argument, 0, 'a'},
280 {"bytes", required_argument, 0, 'b'},
281 {"number", required_argument, 0, 'n'},
282 {"target-timeout", required_argument, 0, 'T'},
283 {"interval", required_argument, 0, 'i'},
284 {"verbose", no_argument, 0, 'v'},
285 {"version", no_argument, 0, 'V'},
286 {"help", no_argument, 0, 'h'},
287 {"use-ipv4", no_argument, 0, '4'},
288 {"use-ipv6", no_argument, 0, '6'},
289 {"dontfrag", no_argument, 0, 'M'},
290 {"random", no_argument, 0, 'R'},
291 {0, 0, 0, 0}};
292 291
293 rv[PL] = NULL; 292 check_fping_config_wrapper result = {
294 rv[RTA] = NULL; 293 .errorcode = OK,
294 .config = check_fping_config_init(),
295 };
295 296
296 if (argc < 2) 297 if (argc < 2) {
297 return ERROR; 298 result.errorcode = ERROR;
299 return result;
300 }
298 301
299 if (!is_option(argv[1])) { 302 if (!is_option(argv[1])) {
300 server_name = argv[1]; 303 result.config.server_name = argv[1];
301 argv[1] = argv[0]; 304 argv[1] = argv[0];
302 argv = &argv[1]; 305 argv = &argv[1];
303 argc--; 306 argc--;
304 } 307 }
305 308
306 while (1) { 309 while (1) {
307 c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); 310 int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option);
308 311
309 if (c == -1 || c == EOF || c == 1) 312 if (option_index == -1 || option_index == EOF || option_index == 1) {
310 break; 313 break;
314 }
311 315
312 switch (c) { 316 switch (option_index) {
313 case '?': /* print short usage statement if args not parsable */ 317 case '?': /* print short usage statement if args not parsable */
314 usage5(); 318 usage5();
315 case 'a': /* host alive mode */ 319 case 'a': /* host alive mode */
316 alive_p = true; 320 result.config.alive_p = true;
317 break; 321 break;
318 case 'h': /* help */ 322 case 'h': /* help */
319 print_help(); 323 print_help();
@@ -325,109 +329,112 @@ int process_arguments(int argc, char **argv) {
325 verbose = true; 329 verbose = true;
326 break; 330 break;
327 case 'H': /* hostname */ 331 case 'H': /* hostname */
328 if (is_host(optarg) == false) { 332 if (!is_host(optarg)) {
329 usage2(_("Invalid hostname/address"), optarg); 333 usage2(_("Invalid hostname/address"), optarg);
330 } 334 }
331 server_name = strscpy(server_name, optarg); 335 result.config.server_name = optarg;
332 break; 336 break;
333 case 'S': /* sourceip */ 337 case 'S': /* sourceip */
334 if (is_host(optarg) == false) { 338 if (!is_host(optarg)) {
335 usage2(_("Invalid hostname/address"), optarg); 339 usage2(_("Invalid hostname/address"), optarg);
336 } 340 }
337 sourceip = strscpy(sourceip, optarg); 341 result.config.sourceip = optarg;
338 break; 342 break;
339 case 'I': /* sourceip */ 343 case 'I': /* sourceip */
340 sourceif = strscpy(sourceif, optarg); 344 result.config.sourceif = optarg;
341 break; 345 break;
342 case '4': /* IPv4 only */ 346 case '4': /* IPv4 only */
343 address_family = AF_INET; 347 address_family = AF_INET;
344 break; 348 break;
345 case '6': /* IPv6 only */ 349 case '6': /* IPv6 only */
346#ifdef USE_IPV6
347 address_family = AF_INET6; 350 address_family = AF_INET6;
348#else
349 usage(_("IPv6 support not available\n"));
350#endif
351 break; 351 break;
352 case 'c': 352 case 'c':
353 get_threshold(optarg, rv); 353 get_threshold(optarg, rv);
354 if (rv[RTA]) { 354 if (rv[RTA]) {
355 crta = strtod(rv[RTA], NULL); 355 result.config.crta = strtod(rv[RTA], NULL);
356 crta_p = true; 356 result.config.crta_p = true;
357 rv[RTA] = NULL; 357 rv[RTA] = NULL;
358 } 358 }
359 if (rv[PL]) { 359 if (rv[PL]) {
360 cpl = atoi(rv[PL]); 360 result.config.cpl = atoi(rv[PL]);
361 cpl_p = true; 361 result.config.cpl_p = true;
362 rv[PL] = NULL; 362 rv[PL] = NULL;
363 } 363 }
364 break; 364 break;
365 case 'w': 365 case 'w':
366 get_threshold(optarg, rv); 366 get_threshold(optarg, rv);
367 if (rv[RTA]) { 367 if (rv[RTA]) {
368 wrta = strtod(rv[RTA], NULL); 368 result.config.wrta = strtod(rv[RTA], NULL);
369 wrta_p = true; 369 result.config.wrta_p = true;
370 rv[RTA] = NULL; 370 rv[RTA] = NULL;
371 } 371 }
372 if (rv[PL]) { 372 if (rv[PL]) {
373 wpl = atoi(rv[PL]); 373 result.config.wpl = atoi(rv[PL]);
374 wpl_p = true; 374 result.config.wpl_p = true;
375 rv[PL] = NULL; 375 rv[PL] = NULL;
376 } 376 }
377 break; 377 break;
378 case 'b': /* bytes per packet */ 378 case 'b': /* bytes per packet */
379 if (is_intpos(optarg)) 379 if (is_intpos(optarg)) {
380 packet_size = atoi(optarg); 380 result.config.packet_size = atoi(optarg);
381 else 381 } else {
382 usage(_("Packet size must be a positive integer")); 382 usage(_("Packet size must be a positive integer"));
383 }
383 break; 384 break;
384 case 'n': /* number of packets */ 385 case 'n': /* number of packets */
385 if (is_intpos(optarg)) 386 if (is_intpos(optarg)) {
386 packet_count = atoi(optarg); 387 result.config.packet_count = atoi(optarg);
387 else 388 } else {
388 usage(_("Packet count must be a positive integer")); 389 usage(_("Packet count must be a positive integer"));
390 }
389 break; 391 break;
390 case 'T': /* timeout in msec */ 392 case 'T': /* timeout in msec */
391 if (is_intpos(optarg)) 393 if (is_intpos(optarg)) {
392 target_timeout = atoi(optarg); 394 result.config.target_timeout = atoi(optarg);
393 else 395 } else {
394 usage(_("Target timeout must be a positive integer")); 396 usage(_("Target timeout must be a positive integer"));
397 }
395 break; 398 break;
396 case 'i': /* interval in msec */ 399 case 'i': /* interval in msec */
397 if (is_intpos(optarg)) 400 if (is_intpos(optarg)) {
398 packet_interval = atoi(optarg); 401 result.config.packet_interval = atoi(optarg);
399 else 402 } else {
400 usage(_("Interval must be a positive integer")); 403 usage(_("Interval must be a positive integer"));
404 }
401 break; 405 break;
402 case 'R': 406 case 'R':
403 randomize_packet_data = true; 407 result.config.randomize_packet_data = true;
404 break; 408 break;
405 case 'M': 409 case 'M':
406 dontfrag = true; 410 result.config.dontfrag = true;
407 break; 411 break;
408 } 412 }
409 } 413 }
410 414
411 if (server_name == NULL) 415 if (result.config.server_name == NULL) {
412 usage4(_("Hostname was not supplied")); 416 usage4(_("Hostname was not supplied"));
417 }
413 418
414 return OK; 419 return result;
415} 420}
416 421
417int get_threshold(char *arg, char *rv[2]) { 422int get_threshold(char *arg, char *rv[2]) {
418 char *arg1 = NULL;
419 char *arg2 = NULL; 423 char *arg2 = NULL;
420 424
421 arg1 = strscpy(arg1, arg); 425 char *arg1 = strdup(arg);
422 if (strpbrk(arg1, ",:")) 426 if (strpbrk(arg1, ",:")) {
423 arg2 = 1 + strpbrk(arg1, ",:"); 427 arg2 = 1 + strpbrk(arg1, ",:");
428 }
424 429
425 if (arg2) { 430 if (arg2) {
426 arg1[strcspn(arg1, ",:")] = 0; 431 arg1[strcspn(arg1, ",:")] = 0;
427 if (strstr(arg1, "%") && strstr(arg2, "%")) 432 if (strstr(arg1, "%") && strstr(arg2, "%")) {
428 die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); 433 die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg);
429 if (!strstr(arg1, "%") && !strstr(arg2, "%")) 434 }
435 if (!strstr(arg1, "%") && !strstr(arg2, "%")) {
430 die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); 436 die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg);
437 }
431 } 438 }
432 439
433 if (arg2 && strstr(arg2, "%")) { 440 if (arg2 && strstr(arg2, "%")) {