summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2006-02-11 23:25:11 +0000
committerUlf Lamping <ulf.lamping@web.de>2006-02-11 23:25:11 +0000
commitcf94760fa4a1de9fdb1aa5a3152516699bceaf45 (patch)
tree1c665d6e6c1ad304187017b4cdbe4ecc3aba2532
parentec37501696d809d932c6db398b71950b4beb4e36 (diff)
downloadwireshark-cf94760fa4a1de9fdb1aa5a3152516699bceaf45.tar.gz
the point of no return ...
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. svn path=/trunk/; revision=17256
-rw-r--r--Makefile.common1
-rw-r--r--capture_loop.c15
-rw-r--r--capture_opts.c74
-rw-r--r--capture_opts.h2
-rw-r--r--capture_sync.c281
-rw-r--r--capture_sync.h3
-rw-r--r--dumpcap.c191
-rw-r--r--gtk/main.c78
8 files changed, 150 insertions, 495 deletions
diff --git a/Makefile.common b/Makefile.common
index a6f5c7954c..27f542b5de 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -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 \
diff --git a/capture_loop.c b/capture_loop.c
index 58745e7c12..3ae13f0492 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -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
diff --git a/capture_opts.c b/capture_opts.c
index 6c451458a1..a893ff6f9b 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -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();
diff --git a/capture_opts.h b/capture_opts.h
index 178757e2c8..8c3b85eff4 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -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) */
diff --git a/capture_sync.c b/capture_sync.c
index 6c9901b929..a6aaac0b52 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -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;
diff --git a/capture_sync.h b/capture_sync.h
index 6e8dea1a09..6dbb64151a 100644
--- a/capture_sync.h
+++ b/capture_sync.h
@@ -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 */
diff --git a/dumpcap.c b/dumpcap.c
index 659b922ba8..9c22753b81 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -42,10 +42,6 @@
#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"
@@ -69,14 +65,8 @@
-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;
-}
-
diff --git a/gtk/main.c b/gtk/main.c
index 375081464d..723e91a467 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -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();