# define _POSIX_SAVED_IDS 0
#endif
+#ifndef IPTOS_MINCOST
+# define IPTOS_MINCOST 0x02
+#endif
+
/* Remove GNU specific __attribute__ settings when using another compiler */
#if !__GNUC__
# define __attribute__(x) /**/
static int opt_count = -1;
static int opt_send_ttl = 64;
static uint8_t opt_send_qos = 0;
+static double opt_exit_status_threshold = 1.0;
#if USE_NCURSES
static int opt_utf8 = 0;
#endif
#if USE_NCURSES
" -u / -U force / disable UTF-8 output\n"
#endif
+ " -Z percent Exit with non-zero exit status if more than this percentage of\n"
+ " probes timed out. (default: never)\n"
"\noping "PACKAGE_VERSION", http://verplant.org/liboping/\n"
"by Florian octo Forster <octo@verplant.org>\n"
while (1)
{
- optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:"
+ optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:"
#if USE_NCURSES
"uU"
#endif
break;
#endif
+ case 'Z':
+ {
+ char *endptr = NULL;
+ double tmp;
+
+ errno = 0;
+ tmp = strtod (optarg, &endptr);
+ if ((errno != 0) || (endptr == NULL) || (*endptr != 0) || (tmp < 0.0) || (tmp > 100.0))
+ {
+ fprintf (stderr, "Ignoring invalid -Z argument: %s\n", optarg);
+ fprintf (stderr, "The \"-Z\" option requires a numeric argument between 0 and 100.\n");
+ }
+ else
+ opt_exit_status_threshold = tmp / 100.0;
+
+ break;
+ }
+
case 'h':
usage_exit (argv[0], 0);
break;
int color = OPING_RED;
char const *symbol = "!";
int symbolc = '!';
- size_t hist_symbols_num;
- size_t index_symbols;
int x_max;
int x_pos;
x_max = getmaxx (ctx->window);
x_pos = ((sequence - 1) % (x_max - 4)) + 2;
- if (has_utf8())
- {
- hist_symbols_num = hist_symbols_utf8_num;
- }
- else {
- hist_symbols_num = hist_symbols_acs_num;
- }
-
if (latency >= 0.0)
{
double ratio;
- size_t intensity;
+
+ size_t symbols_num = hist_symbols_acs_num;
+ size_t colors_num = 1;
+
+ size_t index_symbols;
size_t index_colors;
+ size_t intensity;
- ratio = latency / PING_DEF_TTL;
+ /* latency is in milliseconds, opt_interval is in seconds. */
+ ratio = (latency * 0.001) / opt_interval;
if (ratio > 1) {
ratio = 1.0;
}
- intensity = (size_t) ((ratio * hist_symbols_num
- * hist_colors_num) - 1);
+ if (has_utf8 ())
+ symbols_num = hist_symbols_utf8_num;
- index_colors = intensity / hist_symbols_num;
- assert (index_colors < hist_colors_num);
+ if (has_colors () == TRUE)
+ colors_num = hist_colors_num;
+
+ intensity = (size_t) (ratio * ((double) (symbols_num * colors_num)));
+ if (intensity >= (symbols_num * colors_num))
+ intensity = (symbols_num * colors_num) - 1;
+
+ index_symbols = intensity % symbols_num;
+ assert (index_symbols < symbols_num);
+
+ index_colors = intensity / symbols_num;
+ assert (index_colors < colors_num);
- index_symbols = intensity % hist_symbols_num;
if (has_utf8())
{
color = hist_colors_utf8[index_colors];
color = hist_colors_acs[index_colors];
symbolc = hist_symbols_acs[index_symbols] | A_ALTCHARSET;
}
- }
+ }
else /* if (!(latency >= 0.0)) */
wattron (ctx->window, A_BOLD);
- wattron (ctx->window, COLOR_PAIR(color));
+ if (has_colors () == TRUE)
+ wattron (ctx->window, COLOR_PAIR(color));
+
if (has_utf8())
- {
- mvwprintw (ctx->window,
- /* y = */ 3,
- /* x = */ x_pos,
- symbol);
- }
- else {
- mvwaddch (ctx->window,
- /* y = */ 3,
- /* x = */ x_pos,
- symbolc);
- }
- wattroff (ctx->window, COLOR_PAIR(color));
+ mvwprintw (ctx->window, /* y = */ 3, /* x = */ x_pos, symbol);
+ else
+ mvwaddch (ctx->window, /* y = */ 3, /* x = */ x_pos, symbolc);
+
+ if (has_colors () == TRUE)
+ wattroff (ctx->window, COLOR_PAIR(color));
/* Use negation here to handle NaN correctly. */
if (!(latency >= 0.0))
average = context_get_average (ctx);
deviation = context_get_stddev (ctx);
-
+
mvwprintw (ctx->window, /* y = */ 2, /* x = */ 2,
"rtt min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms",
ctx->latency_min,
deviation);
}
- if (has_colors () == TRUE)
- update_prettyping_graph (ctx, latency, sequence);
+ update_prettyping_graph (ctx, latency, sequence);
wrefresh (ctx->window);
#endif
} /* }}} void update_host_hook */
+/* Prints statistics for each host, cleans up the contexts and returns the
+ * number of hosts which failed to return more than the fraction
+ * opt_exit_status_threshold of pings. */
static int post_loop_hook (pingobj_t *ping) /* {{{ */
{
pingobj_iter_t *iter;
+ int failure_count = 0;
#if USE_NCURSES
endwin ();
context_get_packet_loss (context),
context->latency_total);
+ {
+ double pct_failed = 1.0 - (((double) context->req_rcvd)
+ / ((double) context->req_sent));
+ if (pct_failed > opt_exit_status_threshold)
+ failure_count++;
+ }
+
if (context->req_rcvd != 0)
{
double average;
context_destroy (context);
}
- return (0);
+ return (failure_count);
} /* }}} int post_loop_hook */
int main (int argc, char **argv) /* {{{ */
return (1);
}
- if (ping_send (ping) < 0)
+ status = ping_send (ping);
+ if (status == -EINTR)
+ {
+ continue;
+ }
+ else if (status < 0)
{
fprintf (stderr, "ping_send failed: %s\n",
ping_get_error (ping));
/* printf ("Sleeping for %i.%09li seconds\n", (int) ts_wait.tv_sec, ts_wait.tv_nsec); */
while ((status = nanosleep (&ts_wait, &ts_wait)) != 0)
{
- if (errno != EINTR)
+ if (errno == EINTR)
{
- perror ("nanosleep");
- break;
+ continue;
}
- else if (opt_count == 0)
+ else
{
- /* sigint */
+ perror ("nanosleep");
break;
}
}
opt_count--;
} /* while (opt_count != 0) */
- post_loop_hook (ping);
+ /* Returns the number of failed hosts according to -Z. */
+ status = post_loop_hook (ping);
ping_destroy (ping);
- return (0);
+ if (status == 0)
+ exit (EXIT_SUCCESS);
+ else
+ {
+ if (status > 255)
+ status = 255;
+ exit (status);
+ }
} /* }}} int main */
/* vim: set fdm=marker : */