Code

src/oping.c: Implement the "-O" option.
[liboping.git] / src / oping.c
index 53602d3c53feeb87cdd2682c3748ba4133e3a248..94515c2c2005fe7300ebd2e57cb920d5da7fec99 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Object oriented C module to send ICMP and ICMPv6 `echo's.
- * Copyright (C) 2006-2014  Florian octo Forster <ff at octo.it>
+ * Copyright (C) 2006-2016  Florian octo Forster <ff at octo.it>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -208,8 +208,10 @@ static double  opt_exit_status_threshold = 1.0;
 static int     opt_show_graph = 1;
 static int     opt_utf8       = 0;
 #endif
+static char   *opt_outfile    = NULL;
 
-static int host_num = 0;
+static int host_num  = 0;
+static FILE *outfile = NULL;
 
 #if USE_NCURSES
 static WINDOW *main_win = NULL;
@@ -439,7 +441,8 @@ static void usage_exit (const char *name, int status) /* {{{ */
                        "  -I srcaddr   source address\n"
                        "  -D device    outgoing interface name\n"
                        "  -m mark      mark to set on outgoing packets\n"
-                       "  -f filename  filename to read hosts from\n"
+                       "  -f filename  read hosts from <filename>\n"
+                       "  -O filename  write RTT measurements to <filename>\n"
 #if USE_NCURSES
                        "  -u / -U      force / disable UTF-8 output\n"
                        "  -g graph     graph type to draw\n"
@@ -649,7 +652,7 @@ static int read_options (int argc, char **argv) /* {{{ */
 
        while (1)
        {
-               optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:P:m:w:"
+               optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:O:P:m:w:"
 #if USE_NCURSES
                                "uUg:"
 #endif
@@ -746,6 +749,12 @@ static int read_options (int argc, char **argv) /* {{{ */
                                set_opt_send_qos (optarg);
                                break;
 
+                       case 'O':
+                               {
+                                       free (opt_outfile);
+                                       opt_outfile = strdup (optarg);
+                               }
+
                        case 'P':
                                {
                                        double new_percentile;
@@ -1591,6 +1600,21 @@ static void update_host_hook (pingobj_iter_t *iter, /* {{{ */
 #endif
        }
 
+       if (outfile != NULL)
+       {
+               struct timespec ts = { 0, 0 };
+
+               if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
+               {
+                       double t = ((double) ts.tv_sec) + (((double) ts.tv_nsec) / 1000000.0);
+
+                       if ((sequence % 32) == 0)
+                               fprintf (outfile, "#time,host,latency[ms]\n");
+
+                       fprintf (outfile, "%.3f \"%s\" %.2f\n", t, context->host, latency);
+               }
+       }
+
 #if USE_NCURSES
        update_stats_from_context (context, iter);
        wrefresh (main_win);
@@ -1890,6 +1914,17 @@ int main (int argc, char **argv) /* {{{ */
        saved_set_uid = (uid_t) -1;
 #endif
 
+       if (opt_outfile != NULL)
+       {
+               outfile = fopen (opt_outfile, "a");
+               if (outfile == NULL)
+               {
+                       fprintf (stderr, "opening \"%s\" failed: %s\n",
+                                opt_outfile, strerror (errno));
+                       exit (EXIT_FAILURE);
+               }
+       }
+
        ping_initialize_contexts (ping);
 
        if (i == 0)
@@ -1976,6 +2011,12 @@ int main (int argc, char **argv) /* {{{ */
 
        ping_destroy (ping);
 
+       if (outfile != NULL)
+       {
+               fclose (outfile);
+               outfile = NULL;
+       }
+
        if (status == 0)
                exit (EXIT_SUCCESS);
        else