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. */ /* Returns TRUE if the file opened successfully, FALSE otherwise. */
gboolean gboolean
capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, 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) { if (capture_opts->multi_files_on) {
/* ringbuffer is enabled; that doesn't work with standard output */ /* ringbuffer is enabled; that doesn't work with standard output */
g_snprintf(errmsg, errmsg_len, 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); g_free(capfile_name);
return FALSE; return FALSE;
} else { } else {
@ -1290,6 +1290,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
continue; continue;
} }
} /* cnd_autostop_size */ } /* cnd_autostop_size */
if (capture_opts->output_to_pipe) {
wtap_dump_flush(ld.wtap_pdh);
}
} /* inpkts */ } /* inpkts */
/* Only update once a second (Win32: 500ms) so as not to overload slow displays */ /* 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...) */ 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 */ 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 "input file" */
pcap_t *pcap_h; /* pcap handle */ pcap_t *pcap_h; /* pcap handle */

View File

@ -45,8 +45,11 @@
#include "capture-pcap-util.h" #include "capture-pcap-util.h"
#include "capture_ui_utils.h" #include "capture_ui_utils.h"
#include <wiretap/file_util.h>
static gboolean capture_opts_output_to_pipe(const char *save_file);
void void
capture_opts_init(capture_options *capture_opts, void *cfile) 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; capture_opts->signal_pipe_fd = -1;
#endif #endif
capture_opts->state = CAPTURE_STOPPED; 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; break;
case 'w': /* Write to capture file xxx */ case 'w': /* Write to capture file xxx */
capture_opts->save_file = g_strdup(optarg); capture_opts->save_file = g_strdup(optarg);
capture_opts->output_to_pipe = capture_opts_output_to_pipe(capture_opts->save_file);
break; break;
case 'y': /* Set the pcap data link type */ case 'y': /* Set the pcap data link type */
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL #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 */ #endif /* HAVE_LIBPCAP */

View File

@ -94,6 +94,7 @@ typedef struct capture_options_tag {
int signal_pipe_fd; /**< the pipe to signal the child */ int signal_pipe_fd; /**< the pipe to signal the child */
#endif #endif
capture_state state; /**< current state of the capture engine */ capture_state state; /**< current state of the capture engine */
gboolean output_to_pipe; /**< save_file is a pipe (named or stdout) */
} capture_options; } capture_options;

View File

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