the point of no return ...
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 11 Feb 2006 23:25:11 +0000 (23:25 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 11 Feb 2006 23:25:11 +0000 (23:25 +0000)
using dumpcap as the capture child for Ethereal.

dumpcap is a plain console application now, even for Win32 (so no WinMain, create_console and special piping stuff reguired). The undocumented command line option -Z will switch dumpcap into "child mode", using binary instead of plain text output messages to communicate with a parent Ethereal.

Ethereal's main.c no longer needs to distinguish between child mode or not, so some simplifying here.

capture_sync.c has to call dumpcap in a "hidden window" mode using CreateProcess instead of spawnvp, otherwise an uggly console window would appear. The handles created by _pipe doesn't seem to be inheritable for this function, using CreatePipe instead.

The file capture_loop.c is only needed by dumpcap, removed from Ethereal link objects.

Some debugging aid added and other minor cleanup done.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@17256 f5534014-38df-0310-8fa8-9805f1628bb7

Makefile.common
capture_loop.c
capture_opts.c
capture_opts.h
capture_sync.c
capture_sync.h
dumpcap.c
gtk/main.c

index a6f5c7954c66b45d15a93102b633c33f7c829100..27f542b5de89240a8cd5a9ccddf3fc8dff1d278e 100644 (file)
@@ -136,7 +136,6 @@ ethereal_SOURCES =  \
        alert_box.c     \
        capture.c       \
        capture_info.c  \
-       capture_loop.c  \
        capture_opts.c \
        capture_sync.c  \
        color_filters.c \
index 58745e7c12ea1ac41b61cdd882f350ad7c634c09..3ae13f04927cd57fa4a32c46fdd032feeda9f256 100644 (file)
@@ -1100,19 +1100,22 @@ capture_loop_stop_signal_handler(int signo _U_)
 static gboolean
 signal_pipe_stopped(void)
 {
-    /* some news from our parent (signal pipe)? -> just stop the capture */
+    /* any news from our parent (stdin)? -> just stop the capture */
     HANDLE handle;
     DWORD avail = 0;
     gboolean result;
 
 
-    handle = (HANDLE) _get_osfhandle (0);
+    handle = (HANDLE) GetStdHandle(STD_INPUT_HANDLE);
     result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
 
-    /*g_warning("check pipe: handle: %x result: %u avail: %u", handle, result, avail);*/
-
     if(!result || avail > 0) {
         /* peek failed or some bytes really available */
+
+        /* XXX - if not piping from stdin this fails */
+        /*g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
+            "Signal pipe: handle: %x result: %u avail: %u", handle, result, avail);
+        return FALSE;*/
         return TRUE;
     } else {
         /* pipe ok and no bytes available */
@@ -1247,10 +1250,10 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
     inpkts = capture_loop_dispatch(capture_opts, &ld, errmsg, sizeof(errmsg));
 
 #ifdef _WIN32
-    /*fprintf(stderr, "fd: %u ret: %u\n", capture_opts->signal_pipe_fd, signal_pipe_stopped());*/
+    /*fprintf(stderr, "signal pipe ret: %u\n", signal_pipe_stopped());*/
 
     /* any news from our parent (signal pipe)? -> just stop the capture */
-    if (capture_opts->signal_pipe_fd != -1 && signal_pipe_stopped()) {
+    if (signal_pipe_stopped()) {
       ld.go = FALSE;
     }
 #endif
index 6c451458a17d58f555614217d9e4ecbe9643c516..a893ff6f9b609b33ad5bdf8efaeb975dc1f1b599 100644 (file)
@@ -89,7 +89,7 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
 
   capture_opts->fork_child              = -1;               /* invalid process handle */
 #ifdef _WIN32
-  capture_opts->signal_pipe_fd          = -1;
+  capture_opts->signal_pipe_write_fd    = -1;
 #endif
   capture_opts->state                   = CAPTURE_STOPPED;
   capture_opts->output_to_pipe          = FALSE;
@@ -125,7 +125,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
 
     g_log(log_domain, log_level, "ForkChild          : %d", capture_opts->fork_child);
 #ifdef _WIN32
-    g_log(log_domain, log_level, "SignalPipeFd       : %d", capture_opts->signal_pipe_fd);
+    g_log(log_domain, log_level, "SignalPipeWrite    : %d", capture_opts->signal_pipe_write_fd);
 #endif
 }
 
@@ -231,67 +231,6 @@ get_ring_arguments(capture_options *capture_opts, const char *arg)
 }
 
 
-#ifdef _WIN32
-/*
- * Given a string of the form "<pipe name>:<file descriptor>", as might appear
- * as an argument to a "-Z" option, parse it and set the arguments in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_pipe_arguments(capture_options *capture_opts, const char *arg)
-{
-  gchar *p = NULL, *colonp;
-  int pipe_fd;
-
-
-  colonp = strchr(arg, ':');
-  if (colonp == NULL)
-    return TRUE;
-
-  p = colonp;
-  *p++ = '\0';
-
-  /*
-   * Skip over any white space (there probably won't be any, but
-   * as we allow it in the preferences file, we might as well
-   * allow it here).
-   */
-  while (isspace((guchar)*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-
-  if (strcmp(arg,"sync") == 0) {
-    /* associate stdout with sync pipe */
-    pipe_fd = get_natural_int(p, "sync pipe file descriptor");
-    if (dup2(pipe_fd, 1) < 0) {
-      cmdarg_err("Unable to dup sync pipe handle");
-      return FALSE;
-    }
-  } else if (strcmp(arg,"signal") == 0) {
-    /* associate stdin with signal pipe */
-    pipe_fd = get_natural_int(p, "signal pipe file descriptor");
-    if (dup2(pipe_fd, 0) < 0) {
-      cmdarg_err("Unable to dup signal pipe handle");
-      return FALSE;
-    }
-    capture_opts->signal_pipe_fd = pipe_fd;
-  }
-
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-#endif
-
-
 static int
 capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg)
 {
@@ -441,15 +380,6 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
         capture_opts->linktype = get_natural_int(optarg, "data link type");
 #endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
         break;
-#ifdef _WIN32
-      /* Hidden option supporting Sync mode */
-    case 'Z':        /* Write to pipe FD XXX */
-       if (get_pipe_arguments(capture_opts, optarg) == FALSE) {
-          cmdarg_err("Invalid or unknown -Z flag \"%s\"", optarg);
-          return 1;
-        }
-        break;
-#endif /* _WIN32 */
     default:
         /* the caller is responsible to send us only the right opt's */
         g_assert_not_reached();
index 178757e2c85104b277481875e83be7f81cb51aff..8c3b85eff4807aa70762359fef7091bd14c08ade 100644 (file)
@@ -91,7 +91,7 @@ typedef struct capture_options_tag {
     /* internally used (don't touch from outside) */
     int fork_child;                /**< If not -1, in parent, process ID of child */
 #ifdef _WIN32
-    int signal_pipe_fd;         /**< the pipe to signal the child */
+    int signal_pipe_write_fd;   /**< the pipe to signal the child */
 #endif
     capture_state state;        /**< current state of the capture engine */
     gboolean output_to_pipe;    /**< save_file is a pipe (named or stdout) */
index 6c9901b92943435d858ca495f71da3bd790de2cc..a6aaac0b52d67237a9f6fed05f0e9802a83bf635 100644 (file)
@@ -153,6 +153,18 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
     /*g_warning("write %d leave", pipe);*/
 }
 
+#ifdef _WIN32
+static void
+signal_pipe_capquit_to_child(capture_options *capture_opts)
+{
+
+    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
+
+    pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
+}
+#endif
+
+
 
 /* read a message from the sending pipe in the standard format 
    (1-byte message indicator, 3-byte message length (excluding length
@@ -195,7 +207,9 @@ pipe_read_block(int pipe, char *indicator, int len, char *msg) {
         return 4;
     }
 
-    g_assert(required <= len);
+    if(required > len) {
+        return -1;
+    }
     len = required;
 
     /* read value */
@@ -216,59 +230,6 @@ pipe_read_block(int pipe, char *indicator, int len, char *msg) {
     return len + 4;
 }
 
-void
-sync_pipe_packet_count_to_parent(int packet_count)
-{
-    char tmp[SP_DECISIZE+1+1];
-
-    g_snprintf(tmp, sizeof(tmp), "%d", packet_count);
-
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_packet_count_to_parent: %s", tmp);
-
-    pipe_write_block(1, SP_PACKET_COUNT, strlen(tmp)+1, tmp);
-}
-
-void
-sync_pipe_filename_to_parent(const char *filename)
-{
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_filename_to_parent: %s", filename);
-
-    pipe_write_block(1, SP_FILE, strlen(filename)+1, filename);
-}
-
-void
-sync_pipe_errmsg_to_parent(const char *errmsg)
-{
-    g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
-
-    pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
-}
-
-void
-sync_pipe_drops_to_parent(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, "sync_pipe_drops_to_parent: %s", tmp);
-
-    pipe_write_block(1, SP_DROPS, strlen(tmp)+1, tmp);
-}
-
-
-#ifdef _WIN32
-
-static void
-signal_pipe_capquit_to_child(capture_options *capture_opts)
-{
-
-    g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
-
-    pipe_write_block(capture_opts->signal_pipe_fd, SP_QUIT, 0, NULL);
-}
-#endif
 
 
 /* Add a string pointer to a NULL-terminated array of string pointers. */
@@ -311,18 +272,27 @@ sync_pipe_start(capture_options *capture_opts) {
     char sautostop_duration[ARGV_NUMBER_LEN];
 #ifdef _WIN32
     char buffer_size[ARGV_NUMBER_LEN];
-    char sync_pipe_fd[ARGV_NUMBER_LEN];
-    char signal_pipe_fd[ARGV_NUMBER_LEN];
     char *filterstring;
     char *savefilestring;
-    int signal_pipe[2];                     /* pipe used to send messages from parent to child (currently only stop) */
+    HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
+    HANDLE sync_pipe_write;                 /* pipe used to send messages from child to parent */
+    HANDLE signal_pipe_read;                /* pipe used to send messages from parent to child (currently only stop) */
+    HANDLE signal_pipe_write;               /* pipe used to send messages from parent to child (currently only stop) */
+    GString *args = g_string_sized_new(200);
+    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 */
+    enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
 #endif
+    int sync_pipe_read_fd;
+    char *dirname;
+    char *exename;
     int argc;
     const char **argv;
-    enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
-    int sync_pipe[2];                       /* pipe used to send messages from child to parent */
 
 
     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
@@ -336,9 +306,6 @@ sync_pipe_start(capture_options *capture_opts) {
     argv = g_malloc(sizeof (char *));
     *argv = NULL;
 
-    /* Now add those arguments used on all platforms. */
-    argv = sync_pipe_add_arg(argv, &argc, CHILD_NAME);
-
     argv = sync_pipe_add_arg(argv, &argc, "-i");
     argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
 
@@ -406,44 +373,21 @@ sync_pipe_start(capture_options *capture_opts) {
     if (!capture_opts->promisc_mode)
       argv = sync_pipe_add_arg(argv, &argc, "-p");
 
-#ifdef _WIN32
-    /* Create a pipe for the child process */
-    /* (inrease this value if you have trouble while fast capture file switches) */
-    if(_pipe(sync_pipe, 5120, O_BINARY) < 0) {
-      /* Couldn't create the pipe between parent and child. */
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
-                        strerror(errno));
-      g_free( (gpointer) argv);
-      return FALSE;
-    }
-
-    /* Create a pipe for the parent process */
-    if(_pipe(signal_pipe, 512, O_BINARY) < 0) {
-      /* Couldn't create the signal pipe between parent and child. */
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
-                        strerror(errno));
-      eth_close(sync_pipe[PIPE_READ]);
-      eth_close(sync_pipe[PIPE_WRITE]);
-      g_free( (gpointer) argv);
-      return FALSE;
-    }
+    /* dumpcap should be running in capture child mode (hidden feature) */
+#ifndef DEBUG_CHILD
+    argv = sync_pipe_add_arg(argv, &argc, "-Z");
+#endif
 
-    capture_opts->signal_pipe_fd = signal_pipe[PIPE_WRITE];
+    /* take ethereal's absolute program path and replace ethereal with dumpcap */
+    dirname = get_dirname(g_strdup(ethereal_path));
+    exename = g_strdup_printf("\"%s" G_DIR_SEPARATOR_S "dumpcap\"", dirname);
+    g_free(dirname);
 
+#ifdef _WIN32
     argv = sync_pipe_add_arg(argv, &argc, "-B");
     g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
     argv = sync_pipe_add_arg(argv, &argc, buffer_size);
 
-    /* Convert sync pipe write handle to a string and pass to child */
-    argv = sync_pipe_add_arg(argv, &argc, "-Z");
-    g_snprintf(sync_pipe_fd, ARGV_NUMBER_LEN, "sync:%d",sync_pipe[PIPE_WRITE]);
-    argv = sync_pipe_add_arg(argv, &argc, sync_pipe_fd);
-
-    /* Convert signal pipe read handle to a string and pass to child */
-    argv = sync_pipe_add_arg(argv, &argc, "-Z");
-    g_snprintf(signal_pipe_fd, ARGV_NUMBER_LEN, "signal:%d",signal_pipe[PIPE_READ]);
-    argv = sync_pipe_add_arg(argv, &argc, signal_pipe_fd);
-
     /* Convert filter string to a quote delimited string and pass to child */
     filterstring = NULL;
     if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
@@ -460,73 +404,74 @@ sync_pipe_start(capture_options *capture_opts) {
       argv = sync_pipe_add_arg(argv, &argc, savefilestring);
     }
 
-    /* Spawn process */
-#if 0
-    {
-        /* XXX - very experimental using dumpcap as the capture child */
-        /* currently not working, the pipe handles seem to make problems ... */
-        char *dirname;
-        GString *args = g_string_sized_new(200);
-        STARTUPINFO si;
-        PROCESS_INFORMATION pi;
-        int i;
-
-        memset(&si, 0, sizeof(si));
-        si.cb           = sizeof(si);
-        si.dwFlags      = STARTF_USESHOWWINDOW;
-        si.wShowWindow  = SW_SHOW /* SW_HIDE */;
-#if 0
-        si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
-        si.hStdInput = signal_pipe[PIPE_READ];
-        si.hStdOutput = sync_pipe[PIPE_WRITE];
-        si.hStdError = stderr;
-#endif
+    /* init SECURITY_ATTRIBUTES */
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
+    sa.bInheritHandle = TRUE; 
+    sa.lpSecurityDescriptor = NULL; 
 
-        /* take the ethereal programs path and replace ethereal with dumpcap */
-        dirname = get_dirname(g_strdup(ethereal_path));
-        g_string_sprintfa(args, "\"%s" G_DIR_SEPARATOR_S "dumpcap\"", dirname);
-        g_free(dirname);
+    /* Create a pipe for the child process */
+    /* (inrease this value if you have trouble while fast capture file switches) */
+    if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
+      /* Couldn't create the pipe between parent and child. */
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
+                        strerror(errno));
+      g_free( (gpointer) argv);
+      return FALSE;
+    }
 
-        for(i=1; argv[i] != 0; i++) {
-            g_string_append_c(args, ' ');
-            g_string_append(args, argv[i]);
-        }
-        
-        /* call dumpcap */
-        /*capture_opts->fork_child = spawnvp(_P_NOWAIT, exename, argv);*/
-        if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
-            CREATE_NEW_CONSOLE,
-            NULL,
-            NULL,
-            &si,
-            &pi)) {
-            g_error("couldn't open child!");
-        }
-        capture_opts->fork_child = (int) pi.hProcess;
-        g_string_free(args, TRUE);
+    /* Create a pipe for the parent process */
+    if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
+      /* Couldn't create the signal pipe between parent and child. */
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
+                        strerror(errno));
+      CloseHandle(sync_pipe_read);
+      CloseHandle(sync_pipe_write);
+      g_free( (gpointer) argv);
+      return FALSE;
     }
