diff options
author | Ulf Lamping <ulf.lamping@web.de> | 2006-02-11 23:25:11 +0000 |
---|---|---|
committer | Ulf Lamping <ulf.lamping@web.de> | 2006-02-11 23:25:11 +0000 |
commit | cf94760fa4a1de9fdb1aa5a3152516699bceaf45 (patch) | |
tree | 1c665d6e6c1ad304187017b4cdbe4ecc3aba2532 | |
parent | ec37501696d809d932c6db398b71950b4beb4e36 (diff) | |
download | wireshark-cf94760fa4a1de9fdb1aa5a3152516699bceaf45.tar.gz wireshark-cf94760fa4a1de9fdb1aa5a3152516699bceaf45.tar.bz2 wireshark-cf94760fa4a1de9fdb1aa5a3152516699bceaf45.zip |
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.common | 1 | ||||
-rw-r--r-- | capture_loop.c | 15 | ||||
-rw-r--r-- | capture_opts.c | 74 | ||||
-rw-r--r-- | capture_opts.h | 2 | ||||
-rw-r--r-- | capture_sync.c | 281 | ||||
-rw-r--r-- | capture_sync.h | 3 | ||||
-rw-r--r-- | dumpcap.c | 191 | ||||
-rw-r--r-- | gtk/main.c | 78 |
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 */ @@ -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(); |