Fix dist.
[obnox/wireshark/wip.git] / dumpcap.c
index 63a52ce0c6f2a2a31d48e8f8a40fc3009de8b34b..9a540407c8bf6f5f8f8f99a843b8659a68f0eea3 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -25,6 +25,7 @@
 # include "config.h"
 #endif
 
+#include <stdlib.h> /* for exit() */
 #include <glib.h>
 
 #include <string.h>
@@ -97,7 +98,7 @@ print_usage(gboolean print_ver) {
         "Dumpcap " VERSION "%s\n"
         "Capture network packets and dump them into a libpcap file.\n"
         "See http://www.wireshark.org for more information.\n",
-        svnversion);
+        wireshark_svnversion);
   } else {
     output = stderr;
   }
@@ -114,6 +115,7 @@ print_usage(gboolean print_ver) {
   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
   fprintf(output, "  -D                       print list of interfaces and exit\n");
   fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
+  fprintf(output, "  -I [l|s]                 print a detailed interface list (l) or interface statistics (s).\n");
   fprintf(output, "\n");
   fprintf(output, "Stop conditions:\n");
   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
@@ -148,7 +150,7 @@ show_version(GString *comp_info_str, GString *runtime_info_str)
         "%s\n"
         "%s\n"
         "See http://www.wireshark.org for more information.\n",
-        svnversion, get_copyright_info() ,comp_info_str->str, runtime_info_str->str);
+        wireshark_svnversion, get_copyright_info() ,comp_info_str->str, runtime_info_str->str);
 }
 
 /*
@@ -160,7 +162,10 @@ cmdarg_err(const char *fmt, ...)
   va_list ap;
 
   if(capture_child) {
-    /* XXX - convert to g_log */
+    /* Print a bare error */
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
   } else {
     va_start(ap, fmt);
     fprintf(stderr, "dumpcap: ");
@@ -232,8 +237,6 @@ main(int argc, char *argv[])
   int                  opt;
   extern char         *optarg;
   gboolean             arg_error = FALSE;
-  GString             *comp_info_str;
-  GString             *runtime_info_str;
 
 #ifdef _WIN32
   WSADATA              wsaData;
@@ -246,7 +249,7 @@ main(int argc, char *argv[])
   gboolean             list_link_layer_types = FALSE;
   int                  status;
 
-#define OPTSTRING_INIT "a:b:c:Df:hi:Lps:vw:y:Z"
+#define OPTSTRING_INIT "a:b:c:Df:hI:i:Lps:vw:y:Z"
 
 #ifdef _WIN32
 #define OPTSTRING_WIN32 "B:"
@@ -272,18 +275,11 @@ main(int argc, char *argv[])
   SetConsoleCtrlHandler(&ConsoleCtrlHandlerRoutine, TRUE);
 #endif  /* _WIN32 */
 
-  /* Assemble the compile-time version information string */
-  comp_info_str = g_string_new("Compiled ");
-  get_compiled_version_info(comp_info_str, NULL);
-
-  /* Assemble the run-time version information string */
-  runtime_info_str = g_string_new("Running ");
-  get_runtime_version_info(runtime_info_str, NULL);
 
   /* the default_log_handler will use stdout, which makes trouble in */
   /* capture child mode, as it uses stdout for it's sync_pipe */
   /* so do the filtering in the console_log_handler and not here */
-  log_flags = 
+  log_flags =
                    G_LOG_LEVEL_ERROR|
                    G_LOG_LEVEL_CRITICAL|
                    G_LOG_LEVEL_WARNING|
@@ -305,7 +301,7 @@ main(int argc, char *argv[])
                    log_flags,
             console_log_handler, NULL /* user_data */);
 
-  /* Set the initial values in the capture_opts. This might be overwritten 
+  /* Set the initial values in the capture_opts. This might be overwritten
      by the command line parameters. */
   capture_opts_init(capture_opts, NULL);
 
@@ -325,9 +321,22 @@ main(int argc, char *argv[])
         exit_main(0);
         break;
       case 'v':        /* Show version and exit */