+
+    /* init STARTUPINFO */
+    memset(&si, 0, sizeof(si));
+    si.cb           = sizeof(si);
+#ifdef DEBUG_CHILD
+    si.dwFlags = STARTF_USESHOWWINDOW;
+    si.wShowWindow  = SW_SHOW;
+#else
+    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+    si.wShowWindow  = SW_HIDE;  /* this hides the console window */
+    si.hStdInput = signal_pipe_read;
+    si.hStdOutput = sync_pipe_write;
+    si.hStdError = sync_pipe_write;
 #endif
-#if 0
-    {
-        /* experiment to use dumpcap as the capture child */
-        /* Win32 will open a console window for the child, so very ugly ... */
-        char *dirname;
-        char *exename;
-        
-        /* take the ethereal programs path and replace ethereal with dumpcap */
-        dirname = get_dirname(g_strdup(ethereal_path));
-        exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", dirname);
-        g_free(dirname);
-        
-        /* call dumpcap */
-        capture_opts->fork_child = spawnvp(_P_NOWAIT, exename, argv);
-        g_free(exename);
+
+    g_string_append(args, exename);
+
+    /* convert args array into a single string */
+    /* XXX - could change sync_pipe_add_arg() instead */
+    /* there is a drawback here: the length is internally limited to 1024 bytes */
+    for(i=0; argv[i] != 0; i++) {
+        g_string_append_c(args, ' ');
+        g_string_append(args, argv[i]);
     }
-#endif
-#if 1
-    /* use Ethereal itself as the capture child */
-    capture_opts->fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
-#endif
+
+    /* call dumpcap */
+        if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
+        CREATE_NEW_CONSOLE,
+        NULL,
+        NULL,
+        &si,
+        &pi)) {
+        g_error("couldn't open dumpcap.exe!");
+    }
+    capture_opts->fork_child = (int) pi.hProcess;
+    g_string_free(args, TRUE);
+
+    /* associate the operating system filehandle to a C run-time file handle */
+    sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
+
+    /* associate the operating system filehandle to a C run-time file handle */
+    capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
+
     if (filterstring) {
       g_free(filterstring);
     }
