I had a capture_errs.c but capture-wpcap.c eated it.
[obnox/wireshark/wip.git] / capture_sync.c
index 0e00856d5f9c5ab41148f848bd43a1145b445284..e2f4d7dcb55388a1affdb574b6f384d78e65e046 100644 (file)
@@ -133,8 +133,7 @@ sync_pipe_add_arg(const char **args, int *argc, const char *arg)
 
     /* Stuff the pointer into the penultimate element of the array, which
        is the one at the index specified by "*argc". */
-    args[*argc] = arg;
-
+    args[*argc] = g_strdup(arg);
     /* Now bump the count. */
     (*argc)++;
 
@@ -361,7 +360,6 @@ sync_pipe_start(capture_options *capture_opts) {
     int i;
     guint j;
     interface_options interface_opts;
-    gboolean no_ifaces;
 
     if (capture_opts->ifaces->len > 1)
         capture_opts->use_pcapng = TRUE;
@@ -428,57 +426,6 @@ sync_pipe_start(capture_options *capture_opts) {
         g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
         argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
     }
-    if (capture_opts->ifaces->len == 0) {
-        no_ifaces = TRUE;
-        interface_opts.name = g_strdup(capture_opts->iface);
-        if (capture_opts->iface_descr) {
-            interface_opts.descr = g_strdup(capture_opts->iface_descr);
-        } else {
-            interface_opts.descr = NULL;
-        }
-        interface_opts.cfilter = g_strdup(capture_opts->cfilter);
-        interface_opts.snaplen = capture_opts->snaplen;
-        interface_opts.linktype = capture_opts->linktype;
-        interface_opts.promisc_mode = capture_opts->promisc_mode;
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-        interface_opts.buffer_size = capture_opts->buffer_size;
-#endif
-        interface_opts.monitor_mode = capture_opts->monitor_mode;
-#ifdef HAVE_PCAP_REMOTE
-        interface_opts.src_type = capture_opts->src_type;
-        if (capture_opts->remote_host) {
-            interface_opts.remote_host = g_strdup(capture_opts->remote_host);
-        } else {
-            interface_opts.remote_host = NULL;
-        }
-        if (capture_opts->remote_port) {
-            interface_opts.remote_port = g_strdup(capture_opts->remote_port);
-        } else {
-            interface_opts.remote_port = NULL;
-        }
-        interface_opts.auth_type = capture_opts->auth_type;
-        if (capture_opts->auth_username) {
-            interface_opts.auth_username = g_strdup(capture_opts->auth_username);
-        } else {
-            interface_opts.auth_username = NULL;
-        }
-        if (capture_opts->auth_password) {
-            interface_opts.auth_password = g_strdup(capture_opts->auth_password);
-        } else {
-            interface_opts.auth_password = NULL;
-        }
-        interface_opts.datatx_udp = capture_opts->datatx_udp;
-        interface_opts.nocap_rpcap = capture_opts->nocap_rpcap;
-        interface_opts.nocap_local = capture_opts->nocap_local;
-#endif
-#ifdef HAVE_PCAP_SETSAMPLING
-        interface_opts.sampling_method = capture_opts->sampling_method;
-        interface_opts.sampling_param  = capture_opts->sampling_param;
-#endif
-        g_array_append_val(capture_opts->ifaces, interface_opts);
-    } else {
-        no_ifaces = FALSE;
-    }
 
     for (j = 0; j < capture_opts->ifaces->len; j++) {
         interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
@@ -490,7 +437,6 @@ sync_pipe_start(capture_options *capture_opts) {
             argv = sync_pipe_add_arg(argv, &argc, "-f");
             argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
         }
-
         if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
             argv = sync_pipe_add_arg(argv, &argc, "-s");
             g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
@@ -547,9 +493,6 @@ sync_pipe_start(capture_options *capture_opts) {
         }
 #endif
     }
-    if (no_ifaces) {
-        capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
-    }
 
     /* dumpcap should be running in capture child mode (hidden feature) */
 #ifndef DEBUG_CHILD
@@ -582,7 +525,9 @@ sync_pipe_start(capture_options *capture_opts) {
         /* Couldn't create the pipe between parent and child. */
         report_failure("Couldn't create sync pipe: %s",
                        win32strerror(GetLastError()));
-        g_free( (gpointer) argv[0]);
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return FALSE;
     }
@@ -597,7 +542,9 @@ sync_pipe_start(capture_options *capture_opts) {
         /* Couldn't create the signal pipe between parent and child. */
         report_failure("Couldn't create signal pipe: %s",
                        win32strerror(GetLastError()));
-        g_free( (gpointer) argv[0]);
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return FALSE;
     }
@@ -634,7 +581,9 @@ sync_pipe_start(capture_options *capture_opts) {
                        args->str, win32strerror(GetLastError()));
         CloseHandle(sync_pipe_read);
         CloseHandle(sync_pipe_write);
-        g_free( (gpointer) argv[0]);
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return FALSE;
     }