+      {
+        GString             *comp_info_str;
+        GString             *runtime_info_str;
+        /* Assemble the compile-time version information string */
+        comp_info_str = g_string_new("Compiled with ");
+        get_compiled_version_info(comp_info_str, NULL);
+
+        /* Assemble the run-time version information string */
+        runtime_info_str = g_string_new("Running ");
+        get_runtime_version_info(runtime_info_str, NULL);
         show_version(comp_info_str, runtime_info_str);
+        g_string_free(comp_info_str, TRUE);
+        g_string_free(runtime_info_str, TRUE);
         exit_main(0);
         break;
+      }
       /*** capture option specific ***/
       case 'a':        /* autostop criteria */
       case 'b':        /* Ringbuffer option */
@@ -357,9 +366,15 @@ main(int argc, char *argv[])
 
       /*** all non capture option specific ***/
       case 'D':        /* Print a list of capture devices and exit */
-        status = capture_opts_list_interfaces();
+        status = capture_opts_list_interfaces(FALSE);
         exit_main(status);
         break;
+      /* XXX - We might want to use 'D' for this.  Do we use GNU
+       * getopt on every platform (which supports optional arguments)? */
+      /* XXX - Implement interface stats */
+      case 'I':
+        status = capture_opts_list_interfaces(TRUE);
+        exit_main(status);
       case 'L':        /* Print list of link-layer types and exit */
         list_link_layer_types = TRUE;
         break;
@@ -468,7 +483,7 @@ console_log_handler(const char *log_domain, GLogLevelFlags log_level,
 
   /* create a "timestamp" */
   time(&curr);
-  today = localtime(&curr);    
+  today = localtime(&curr);
 
   switch(log_level & G_LOG_LEVEL_MASK) {
   case G_LOG_LEVEL_ERROR:
@@ -521,7 +536,6 @@ report_packet_count(int packet_count)
     char tmp[SP_DECISIZE+1+1];
     static int count = 0;
 
-
     if(capture_child) {
         g_snprintf(tmp, sizeof(tmp), "%d", packet_count);
         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Packets: %s", tmp);
@@ -537,36 +551,43 @@ report_packet_count(int packet_count)
 void
 report_new_capture_file(const char *filename)
 {
-
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "File: %s", filename);
-
     if(capture_child) {
+        g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "File: %s", filename);
         pipe_write_block(1, SP_FILE, filename);
+    } else {
+        fprintf(stderr, "File: %s\n", filename);
+        /* stderr could be line buffered */
+        fflush(stderr);
     }
 }
 
 void
-report_cfilter_error(const char *cfilter _U_, const char *errmsg)
+report_cfilter_error(const char *cfilter, const char *errmsg)
 {
-
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Capture filter error: %s", errmsg);
-
     if (capture_child) {
+        g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Capture filter error: %s", errmsg);
         pipe_write_block(1, SP_BAD_FILTER, errmsg);
+    } else {
+        fprintf(stderr,
+          "Invalid capture filter: \"%s\"!\n"
+          "\n"
+          "That string isn't a valid capture filter (%s).\n"
+          "See the User's Guide for a description of the capture filter syntax.\n",
+          cfilter, errmsg);
     }
 }
 
 void
 report_capture_error(const char *error_msg, const char *secondary_error_msg)
 {
-
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, 
-        "Primary Error: %s", error_msg);
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, 
-        "Secondary Error: %s", secondary_error_msg);
-
     if(capture_child) {
+        g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
+            "Primary Error: %s", error_msg);
+        g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
+            "Secondary Error: %s", secondary_error_msg);
        sync_pipe_errmsg_to_parent(error_msg, secondary_error_msg);
+    } else {
+        fprintf(stderr, "%s\n%s\n", error_msg, secondary_error_msg);
     }
 }
 
@@ -575,12 +596,15 @@ report_packet_drops(int drops)
 {
     char tmp[SP_DECISIZE+1+1];
 
-
     g_snprintf(tmp, sizeof(tmp), "%d", drops);
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Packets dropped: %s", tmp);
 
     if(capture_child) {
+        g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Packets dropped: %s", tmp);
         pipe_write_block(1, SP_DROPS, tmp);
+    } else {
+        fprintf(stderr, "Packets dropped: %s\n", tmp);
+        /* stderr could be line buffered */
+        fflush(stderr);
     }
 }