@@ -535,8 +480,8 @@ sync_pipe_start(capture_options *capture_opts) {
     }
 
     /* child own's the read side now, close our handle */
-    eth_close(signal_pipe[PIPE_READ]);
-#else
+    CloseHandle(signal_pipe_read);
+#else /* _WIN32 */
     if (pipe(sync_pipe) < 0) {
       /* Couldn't create the pipe between parent and child. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
@@ -571,9 +516,9 @@ sync_pipe_start(capture_options *capture_opts) {
       eth_close(1);
       dup(sync_pipe[PIPE_WRITE]);
       eth_close(sync_pipe[PIPE_READ]);
-      execvp(ethereal_path, argv);
+      execvp(exename, argv);
       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
-               ethereal_path, strerror(errno));
+               exename, strerror(errno));
       sync_pipe_errmsg_to_parent(errmsg);
 
       /* Exit with "_exit()", so that we don't close the connection
@@ -582,8 +527,12 @@ sync_pipe_start(capture_options *capture_opts) {
         our parent). */
       _exit(2);
     }
+
+    sync_pipe_read_fd = sync_pipe[PIPE_READ];
 #endif
 
+    g_free(exename);
+
     /* Parent process - read messages from the child process over the
        sync pipe. */
     g_free( (gpointer) argv);  /* free up arg array */
