move output_to_pipe flag from tethereal's loop_data into capture_opts, so it can be used by dumpcap (capture_loop.c) as well

svn path=/trunk/; revision=16972
This commit is contained in:
Ulf Lamping 2006-01-07 01:29:45 +00:00
parent 76bbd4181b
commit 15f9051029
5 changed files with 98 additions and 71 deletions

View File

@ -995,7 +995,7 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
}
/* open the output file (temporary/specified name/ringbuffer) */
/* open the output file (temporary/specified name/ringbuffer/named pipe/stdout) */
/* Returns TRUE if the file opened successfully, FALSE otherwise. */
gboolean
capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
@ -1020,7 +1020,7 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
if (capture_opts->multi_files_on) {
/* ringbuffer is enabled; that doesn't work with standard output */
g_snprintf(errmsg, errmsg_len,
"Ring buffer requested, but capture is being written to the standard error.");
"Ring buffer requested, but capture is being written to the standard output.");
g_free(capfile_name);
return FALSE;
} else {
@ -1290,6 +1290,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
continue;
}
} /* cnd_autostop_size */
if (capture_opts->output_to_pipe) {
wtap_dump_flush(ld.wtap_pdh);
}
} /* inpkts */
/* Only update once a second (Win32: 500ms) so as not to overload slow displays */

View File

@ -90,8 +90,7 @@ typedef struct _loop_data {
jmp_buf stopenv; /* T: starting point of loop (jump back this point on SIG...) */
char *save_file; /* T: Name of file to which we're writing */
gboolean output_to_pipe; /* T: output to a pipe, flush outut file immediately */
capture_packet_cb_fct packet_cb; /* callback for a single captured packet */
capture_packet_cb_fct packet_cb; /* callback for a single captured packet */
/* pcap "input file" */
pcap_t *pcap_h; /* pcap handle */

View File

@ -45,8 +45,11 @@
#include "capture-pcap-util.h"
#include "capture_ui_utils.h"
#include <wiretap/file_util.h>
static gboolean capture_opts_output_to_pipe(const char *save_file);
void
capture_opts_init(capture_options *capture_opts, void *cfile)
@ -89,6 +92,7 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
capture_opts->signal_pipe_fd = -1;
#endif
capture_opts->state = CAPTURE_STOPPED;
capture_opts->output_to_pipe = FALSE;
}
@ -409,6 +413,7 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg,
break;
case 'w': /* Write to capture file xxx */
capture_opts->save_file = g_strdup(optarg);
capture_opts->output_to_pipe = capture_opts_output_to_pipe(capture_opts->save_file);
break;
case 'y': /* Set the pcap data link type */
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
@ -575,4 +580,64 @@ gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capt
}
#ifndef S_IFIFO
#define S_IFIFO _S_IFIFO
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
/* copied from filesystem.c */
static int capture_opts_test_for_fifo(const char *path)
{
struct stat statb;
if (eth_stat(path, &statb) < 0)
return errno;
if (S_ISFIFO(statb.st_mode))
return ESPIPE;
else
return 0;
}
static gboolean capture_opts_output_to_pipe(const char *save_file)
{
int err;
if (save_file != NULL) {
/* We're writing to a capture file. */
if (strcmp(save_file, "-") == 0) {
/* Writing to stdout. */
/* XXX - should we check whether it's a pipe? It's arguably
silly to do "-w - >output_file" rather than "-w output_file",
but by not checking we might be violating the Principle Of
Least Astonishment. */
return TRUE;
} else {
/* not a capture file, test for a FIFO (aka named pipe) */
err = capture_opts_test_for_fifo(save_file);
switch (err) {
case ENOENT: /* it doesn't exist, so we'll be creating it,
and it won't be a FIFO */
case 0: /* found it, but it's not a FIFO */
break;
case ESPIPE: /* it is a FIFO */
return TRUE;
break;
default: /* couldn't stat it */
cmdarg_err("Error testing whether capture file is a pipe: %s",
strerror(errno));
exit(2);
}
}
}
return FALSE;
}
#endif /* HAVE_LIBPCAP */

