dinfo->switch_level
[metze/wireshark/wip.git] / capture_opts.c
index 92a5e1cea85c0b80b21e8d0eabd3720f53a33c42..40df74d7dc37e0ebbc6f870d8c6ec2bfc378f63e 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #ifdef HAVE_LIBPCAP
 
 #include <string.h>
@@ -59,8 +63,11 @@ capture_opts_init(capture_options *capture_opts)
     capture_opts->default_options.extcap          = NULL;
     capture_opts->default_options.extcap_fifo     = NULL;
     capture_opts->default_options.extcap_args     = NULL;
-    capture_opts->default_options.extcap_pipedata = NULL;
     capture_opts->default_options.extcap_pid      = WS_INVALID_PID;
+    capture_opts->default_options.extcap_pipedata = NULL;
+    capture_opts->default_options.extcap_stderr   = NULL;
+    capture_opts->default_options.extcap_stdout_watch = 0;
+    capture_opts->default_options.extcap_stderr_watch = 0;
 #ifdef _WIN32
     capture_opts->default_options.extcap_pipe_h   = INVALID_HANDLE_VALUE;
     capture_opts->default_options.extcap_control_in_h  = INVALID_HANDLE_VALUE;
@@ -112,6 +119,8 @@ capture_opts_init(capture_options *capture_opts)
     capture_opts->autostop_files                  = 1;
     capture_opts->has_autostop_packets            = FALSE;
     capture_opts->autostop_packets                = 0;
+    capture_opts->has_autostop_written_packets    = FALSE;
+    capture_opts->autostop_written_packets        = 0;
     capture_opts->has_autostop_filesize           = FALSE;
     capture_opts->autostop_filesize               = 1000;             /* 1 MB */
     capture_opts->has_autostop_duration           = FALSE;
@@ -119,9 +128,14 @@ capture_opts_init(capture_options *capture_opts)
 
     capture_opts->output_to_pipe                  = FALSE;
     capture_opts->capture_child                   = FALSE;
+    capture_opts->stop_after_extcaps              = FALSE;
+    capture_opts->wait_for_extcap_cbs             = FALSE;
     capture_opts->print_file_names                = FALSE;
     capture_opts->print_name_to                   = NULL;
+    capture_opts->temp_dir                        = NULL;
     capture_opts->compress_type                   = NULL;
+    capture_opts->closed_msg                      = NULL;
+    capture_opts->extcap_terminate_id             = 0;
 }
 
 void
@@ -147,6 +161,16 @@ capture_opts_cleanup(capture_options *capture_opts)
         capture_opts->all_ifaces = NULL;
     }
     g_free(capture_opts->save_file);
+    g_free(capture_opts->temp_dir);
+
+    if (capture_opts->closed_msg) {
+        g_free(capture_opts->closed_msg);
+        capture_opts->closed_msg = NULL;
+    }
+    if (capture_opts->extcap_terminate_id > 0) {
+        g_source_remove(capture_opts->extcap_terminate_id);
+        capture_opts->extcap_terminate_id = 0;
+    }
 }
 
 /* log content of capture_opts */