@@ -651,8 +600,10 @@ sync_pipe_start(capture_options *capture_opts) {
 #else /* _WIN32 */
     if (pipe(sync_pipe) < 0) {
         /* Couldn't create the pipe between parent and child. */
-        report_failure("Couldn't create sync pipe: %s", strerror(errno));
-        g_free( (gpointer) argv[0]);
+        report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free(argv);
         return FALSE;
     }
@@ -666,7 +617,7 @@ sync_pipe_start(capture_options *capture_opts) {
         ws_close(sync_pipe[PIPE_READ]);
         execv(argv[0], (gpointer)argv);
         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
-                   argv[0], strerror(errno));
+                   argv[0], g_strerror(errno));
         sync_pipe_errmsg_to_parent(2, errmsg, "");
 
         /* Exit with "_exit()", so that we don't close the connection
@@ -682,7 +633,9 @@ sync_pipe_start(capture_options *capture_opts) {
     sync_pipe_read_fd = sync_pipe[PIPE_READ];
 #endif
 
-    g_free( (gpointer) argv[0]);  /* exename */
+    for (i = 0; i < argc; i++) {
+        g_free( (gpointer) argv[i]);
+    }
 
     /* Parent process - read messages from the child process over the
        sync pipe. */
@@ -700,7 +653,7 @@ sync_pipe_start(capture_options *capture_opts) {
 
     if (capture_opts->fork_child == -1) {
         /* We couldn't even create the child process. */
-        report_failure("Couldn't create child process: %s", strerror(errno));
+        report_failure("Couldn't create child process: %s", g_strerror(errno));
         ws_close(sync_pipe_read_fd);
 #ifdef _WIN32
         ws_close(capture_opts->signal_pipe_write_fd);
@@ -753,13 +706,12 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
     SECURITY_ATTRIBUTES sa;
     STARTUPINFO si;
     PROCESS_INFORMATION pi;
-    int i;
 #else
     char errmsg[1024+1];
     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
     int data_pipe[2];                       /* pipe used to send data from child to parent */
 #endif
-
+    int i;
     *fork_child = -1;
     *data_read_fd = -1;
     *message_read_fd = -1;
@@ -785,7 +737,9 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
         /* Couldn't create the message pipe between parent and child. */
         *msg = g_strdup_printf("Couldn't create sync pipe: %s",
                                win32strerror(GetLastError()));
-        g_free( (gpointer) argv[0]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return -1;
     }
@@ -798,7 +752,9 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
                                win32strerror(GetLastError()));
         CloseHandle(sync_pipe[PIPE_READ]);
         CloseHandle(sync_pipe[PIPE_WRITE]);
-        g_free( (gpointer) argv[0]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return -1;
     }
@@ -836,7 +792,9 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
         CloseHandle(data_pipe[PIPE_WRITE]);
         CloseHandle(sync_pipe[PIPE_READ]);
         CloseHandle(sync_pipe[PIPE_WRITE]);
-        g_free( (gpointer) argv[0]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free( (gpointer) argv);
         return -1;
     }
@@ -851,8 +809,10 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
     /* Create a pipe for the child process to send us messages */
     if (pipe(sync_pipe) < 0) {
         /* Couldn't create the message pipe between parent and child. */
-        *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
-        g_free( (gpointer) argv[0]);
+        *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free(argv);
         return -1;
     }
@@ -860,10 +820,12 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
     /* Create a pipe for the child process to send us data */
     if (pipe(data_pipe) < 0) {
         /* Couldn't create the data pipe between parent and child. */
-        *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
+        *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
         ws_close(sync_pipe[PIPE_READ]);
         ws_close(sync_pipe[PIPE_WRITE]);
-        g_free( (gpointer) argv[0]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
         g_free(argv);
         return -1;
     }
@@ -881,7 +843,7 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
         ws_close(sync_pipe[PIPE_WRITE]);
         execv(argv[0], (gpointer)argv);
         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
-                   argv[0], strerror(errno));
+                   argv[0], g_strerror(errno));
         sync_pipe_errmsg_to_parent(2, errmsg, "");
 
         /* Exit with "_exit()", so that we don't close the connection
@@ -898,7 +860,9 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
     *message_read_fd = sync_pipe[PIPE_READ];
 #endif
 
-    g_free( (gpointer) argv[0]);  /* exename */
+    for (i = 0; argv[i] != NULL; i++) {
+        g_free( (gpointer) argv[i]);
+    }
 
     /* Parent process - read messages from the child process over the
        sync pipe. */