View File

@ -94,6 +94,7 @@ typedef struct capture_options_tag {
int signal_pipe_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) */
} capture_options;

View File

@ -152,7 +152,7 @@ static gboolean infoprint; /* if TRUE, print capture info after clearing infodel
#endif /* HAVE_LIBPCAP */
static int capture(char *, int);
static int capture(int);
static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
const u_char *);
static void report_counts(void);
@ -634,7 +634,6 @@ main(int argc, char *argv[])
gboolean capture_option_specified = FALSE;
#endif
gboolean quiet = FALSE;
gchar *save_file = NULL;
int out_file_type = WTAP_FILE_PCAP;
gchar *cf_name = NULL, *rfilter = NULL;
#ifdef HAVE_PCAP_OPEN_DEAD
@ -835,6 +834,7 @@ main(int argc, char *argv[])
case 'i': /* Use interface xxx */
case 'p': /* Don't capture in promiscuous mode */
case 's': /* Set the snapshot (capture) length */
case 'w': /* Write to capture file xxx */
case 'y': /* Set the pcap data link type */
#ifdef _WIN32
case 'B': /* Buffer size */
@ -984,9 +984,6 @@ main(int argc, char *argv[])
runtime_info_str->str);
exit(0);
break;
case 'w': /* Write to capture file xxx */
save_file = g_strdup(optarg);
break;
case 'V': /* Verbose */
verbose = TRUE;
break;
@ -1041,56 +1038,20 @@ main(int argc, char *argv[])
/* If we're not writing to a file and "-q" wasn't specified
we should print packet information */
if (save_file == NULL && !quiet)
if (capture_opts.save_file == NULL && !quiet)
print_packet_info = TRUE;
/* See if we're writing a capture file and the file is a pipe */
#ifdef HAVE_LIBPCAP
ld.output_to_pipe = FALSE;
#endif
if (save_file != NULL) {
/* We're writing to a capture file. */
if (strcmp(save_file, "-") == 0) {
/* Write to the standard output.
If we'll also be writing dissected packets to the standard
if (capture_opts.save_file != NULL &&
strcmp(capture_opts.save_file, "-") == 0
&& print_packet_info) {
/* If we're writing to the standard output.
and we'll also be writing dissected packets to the standard
output, reject the request. At best, we could redirect that
to the standard error; we *can't* write both to the standard
output and have either of them be useful. */
if (print_packet_info) {
cmdarg_err("You can't write both raw packet data and dissected packets"
" to the standard output.");
exit(1);
}
#ifdef HAVE_LIBPCAP
/* XXX - should we check whether it's a pipe? It's arguably
silly to do "-w - >output_file" rather than "-w output_file",
but by not checking we might be violating the Principle Of
Least Astonishment. */
ld.output_to_pipe = TRUE;
#endif
}
#ifdef HAVE_LIBPCAP
else {
/* not a capture file, test for a FIFO (aka named pipe) */
err = test_for_fifo(save_file);
switch (err) {
case ENOENT: /* it doesn't exist, so we'll be creating it,
and it won't be a FIFO */
case 0: /* found it, but it's not a FIFO */
break;
case ESPIPE: /* it is a FIFO */
ld.output_to_pipe = TRUE;
break;
default: /* couldn't stat it */
cmdarg_err("Error testing whether capture file is a pipe: %s",
strerror(errno));
exit(2);
}
}
#endif
cmdarg_err("You can't write both raw packet data and dissected packets"
" to the standard output.");
exit(1);
}
#ifndef HAVE_LIBPCAP
@ -1139,7 +1100,7 @@ main(int argc, char *argv[])
} else {
/* If they didn't specify a "-w" flag, but specified a maximum capture
file size, tell them that this doesn't work, and exit. */
if (capture_opts.has_autostop_filesize && save_file == NULL) {
if (capture_opts.has_autostop_filesize && capture_opts.save_file == NULL) {
cmdarg_err("Maximum capture file size specified, but "
"capture isn't being saved to a file.");
exit(1);
@ -1155,17 +1116,17 @@ main(int argc, char *argv[])
(XXX - shouldn't that be "if there is no stop criterion",
as you might want to switch files based on a packet count
or a time). */
if (save_file == NULL) {
if (capture_opts.save_file == NULL) {
cmdarg_err("Multiple capture files requested, but "
"the capture isn't being saved to a file.");
exit(1);
}
if (strcmp(save_file, "-") == 0) {
if (strcmp(capture_opts.save_file, "-") == 0) {
cmdarg_err("Multiple capture files requested, but "
"the capture is being written to the standard output.");
exit(1);
}
if (ld.output_to_pipe) {
if (capture_opts.output_to_pipe) {
cmdarg_err("Multiple capture files requested, but "
"the capture file is a pipe.");
exit(1);
@ -1340,7 +1301,7 @@ main(int argc, char *argv[])
}
/* Process the packets in the file */
err = load_cap_file(&cfile, save_file, out_file_type);
err = load_cap_file(&cfile, capture_opts.save_file, out_file_type);
if (err != 0) {
epan_cleanup();
exit(2);
@ -1387,7 +1348,7 @@ main(int argc, char *argv[])
/* For now, assume libpcap gives microsecond precision. */
timestamp_set_precision(TS_PREC_AUTO_USEC);
capture(save_file, out_file_type);
capture(out_file_type);
if (capture_opts.multi_files_on) {
ringbuf_free();
@ -1412,7 +1373,7 @@ main(int argc, char *argv[])
static condition *volatile cnd_file_duration = NULL; /* this must be visible in process_packet */
static int
capture(char *save_file, int out_file_type)
capture(int out_file_type)
{
int err = 0;
int volatile volatile_err = 0;
@ -1461,9 +1422,7 @@ capture(char *save_file, int out_file_type)
setgid(getgid());
#endif
capture_opts.save_file = save_file;
/* open the output file (temporary/specified name/ringbuffer) */
/* open the output file (temporary/specified name/ringbuffer/named pipe/stdout) */
if (!capture_loop_open_output(&capture_opts, &save_file_fd, errmsg, sizeof(errmsg))) {
goto error;
}
@ -1616,7 +1575,7 @@ capture(char *save_file, int out_file_type)
its maximum size. */
if (capture_opts.multi_files_on) {
/* Switch to the next ringbuffer file */
if (ringbuf_switch_file(&ld.wtap_pdh, &save_file, &save_file_fd, &loop_err)) {
if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_autostop_size);
if (cnd_file_duration) {
@ -1632,7 +1591,7 @@ capture(char *save_file, int out_file_type)
ld.go = FALSE;
}
}
if (ld.output_to_pipe) {
if (capture_opts.output_to_pipe) {
if (ld.packet_count > packet_count_prev) {
wtap_dump_flush(ld.wtap_pdh);
packet_count_prev = ld.packet_count;
@ -1674,18 +1633,18 @@ capture(char *save_file, int out_file_type)
if (volatile_err == 0)
write_ok = TRUE;
else {
show_capture_file_io_error(save_file, volatile_err, FALSE);
show_capture_file_io_error(capture_opts.save_file, volatile_err, FALSE);
write_ok = FALSE;
}
if (save_file != NULL) {
if (capture_opts.save_file != NULL) {
/* We're saving to a file or files; close all files. */
close_ok = capture_loop_close_output(&capture_opts, &ld, &err);
/* If we've displayed a message about a write error, there's no point
in displaying another message about an error on close. */
if (!close_ok && write_ok)
show_capture_file_io_error(save_file, err, TRUE);
show_capture_file_io_error(capture_opts.save_file, err, TRUE);
}
#ifndef _WIN32
@ -1717,8 +1676,8 @@ error:
if (capture_opts.multi_files_on) {
ringbuf_error_cleanup();
}
g_free(save_file);
save_file = NULL;
g_free(capture_opts.save_file);
capture_opts.save_file = NULL;
cmdarg_err("%s", errmsg);
#ifndef _WIN32
if (ld.from_cap_pipe) {