@@ -592,15 +541,19 @@ sync_pipe_start(capture_options *capture_opts) {
        open, and thus it completely closes, and thus returns to us
        an EOF indication, if the child closes it (either deliberately
        or by exiting abnormally). */
+#ifdef _WIN32
+    CloseHandle(sync_pipe_write);
+#else
     eth_close(sync_pipe[PIPE_WRITE]);
+#endif
 
     if (capture_opts->fork_child == -1) {
       /* We couldn't even create the child process. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                        "Couldn't create child process: %s", strerror(errno));
-      eth_close(sync_pipe[PIPE_READ]);
+      eth_close(sync_pipe_read_fd);
 #ifdef _WIN32
-      eth_close(signal_pipe[PIPE_WRITE]);
+      eth_close(capture_opts->signal_pipe_write_fd);
 #endif
       return FALSE;
     }
@@ -614,7 +567,7 @@ sync_pipe_start(capture_options *capture_opts) {
        the child process wants to tell us something. */
 
     /* we have a running capture, now wait for the real capture filename */
-    pipe_input_set_handler(sync_pipe[PIPE_READ], (gpointer) capture_opts, 
+    pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts, 
         &capture_opts->fork_child, sync_pipe_input_cb);
 
     return TRUE;
@@ -642,7 +595,7 @@ sync_pipe_input_cb(gint source, gpointer user_data)
     sync_pipe_wait_for_child(capture_opts);
 
 #ifdef _WIN32
-    eth_close(capture_opts->signal_pipe_fd);
+    eth_close(capture_opts->signal_pipe_write_fd);
 #endif
     capture_input_closed(capture_opts);
     return FALSE;
index 6e8dea1a09d5d548e9dd63042ae86e73cf8cf4f2..6dbb64151a1b360035b2e4177d0b534e5a6aa6e9 100644 (file)
@@ -34,9 +34,6 @@
 #ifndef __CAPTURE_SYNC_H__
 #define __CAPTURE_SYNC_H__
 
-/** Name we give to the child process when doing a "-S" capture. */
-#define        CHILD_NAME      "ethereal-capture"
-
 
 /* Size of buffer to hold decimal representation of
    signed/unsigned 64-bit int */
index 659b922ba8f6577210103484d133a197b32ddb71..9c22753b81281cb48f6bd6d45dfd9753bf0137c4 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
 #include <netdb.h>
 #endif
 
-#ifdef _WIN32 /* Needed for console I/O */
-#include <conio.h>
-#endif
-
 #include "ringbuffer.h"
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 
 
 
-gboolean capture_child; /* True if this is an Ethereal capture child */
+gboolean capture_child = FALSE; /* FALSE: standalone call, TRUE: this is an Ethereal capture child */
 
-/* Win32 console handling */
-#ifdef _WIN32
-static gboolean has_console = FALSE;           /* TRUE if app has console */
-static void create_console(void);
-static void destroy_console(void);
-#endif
 static void
 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
                    const char *message, gpointer user_data _U_);
@@ -99,9 +89,6 @@ print_usage(gboolean print_ver) {
 
   FILE *output;
 
-#ifdef _WIN32
-  create_console();
-#endif
 
   if (print_ver) {
     output = stdout;
@@ -152,9 +139,6 @@ print_usage(gboolean print_ver) {
 static void
 show_version(GString *comp_info_str, GString *runtime_info_str)
 {
-#ifdef _WIN32
-  create_console();
-#endif
 
   printf(
         "Dumpcap " VERSION "%s\n"
@@ -177,9 +161,6 @@ cmdarg_err(const char *fmt, ...)
 {
   va_list ap;
 
-#ifdef _WIN32
-  create_console();
-#endif
   va_start(ap, fmt);
   fprintf(stderr, "dumpcap: ");
   vfprintf(stderr, fmt, ap);
@@ -198,9 +179,6 @@ cmdarg_err_cont(const char *fmt, ...)
 {
   va_list ap;
 
-#ifdef _WIN32
-  create_console();
-#endif
   va_start(ap, fmt);
   vfprintf(stderr, fmt, ap);
   fprintf(stderr, "\n");
@@ -218,18 +196,20 @@ BOOL WINAPI ConsoleCtrlHandlerRoutine(DWORD dwCtrlType)
 }
 #endif
 
-void exit_main(int err)
+void exit_main(int status)
 {
 #ifdef _WIN32
   /* Shutdown windows sockets */
   WSACleanup();
-
-  destroy_console();
 #endif
 
   /* can be helpful for debugging */
-  /* _getch(); */
-  exit(err);
+#ifdef DEBUG_DUMPCAP
+  printf("Press any key\n");
+  _getch();
+#endif
+
+  exit(status);
 }
 
 
@@ -254,10 +234,10 @@ main(int argc, char *argv[])
   gboolean             list_link_layer_types = FALSE;
   int                  status;
 
-#define OPTSTRING_INIT "a:b:c:Df:hi:Lps:vw:y:"
+#define OPTSTRING_INIT "a:b:c:Df:hi:Lps:vw:y:Z"
 
 #ifdef _WIN32
-#define OPTSTRING_WIN32 "B:Z:"
+#define OPTSTRING_WIN32 "B:"
 #else
 #define OPTSTRING_WIN32 ""
 #endif  /* _WIN32 */
@@ -265,9 +245,6 @@ main(int argc, char *argv[])
   char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
     OPTSTRING_INIT OPTSTRING_WIN32;
 
-
-  capture_child = (strcmp(get_basename(argv[0]), CHILD_NAME) == 0);
-
 #ifdef _WIN32
   /* Load wpcap if possible. Do this before collecting the run-time version information */
   load_wpcap();
@@ -356,14 +333,16 @@ main(int argc, char *argv[])
       case 'y':        /* Set the pcap data link type */
 #ifdef _WIN32
       case 'B':        /* Buffer size */
-      /* Hidden option supporting Sync mode */
-      case 'Z':        /* Write to pipe FD x */
 #endif /* _WIN32 */
         status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
         if(status != 0) {
             exit_main(status);
         }
         break;
+      /*** hidden option: Ethereal child mode (using binary output messages) ***/
+      case 'Z':
+          capture_child = TRUE;
+          break;
 
       /*** all non capture option specific ***/
       case 'D':        /* Print a list of capture devices and exit */
@@ -454,7 +433,6 @@ main(int argc, char *argv[])
 
   /* Now start the capture. */
 
-  /* XXX - hand the stats to the parent process */
   if(capture_loop_start(capture_opts, &stats_known, &stats) == TRUE) {
       /* capture ok */
       exit_main(0);
@@ -464,68 +442,6 @@ main(int argc, char *argv[])
   }
 }
 
-#ifdef _WIN32
-
-/* We build this as a GUI subsystem application on Win32, so
-   "WinMain()", not "main()", gets called.
-
-   Hack shamelessly stolen from the Win32 port of the GIMP. */
-#ifdef __GNUC__
-#define _stdcall  __attribute__((stdcall))
-#endif
-
-int _stdcall
-WinMain (struct HINSTANCE__ *hInstance,
-        struct HINSTANCE__ *hPrevInstance,
-        char               *lpszCmdLine,
-        int                 nCmdShow)
-{
-  has_console = FALSE;
-  return main (__argc, __argv);
-}
-
-/*
- * If this application has no console window to which its standard output
- * would go, create one.
- */
-void
-create_console(void)
-{
-  if (!has_console) {
-    /* We have no console to which to print the version string, so
-       create one and make it the standard input, output, and error. */
-    if (!AllocConsole())
-      return;   /* couldn't create console */
-    eth_freopen("CONIN$", "r", stdin);
-    eth_freopen("CONOUT$", "w", stdout);
-    eth_freopen("CONOUT$", "w", stderr);
-
-    /* Well, we have a console now. */
-    has_console = TRUE;
-
-    /* Now register "destroy_console()" as a routine to be called just
-       before the application exits, so that we can destroy the console
-       after the user has typed a key (so that the console doesn't just
-       disappear out from under them, giving the user no chance to see
-       the message(s) we put in there). */
-    atexit(destroy_console);
-
-    SetConsoleTitle("Dumpcap Console");
-  }
-}
-
-static void
-destroy_console(void)
-{
-  if (has_console) {
-/* XXX - doesn't make sense while we're linked as a console application */
-/*    printf("\n\nPress any key to exit\n");
-    _getch();*/
-    FreeConsole();
-  }
-}
-#endif /* _WIN32 */
-
 
 /* This routine should not be necessary, at least as I read the GLib
    source code, as it looks as if GLib is, on Win32, *supposed* to
@@ -548,22 +464,15 @@ console_log_handler(const char *log_domain, GLogLevelFlags log_level,
 
   /* ignore log message, if log_level isn't interesting */
   if( !(log_level & G_LOG_LEVEL_MASK & ~(G_LOG_LEVEL_DEBUG|G_LOG_LEVEL_INFO))) {
+#ifndef DEBUG_DUMPCAP
     return;
+#endif
   }
 
   /* create a "timestamp" */
   time(&curr);
   today = localtime(&curr);    
 
-#ifdef _WIN32
-  if(!capture_child) {
-    create_console();
-  }
-  if (has_console) {
-    /* For some unknown reason, the above doesn't appear to actually cause
-       anything to be sent to the standard output, so we'll just splat the
-       message out directly, just to make sure it gets out. */
-#endif
     switch(log_level & G_LOG_LEVEL_MASK) {
     case G_LOG_LEVEL_ERROR:
         level = "Err ";
@@ -594,11 +503,6 @@ console_log_handler(const char *log_domain, GLogLevelFlags log_level,
             today->tm_hour, today->tm_min, today->tm_sec,
             log_domain != NULL ? log_domain : "",
             level, message);
-#ifdef _WIN32
-  } else {
-    g_log_default_handler(log_domain, log_level, message, user_data);
-  }
-#endif
 }
 
 /****************************************************************************************************************/
@@ -779,66 +683,3 @@ _U_
 }
 
 
-/****************************************************************************************************************/
-/* functions copied from epan */
-
-/*
- * Given a pathname, return a pointer to the last pathname separator
- * character in the pathname, or NULL if the pathname contains no
- * separators.
- */
-static char *
-find_last_pathname_separator(const char *path)
-{
-       char *separator;
-
-#ifdef _WIN32
-       char c;
-
-       /*
-        * We have to scan for '\' or '/'.
-        * Get to the end of the string.
-        */
-       separator = strchr(path, '\0');         /* points to ending '\0' */
-       while (separator > path) {
-               c = *--separator;
-               if (c == '\\' || c == '/')
-                       return separator;       /* found it */
-       }
-
-       /*
-        * OK, we didn't find any, so no directories - but there might
-        * be a drive letter....
-        */
-       return strchr(path, ':');
-#else
-       separator = strrchr(path, '/');
-#endif
-       return separator;
-}
-
-/*
- * Given a pathname, return the last component.
- */
-const char *
-get_basename(const char *path)
-{
-       const char *filename;
-
-       g_assert(path != NULL);
-       filename = find_last_pathname_separator(path);
-       if (filename == NULL) {
-               /*
-                * There're no directories, drive letters, etc. in the
-                * name; the pathname *is* the file name.
-                */
-               filename = path;
-       } else {
-               /*
-                * Skip past the pathname or drive letter separator.
-                */
-               filename++;
-       }
-       return filename;
-}
-
index 375081464d10dd8dbc3d36386f46172b4a1bf3b4..723e91a4676f0ca36fee70333517a3b827b00372 100644 (file)
@@ -178,7 +178,6 @@ GString *comp_info_str, *runtime_info_str;
 gchar       *ethereal_path = NULL;
 gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
 
-gboolean             capture_child; /* True if this is the child for "-S" */
 #ifdef _WIN32
 static gboolean has_console;   /* TRUE if app has console */
 static void destroy_console(void);
@@ -1869,9 +1868,6 @@ static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
 int
 main(int argc, char *argv[])
 {
-#ifdef HAVE_LIBPCAP
-  const char          *command_name;
-#endif
   char                *s;
   int                  i;
   int                  opt;
@@ -1895,8 +1891,6 @@ main(int argc, char *argv[])
   int                  err;
 #ifdef HAVE_LIBPCAP
   gboolean             start_capture = FALSE;
-  gboolean             stats_known;
-  struct pcap_stat     stats;
 #else
   gboolean             capture_option_specified = FALSE;
 #endif
@@ -2094,9 +2088,6 @@ main(int argc, char *argv[])
   g_log_set_handler(LOG_DOMAIN_CAPTURE,
                    log_flags,
             console_log_handler, NULL /* user_data */);
-  g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
-                   log_flags,
-            console_log_handler, NULL /* user_data */);
 
   /* Set the initial values in the capture_opts. This might be overwritten 
      by preference settings and then again by the command line parameters. */
@@ -2104,22 +2095,10 @@ main(int argc, char *argv[])
 
   capture_opts->snaplen             = MIN_PACKET_SIZE;
   capture_opts->has_ring_num_files  = TRUE;
-
-  command_name = get_basename(ethereal_path);
-  /* Set "capture_child" to indicate whether this is going to be a child
-     process for a "-S" capture. */
-  capture_child = (strcmp(command_name, CHILD_NAME) == 0);
-  if (capture_child) {
-    strcat(optstring, OPTSTRING_CHILD);
-  }
 #endif
 
-  /* We want a splash screen only if we're not a child process.
-     We won't come till here, if we had a "console only" command line parameter. */
-#ifdef HAVE_LIBPCAP
-  if (!capture_child)
-#endif
-    splash_win = splash_new("Loading Ethereal ...");
+  /* We won't come till here, if we had a "console only" command line parameter. */
+  splash_win = splash_new("Loading Ethereal ...");
 
   splash_update(splash_win, "Init dissectors ...");
 
@@ -2209,23 +2188,12 @@ main(int argc, char *argv[])
 #endif
 
 #ifdef HAVE_LIBPCAP
-  /* If this is a capture child process, it should pay no attention
-     to the "prefs.capture_prom_mode" setting in the preferences file;
-     it should do what the parent process tells it to do, and if
-     the parent process wants it not to run in promiscuous mode, it'll
-     tell it so with a "-p" flag.
-
-     Otherwise, set promiscuous mode from the preferences setting. */
+  /* Set promiscuous mode from the preferences setting. */
   /* the same applies to other preferences settings as well. */
-  if (capture_child) {
-    auto_scroll_live             = FALSE;
-  } else {
     capture_opts->promisc_mode   = prefs->capture_prom_mode;
     capture_opts->show_info      = prefs->capture_show_info;
     capture_opts->real_time_mode = prefs->capture_real_time;
     auto_scroll_live             = prefs->capture_auto_scroll;
-  }
-
 #endif /* HAVE_LIBPCAP */
 
   /* Set the name resolution code's flags from the preferences. */
@@ -2625,43 +2593,11 @@ main(int argc, char *argv[])
   rc_file = get_persconffile_path(RC_FILE, FALSE);
   gtk_rc_parse(rc_file);
 
-#ifdef HAVE_LIBPCAP
-  font_init(capture_child);
-#else
   font_init(FALSE);
-#endif
 
   /* close the splash screen, as we are going to open the main window now */
   splash_destroy(splash_win);
 
-
-#ifdef HAVE_LIBPCAP
-  /* Is this a "child" ethereal, which is only supposed to pop up a
-     capture box to let us stop the capture, and run a capture
-     to a file that our parent will read? */
-  if (capture_child) {
-    /* This is the child process of a capture session,
-       so just do the low-level work of a capture - don't create
-       a temporary file and fork off *another* child process (so don't
-       call "capture_start()"). */
-
-    /* Pop up any queued-up alert boxes. */
-    display_queued_messages();
-
-    /* Now start the capture. 
-       After the capture is done; there's nothing more for us to do. */
-
-    /* XXX - hand these stats to the parent process */
-    if(capture_loop_start(capture_opts, &stats_known, &stats) == TRUE) {
-        /* capture ok */
-        gtk_exit(0);
-    } else {
-        /* capture failed */
-        gtk_exit(1);
-    }
-  }
-#endif
-
   /***********************************************************************/
   /* Everything is prepared now, preferences and command line was read in,
        we are NOT a child window for a synced capture. */
@@ -2895,18 +2831,14 @@ create_console(void)
        the message(s) we put in there). */
     atexit(destroy_console);
 
-       if(capture_child) {
-               SetConsoleTitle("Ethereal Capture Child Debug Console");
-       } else {
-               SetConsoleTitle("Ethereal Debug Console");
-       }
+       SetConsoleTitle("Ethereal Debug Console");
   }
 }
 
 static void
 destroy_console(void)
 {
-  if (has_console && !capture_child) {
+  if (has_console) {
     printf("\n\nPress any key to exit\n");
     _getch();
     FreeConsole();