From 4f07a3a56e31c0154bd2374b8e25c0439e619b50 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 8 Jun 2010 09:37:33 +0200 Subject: [PATCH] src/oping.c: Add ncurses based front-end. --- configure.ac | 8 +++++ src/Makefile.am | 12 ++++++++ src/oping.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 114 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 3377772..3b1b574 100644 --- a/configure.ac +++ b/configure.ac @@ -186,6 +186,14 @@ AC_CHECK_FUNCS(nanosleep, [], AC_MSG_ERROR(cannot find nanosleep))) AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes") +with_ncurses="yes" +AC_CHECK_HEADERS(ncurses.h, [with_ncurses="yes"], [with_ncurses="no"]) +if test "x$with_ncurses" = "xyes" +then + AC_CHECK_LIB(ncurses, mvwprintw, [with_ncurses="yes"], [with_ncurses="no"]) +fi +AM_CONDITIONAL(BUILD_WITH_LIBNCURSES, test "x$with_ncurses" = "xyes") + AC_FUNC_STRERROR_R AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], [Enable extensive debugging output.])], diff --git a/src/Makefile.am b/src/Makefile.am index 8bd885c..d411209 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,3 +39,15 @@ oping_LDFLAGS = -lm if BUILD_WITH_LIBRT oping_LDFLAGS += -lrt endif + +if BUILD_WITH_LIBNCURSES +bin_PROGRAMS += noping + +noping_SOURCES = oping.c +noping_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_NCURSES=1 +noping_LDADD = liboping.la +noping_LDFLAGS = -lm -lncurses +if BUILD_WITH_LIBRT +noping_LDFLAGS += -lrt +endif +endif # BUILD_WITH_LIBNCURSES diff --git a/src/oping.c b/src/oping.c index e4584d7..bf494ba 100644 --- a/src/oping.c +++ b/src/oping.c @@ -62,6 +62,10 @@ #include #endif +#if USE_NCURSES +# include +#endif + #include "oping.h" #ifndef _POSIX_SAVED_IDS @@ -80,6 +84,10 @@ typedef struct ping_context double latency_max; double latency_total; double latency_total_square; + +#if USE_NCURSES + WINDOW *window; +#endif } ping_context_t; static double opt_interval = 1.0; @@ -90,6 +98,10 @@ static char *opt_filename = NULL; static int opt_count = -1; static int opt_send_ttl = 64; +#if USE_NCURSES +static WINDOW *main_win = NULL; +#endif + static void sigint_handler (int signal) { /* Make compiler happy */ @@ -112,6 +124,10 @@ static ping_context_t *context_create (void) ret->latency_total = 0.0; ret->latency_total_square = 0.0; +#if USE_NCURSES + ret->window = NULL; +#endif + return (ret); } @@ -120,6 +136,14 @@ static void context_destroy (ping_context_t *context) if (context == NULL) return; +#if USE_NCURSES + if (context->window != NULL) + { + delwin (context->window); + context->window = NULL; + } +#endif + free (context); } @@ -262,6 +286,12 @@ static void print_host (pingobj_iter_t *iter) context = (ping_context_t *) ping_iterator_get_context (iter); +#if USE_NCURSES +# define HOST_PRINTF(...) wprintw(main_win, __VA_ARGS__) +#else +# define HOST_PRINTF(...) printf(__VA_ARGS__) +#endif + context->req_sent++; if (latency > 0.0) { @@ -274,17 +304,53 @@ static void print_host (pingobj_iter_t *iter) if ((context->latency_min < 0.0) || (context->latency_min > latency)) context->latency_min = latency; - printf ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i time=%.2f ms\n", + HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i " + "time=%.2f ms\n", data_len, context->host, context->addr, sequence, recv_ttl, latency); } else { - printf ("echo reply from %s (%s): icmp_seq=%u timeout\n", + HOST_PRINTF ("echo reply from %s (%s): icmp_seq=%u timeout\n", context->host, context->addr, sequence); } + +#if USE_NCURSES + wrefresh (main_win); + werase (context->window); + box (context->window, 0, 0); + mvwprintw (context->window, /* y = */ 0, /* x = */ 5, + " %s ping statistics ", + context->host); + mvwprintw (context->window, /* y = */ 1, /* x = */ 2, + "%i packets transmitted, %i received, %.2f%% packet " + "loss, time %.1fms", + context->req_sent, context->req_rcvd, + 100.0 * (context->req_sent - context->req_rcvd) / ((double) context->req_sent), + context->latency_total); + if (context->req_rcvd != 0) + { + double num_total; + double average; + double deviation; + + num_total = (double) context->req_rcvd; + + average = context->latency_total / num_total; + deviation = sqrt (((num_total * context->latency_total_square) - (context->latency_total * context->latency_total)) + / (num_total * (num_total - 1.0))); + + mvwprintw (context->window, /* y = */ 2, /* x = */ 2, + "rtt min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms", + context->latency_min, + average, + context->latency_max, + deviation); + } + wrefresh (context->window); +#endif } static void time_normalize (struct timespec *ts) @@ -339,6 +405,12 @@ static int print_header (pingobj_t *ping) /* {{{ */ pingobj_iter_t *iter; int i; +#if USE_NCURSES + initscr (); + cbreak (); + noecho (); +#endif + i = 0; for (iter = ping_iterator_get (ping); iter != NULL; @@ -358,14 +430,30 @@ static int print_header (pingobj_t *ping) /* {{{ */ buffer_size = 0; ping_iterator_get_info (iter, PING_INFO_DATA, NULL, &buffer_size); +#if USE_NCURSES + context->window = newwin (/* height = */ 4, COLS, + /* start y = */ 4*i, /* start x = */ 0); + box (context->window, 0, 0); + mvwprintw (context->window, /* y = */ 0, /* x = */ 5, + " %s ping statistics ", + context->host); + wrefresh (context->window); +#else /* !USE_NCURSES */ printf ("PING %s (%s) %zu bytes of data.\n", context->host, context->addr, buffer_size); +#endif ping_iterator_set_context (iter, (void *) context); i++; } +#if USE_NCURSES + delwin (main_win); + main_win = newwin (LINES - 4*i, COLS, 4*i, 0); + scrollok (main_win, TRUE); +#endif + return (0); } /* }}} int print_header */ @@ -373,6 +461,10 @@ static int print_footer (pingobj_t *ping) { pingobj_iter_t *iter; +#if USE_NCURSES + endwin (); +#endif + for (iter = ping_iterator_get (ping); iter != NULL; iter = ping_iterator_next (iter)) -- 2.11.0