@@ -918,7 +882,7 @@ sync_pipe_open_command(const char** argv, int *data_read_fd,
 
     if (*fork_child == -1) {
         /* We couldn't even create the child process. */
-        *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
+        *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
         ws_close(*data_read_fd);
         ws_close(*message_read_fd);
         return -1;
@@ -1408,9 +1372,9 @@ pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
             error = errno;
             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
                   "read from pipe %d: error(%u): %s", pipe_fd, error,
-                  strerror(error));
+                  g_strerror(error));
             *msg = g_strdup_printf("Error reading from sync pipe: %s",
-                                   strerror(error));
+                                   g_strerror(error));
             return newly;
         }
 
@@ -1469,7 +1433,7 @@ sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
         } else if (newly < 0) {
             /* error */
             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
-                  "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
+                  "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
             return newly;
         } else if (bytes[offset] == '\n') {
             break;
@@ -1648,12 +1612,22 @@ sync_pipe_input_cb(gint source, gpointer user_data)
                alerted. Close the sync pipe. */
             ws_close(source);
 
-            /* the child has send us a filename which we couldn't open.
-               this probably means, the child is creating files faster than we can handle it.
-               this should only be the case for very fast file switches
-               we can't do much more than telling the child to stop
-               (this is the "emergency brake" if user e.g. wants to switch files every second) */
+            /* The child has sent us a filename which we couldn't open.
+
+               This could mean that the child is creating files faster
+              than we can handle it.  (XXX - why would that result in
+              a failure to open the file?)
+
+               That should only be the case for very fast file switches;
+               We can't do much more than telling the child to stop.
+               (This is the "emergency brake" if the user e.g. wants to
+              switch files every second).
+
+               This can also happen if the user specified "-", meaning
+               "standard output", as the capture file. */
             sync_pipe_stop(capture_opts);
+            capture_input_closed(capture_opts, NULL);
+            return FALSE;
         }
         break;
     case SP_PACKET_COUNT:
@@ -1673,10 +1647,17 @@ sync_pipe_input_cb(gint source, gpointer user_data)
         /* the capture child will close the sync_pipe, nothing to do for now */
         /* (an error message doesn't mean we have to stop capturing) */
         break;
-    case SP_BAD_FILTER:
-        capture_input_cfilter_error_message(capture_opts, buffer);
-        /* the capture child will close the sync_pipe, nothing to do for now */
-        break;
+    case SP_BAD_FILTER: {
+        char *ch;
+        int index;
+
+        ch = strtok(buffer, ":");
+        index = (int)strtol(ch, NULL, 10);
+        ch = strtok(NULL, ":");
+        capture_input_cfilter_error_message(capture_opts, index, ch);
+         /* the capture child will close the sync_pipe, nothing to do for now */
+         break;
+        }
     case SP_DROPS:
         capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
         break;
@@ -1700,10 +1681,9 @@ sync_pipe_wait_for_child(int fork_child, gchar **msgp)
     g_assert(fork_child != -1);
 
     *msgp = NULL; /* assume no error */
-    ret = 0;
 #ifdef _WIN32
     if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
-        *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
+        *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
         ret = -1;
     } else {
         /*
@@ -1745,7 +1725,7 @@ sync_pipe_wait_for_child(int fork_child, gchar **msgp)
             ret = -1;
         }
     } else {
-        *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
+        *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
         ret = -1;
     }
 #endif
@@ -1869,7 +1849,7 @@ signal_pipe_capquit_to_child(capture_options *capture_opts)
     ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
     if(ret == -1) {
         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
-              "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
+              "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, g_strerror(errno));
     }
 }
 #endif
@@ -1891,7 +1871,7 @@ sync_pipe_stop(capture_options *capture_opts)
         int sts = kill(capture_opts->fork_child, SIGINT);
         if (sts != 0) {
             g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
-                  "Sending SIGINT to child failed: %s\n", strerror(errno));
+                  "Sending SIGINT to child failed: %s\n", g_strerror(errno));
         }
 #else
 #define STOP_SLEEP_TIME 500 /* ms */
@@ -1931,7 +1911,7 @@ sync_pipe_kill(int fork_child)
         int sts = kill(fork_child, SIGTERM);    /* SIGTERM so it can clean up if necessary */
         if (sts != 0) {
             g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
-                  "Sending SIGTERM to child failed: %s\n", strerror(errno));
+                  "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
         }
 #else
         /* Remark: This is not the preferred method of closing a process!