Code

14ca781134d62637023ba147d6176ad525278ee0
[pkg-liboping.git] / debian / patches / z-option
1 diff a/src/mans/oping.pod b/src/mans/oping.pod
2 --- a/src/mans/oping.pod
3 +++ b/src/mans/oping.pod
4 @@ -166,6 +166,18 @@ I<Explicit Congestion Notification> (ECN), even if the deprecated
5  I<Type of Service> (ToS) aliases were used to specify the bits of outgoing
6  packets.
7  
8 +=item B<-Z> I<percent>
9 +
10 +If any hosts have a drop rate higher than I<percent>, where I<percent> is a
11 +number between zero and 100 inclusively, exit with a non-zero exit status.
12 +Since it is not possible to have a higher drop rate than 100%, passing this
13 +limit will effectively disable the feature (the default). Setting the option to
14 +zero means that the exit status will only be zero if I<all> replies for I<all>
15 +hosts have been received.
16 +
17 +The exit status will indicate the number of hosts with more than I<percent>
18 +packets lost, up to a number of 255 failing hosts.
19 +
20  =back
21  
22  =head1 COLORS
23 diff a/src/oping.c b/src/oping.c
24 --- a/src/oping.c
25 +++ b/src/oping.c
26 @@ -121,6 +121,7 @@ static char   *opt_filename   = NULL;
27  static int     opt_count      = -1;
28  static int     opt_send_ttl   = 64;
29  static uint8_t opt_send_qos   = 0;
30 +static double  opt_exit_status_threshold = 1.0;
31  
32  static int host_num = 0;
33  
34 @@ -265,6 +266,8 @@ static void usage_exit (const char *name, int status) /* {{{ */
35                         "  -I srcaddr   source address\n"
36                         "  -D device    outgoing interface name\n"
37                         "  -f filename  filename to read hosts from\n"
38 +                       "  -Z percent   Exit with non-zero exit status if more than this percentage of\n"
39 +                       "               probes timed out. (default: never)\n"
40  
41                         "\noping "PACKAGE_VERSION", http://verplant.org/liboping/\n"
42                         "by Florian octo Forster <octo@verplant.org>\n"
43 @@ -467,7 +470,7 @@ static int read_options (int argc, char **argv) /* {{{ */
44  
45         while (1)
46         {
47 -               optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:");
48 +               optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:");
49  
50                 if (optchar == -1)
51                         break;
52 @@ -538,6 +541,24 @@ static int read_options (int argc, char **argv) /* {{{ */
53                                 set_opt_send_qos (optarg);
54                                 break;
55  
56 +                       case 'Z':
57 +                       {
58 +                               char *endptr = NULL;
59 +                               double tmp;
60 +
61 +                               errno = 0;
62 +                               tmp = strtod (optarg, &endptr);
63 +                               if ((errno != 0) || (endptr == NULL) || (*endptr != 0) || (tmp < 0.0) || (tmp > 100.0))
64 +                               {
65 +                                       fprintf (stderr, "Ignoring invalid -Z argument: %s\n", optarg);
66 +                                       fprintf (stderr, "The \"-Z\" option requires a numeric argument between 0 and 100.\n");
67 +                               }
68 +                               else
69 +                                       opt_exit_status_threshold = tmp / 100.0;
70 +
71 +                               break;
72 +                       }
73 +
74                         case 'h':
75                                 usage_exit (argv[0], 0);
76                                 break;
77 @@ -623,7 +644,7 @@ static int update_stats_from_context (ping_context_t *ctx) /* {{{ */
78  
79                 average = context_get_average (ctx);
80                 deviation = context_get_stddev (ctx);
81 -                       
82 +
83                 mvwprintw (ctx->window, /* y = */ 2, /* x = */ 2,
84                                 "rtt min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms",
85                                 ctx->latency_min,
86 @@ -951,9 +972,13 @@ static void update_host_hook (pingobj_iter_t *iter, /* {{{ */
87  #endif
88  } /* }}} void update_host_hook */
89  
90 +/* Prints statistics for each host, cleans up the contexts and returns the
91 + * number of hosts which failed to return more than the fraction
92 + * opt_exit_status_threshold of pings. */
93  static int post_loop_hook (pingobj_t *ping) /* {{{ */
94  {
95         pingobj_iter_t *iter;
96 +       int failure_count = 0;
97  
98  #if USE_NCURSES
99         endwin ();
100 @@ -973,6 +998,13 @@ static int post_loop_hook (pingobj_t *ping) /* {{{ */
101                                 context_get_packet_loss (context),
102                                 context->latency_total);
103  
104 +               {
105 +                       double pct_failed = 1.0 - (((double) context->req_rcvd)
106 +                                       / ((double) context->req_sent));
107 +                       if (pct_failed > opt_exit_status_threshold)
108 +                               failure_count++;
109 +               }
111                 if (context->req_rcvd != 0)
112                 {
113                         double average;
114 @@ -992,7 +1024,7 @@ static int post_loop_hook (pingobj_t *ping) /* {{{ */
115                 context_destroy (context);
116         }
117  
118 -       return (0);
119 +       return (failure_count);
120  } /* }}} int post_loop_hook */
121  
122  int main (int argc, char **argv) /* {{{ */
123 @@ -1281,11 +1313,19 @@ int main (int argc, char **argv) /* {{{ */
124                         opt_count--;
125         } /* while (opt_count != 0) */
126  
127 -       post_loop_hook (ping);
128 +       /* Returns the number of failed hosts according to -Z. */
129 +       status = post_loop_hook (ping);
130  
131         ping_destroy (ping);
132  
133 -       return (0);
134 +       if (status == 0)
135 +               exit (EXIT_SUCCESS);
136 +       else
137 +       {
138 +               if (status > 255)
139 +                       status = 255;
140 +               exit (status);
141 +       }
142  } /* }}} int main */
143  
144  /* vim: set fdm=marker : */