diff --git a/ci/test-10-option-u-v.pl b/ci/test-10-option-u-x.pl similarity index 51% rename from ci/test-10-option-u-v.pl rename to ci/test-10-option-u-x.pl index 3e9bcf6b..97acf9a7 100755 --- a/ci/test-10-option-u-v.pl +++ b/ci/test-10-option-u-x.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -use Test::Command tests => 6; +use Test::Command tests => 12; # -u show targets that are unreachable # -v show version @@ -22,3 +22,19 @@ }); $cmd->stderr_is_eq(""); } + +# fping -x +{ +my $cmd = Test::Command->new(cmd => "fping -x 1 8.8.0.0 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_is_eq("Enough hosts reachable (required: 1, reachable: 1)\n"); +$cmd->stderr_is_eq(""); +} + +# fping -x +{ +my $cmd = Test::Command->new(cmd => "fping -x 2 8.8.0.0 127.0.0.1"); +$cmd->exit_is_num(1); +$cmd->stdout_is_eq("Not enough hosts reachable (required: 2, reachable: 1)\n"); +$cmd->stderr_is_eq(""); +} diff --git a/doc/fping.pod b/doc/fping.pod index af21bade..2805837c 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -225,6 +225,10 @@ Show targets that are unreachable. Print B version information. +=item B<-x>, B<--min_reachable>=I + +Given a list of hosts, this mode prints if number of active hosts>=N or not. + =back =head1 EXAMPLES diff --git a/src/fping.c b/src/fping.c index a4e45a1c..7ddd58ee 100644 --- a/src/fping.c +++ b/src/fping.c @@ -248,7 +248,7 @@ unsigned int interval = DEFAULT_INTERVAL * 100; unsigned int perhost_interval = DEFAULT_PERHOST_INTERVAL * 100; float backoff = DEFAULT_BACKOFF_FACTOR; unsigned int ping_data_size = DEFAULT_PING_DATA_SIZE; -unsigned int count = 1; +unsigned int count = 1, min_reachable = 0; unsigned int trials; unsigned int report_interval = 0; unsigned int ttl = 0; @@ -414,6 +414,7 @@ int main(int argc, char** argv) { NULL, 'T', OPTPARSE_REQUIRED }, { "unreach", 'u', OPTPARSE_NONE }, { "version", 'v', OPTPARSE_NONE }, + { "min_reachable", 'x', OPTPARSE_REQUIRED }, { 0, 0, 0 } }; @@ -604,6 +605,11 @@ int main(int argc, char** argv) printf("%s: comments to %s\n", prog, EMAIL); exit(0); + case 'x': + if (!(min_reachable = (unsigned int)atoi(optparse_state.optarg))) + usage(1); + break; + case 'f': filename = optparse_state.optarg; break; @@ -732,7 +738,7 @@ int main(int argc, char** argv) exit(1); } - if (alive_flag || unreachable_flag) + if (alive_flag || unreachable_flag || min_reachable) verbose_flag = 0; if (count_flag) { @@ -1323,6 +1329,16 @@ void finish() if (stats_flag) print_global_stats(); + if (min_reachable) { + if ((num_hosts-num_unreachable) >= min_reachable) { + printf("Enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts-num_unreachable); + exit(0); + } else { + printf("Not enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts-num_unreachable); + exit(1); + } + } + if (num_noaddress) exit(2); else if (num_alive != num_hosts) @@ -2767,5 +2783,6 @@ void usage(int is_error) fprintf(out, " -s, --stats print final stats\n"); fprintf(out, " -u, --unreach show targets that are unreachable\n"); fprintf(out, " -v, --version show version\n"); + fprintf(out, " -x, --min_reachable=N shows if >=N hosts are reachable or not\n"); exit(is_error); -} +} \ No newline at end of file