@@ -170,7 +194,7 @@ capture_opts_log(const char *log_domain, enum ws_log_level log_level, capture_op
         ws_log(log_domain, log_level, "Promiscuous Mode[%02d]: %s", i, interface_opts->promisc_mode?"TRUE":"FALSE");
         ws_log(log_domain, log_level, "Extcap[%02d]          : %s", i, interface_opts->extcap ? interface_opts->extcap : "(unspecified)");
         ws_log(log_domain, log_level, "Extcap FIFO[%02d]     : %s", i, interface_opts->extcap_fifo ? interface_opts->extcap_fifo : "(unspecified)");
-        ws_log(log_domain, log_level, "Extcap PID[%02d]      : %d", i, interface_opts->extcap_pid);
+        ws_log(log_domain, log_level, "Extcap PID[%02d]      : %"PRIdMAX, i, (intmax_t)interface_opts->extcap_pid);
 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
         ws_log(log_domain, log_level, "Buffer size[%02d]     : %d (MB)", i, interface_opts->buffer_size);
 #endif
@@ -259,8 +283,10 @@ capture_opts_log(const char *log_domain, enum ws_log_level log_level, capture_op
 
     ws_log(log_domain, log_level, "AutostopFiles   (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
     ws_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
+    ws_log(log_domain, log_level, "AutostopWrittenPackets (%u) : %u", capture_opts->has_autostop_written_packets, capture_opts->autostop_written_packets);
     ws_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
     ws_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
+    ws_log(log_domain, log_level, "Temporary Directory  : %s", capture_opts->temp_dir && capture_opts->temp_dir[0] ? capture_opts->temp_dir : g_get_tmp_dir());
 }
 
 /*
@@ -308,8 +334,8 @@ set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
         capture_opts->has_autostop_files = TRUE;
         capture_opts->autostop_files = get_positive_int(p,"autostop files");
     } else if (strcmp(autostoparg,"packets") == 0) {
-        capture_opts->has_autostop_packets = TRUE;
-        capture_opts->autostop_packets = get_positive_int(p,"packet count");
+        capture_opts->has_autostop_written_packets = TRUE;
+        capture_opts->autostop_written_packets = get_positive_int(p,"packet write count");
     } else {
         return FALSE;
     }
@@ -763,6 +789,9 @@ capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str
     interface_opts.extcap_args = NULL;
     interface_opts.extcap_pid = WS_INVALID_PID;
     interface_opts.extcap_pipedata = NULL;
+    interface_opts.extcap_stderr = NULL;
+    interface_opts.extcap_stdout_watch = 0;
+    interface_opts.extcap_stderr_watch = 0;
 #ifdef _WIN32
     interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
     interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;
@@ -801,6 +830,7 @@ int
 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p)
 {
     int status, snaplen;
+    ws_statb64 fstat;
 
     switch(opt) {
     case 'a':        /* autostop criteria */
@@ -1002,6 +1032,30 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
         }
         capture_opts->compress_type = g_strdup(optarg_str_p);
         break;
+    case LONGOPT_CAPTURE_TMPDIR:  /* capture temporary directory */
+        if (capture_opts->temp_dir) {
+            cmdarg_err("--temp-dir can be set only once");
+            return 1;
+        }
+        if (ws_stat64(optarg_str_p, &fstat) < 0) {
+            cmdarg_err("Can't set temporary directory %s: %s",
+                    optarg_str_p, g_strerror(errno));
+            return 1;
+        }
+        if (!S_ISDIR(fstat.st_mode)) {
+            cmdarg_err("Can't set temporary directory %s: not a directory",
+                    optarg_str_p);
+            return 1;
+        }
+#ifdef S_IRWXU
+        if ((fstat.st_mode & S_IRWXU) != S_IRWXU) {
+            cmdarg_err("Can't set temporary directory %s: not a writable directory",
+                    optarg_str_p);
+            return 1;
+        }
+#endif /* S_IRWXU */
+        capture_opts->temp_dir = g_strdup(optarg_str_p);
+        break;
     default:
         /* the caller is responsible to send us only the right opt's */
         ws_assert_not_reached();
@@ -1237,8 +1291,10 @@ capture_opts_del_iface(capture_options *capture_opts, guint if_index)
     if (interface_opts->extcap_args)
         g_hash_table_unref(interface_opts->extcap_args);
     if (interface_opts->extcap_pid != WS_INVALID_PID)
-        ws_pipe_close((ws_pipe_t *) interface_opts->extcap_pipedata);
+        ws_warning("Extcap still running during interface delete");
     g_free(interface_opts->extcap_pipedata);
+    if (interface_opts->extcap_stderr)
+        g_string_free(interface_opts->extcap_stderr, TRUE);
     g_free(interface_opts->extcap_control_in);
     g_free(interface_opts->extcap_control_out);
 #ifdef HAVE_PCAP_REMOTE
@@ -1272,7 +1328,7 @@ collect_ifaces(capture_options *capture_opts)
     /* Now fill the list up again. */
     for (i = 0; i < capture_opts->all_ifaces->len; i++) {
         device = &g_array_index(capture_opts->all_ifaces, interface_t, i);
-        if (!device->hidden && device->selected) {
+        if (device->selected) {
             interface_opts.name = g_strdup(device->name);
             interface_opts.descr = g_strdup(device->friendly_name);
             interface_opts.ifname = NULL;
@@ -1293,6 +1349,7 @@ collect_ifaces(capture_options *capture_opts)
             if (interface_opts.extcap_args)
                 g_hash_table_ref(interface_opts.extcap_args);
             interface_opts.extcap_pipedata = NULL;
+            interface_opts.extcap_stderr = NULL;
 #ifdef _WIN32
             interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
             interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;