summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-07-16 07:15:09 +0000
committerGuy Harris <guy@alum.mit.edu>2002-07-16 07:15:09 +0000
commit44d19627efccd1b7461d38a6ba6eb25a98ed66ac (patch)
tree9a9121589e31a5c3981ca9d943da7f385c731afd
parent41dc7b1b59bef7521b9e6febc7a482e2f32017fe (diff)
downloadwireshark-44d19627efccd1b7461d38a6ba6eb25a98ed66ac.tar.gz
From Graeme Hewson:
Allow "-" as the output file name in Wiretap, referring to the standard error. Optimize the capture loop. Fix some of the error-message printing code in Ethereal and Tethereal. Have Wiretap check whether it can seek on a file descriptor, and pass the results of that test to the file-type-specific "open for output" routine. Have the "open for output" routines for files where we need to seek when writing the file return an error if seeks don't work. svn path=/trunk/; revision=5884
-rw-r--r--capture.c4
-rw-r--r--doc/tethereal.pod.template3
-rw-r--r--file.c23
-rw-r--r--file.h4
-rw-r--r--tethereal.c205
-rw-r--r--wiretap/file.c66
-rw-r--r--wiretap/lanalyzer.c12
-rw-r--r--wiretap/lanalyzer.h4
-rw-r--r--wiretap/libpcap.c4
-rw-r--r--wiretap/libpcap.h4
-rw-r--r--wiretap/netmon.c13
-rw-r--r--wiretap/netmon.h4
-rw-r--r--wiretap/netxray.c24
-rw-r--r--wiretap/netxray.h6
-rw-r--r--wiretap/ngsniffer.c4
-rw-r--r--wiretap/ngsniffer.h4
-rw-r--r--wiretap/snoop.c4
-rw-r--r--wiretap/snoop.h4
-rw-r--r--wiretap/visual.c11
-rw-r--r--wiretap/visual.h4
-rw-r--r--wiretap/wtap.c7
-rw-r--r--wiretap/wtap.h28
22 files changed, 285 insertions, 157 deletions
diff --git a/capture.c b/capture.c
index bc96b585e3..0640727713 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.185 2002/07/16 05:43:39 guy Exp $
+ * $Id: capture.c,v 1.186 2002/07/16 07:15:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -333,7 +333,7 @@ do_capture(char *capfile_name)
ringbuf_error_cleanup();
}
simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(errno, TRUE), capfile_name);
+ file_open_error_message(errno, TRUE, WTAP_FILE_PCAP), capfile_name);
}
return;
}
diff --git a/doc/tethereal.pod.template b/doc/tethereal.pod.template
index 84a675bdb7..e9114cdbd6 100644
--- a/doc/tethereal.pod.template
+++ b/doc/tethereal.pod.template
@@ -288,7 +288,8 @@ a one-line summary of the packet.
=item -w
-Write packet data to I<savefile>.
+Write packet data to I<savefile> or to the standard output if
+I<savefile> is "-".
=item -x
diff --git a/file.c b/file.c
index 59d1c44c12..a08c3f0cde 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.281 2002/07/15 05:14:26 sharpe Exp $
+ * $Id: file.c,v 1.282 2002/07/16 07:15:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -197,7 +197,7 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
fail:
simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, FALSE), fname);
+ file_open_error_message(err, FALSE, 0), fname);
return (err);
}
@@ -1799,7 +1799,7 @@ save_cap_file(char *fname, capture_file *cf, gboolean save_filtered,
pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap, &err);
if (pdh == NULL) {
simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, TRUE), fname);
+ file_open_error_message(err, TRUE, save_format), fname);
goto fail;
}
@@ -1897,7 +1897,7 @@ fail:
}
char *
-file_open_error_message(int err, gboolean for_writing)
+file_open_error_message(int err, gboolean for_writing, int file_type)
{
char *errmsg;
static char errmsg_errno[1024+1];
@@ -1919,6 +1919,14 @@ file_open_error_message(int err, gboolean for_writing)
errmsg = "The file \"%s\" is not a capture file in a format Ethereal understands.";
break;
+ case WTAP_ERR_CANT_WRITE_TO_PIPE:
+ /* Seen only when opening a capture file for writing. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" is a pipe, and %s capture files cannot be "
+ "written to a pipe.", wtap_file_type_string(file_type));
+ errmsg = errmsg_errno;
+ break;
+
case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
/* Seen only when opening a capture file for writing. */
errmsg = "Ethereal does not support writing capture files in that format.";
@@ -1972,7 +1980,8 @@ file_open_error_message(int err, gboolean for_writing)
default:
snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" could not be opened: %s.",
+ "The file \"%%s\" could not be %s: %s.",
+ for_writing ? "created" : "opened",
wtap_strerror(err));
errmsg = errmsg_errno;
break;
@@ -2103,7 +2112,7 @@ copy_binary_file(char *from_filename, char *to_filename)
if (from_fd < 0) {
err = errno;
simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, TRUE), from_filename);
+ file_open_error_message(err, TRUE, 0), from_filename);
goto done;
}
@@ -2116,7 +2125,7 @@ copy_binary_file(char *from_filename, char *to_filename)
if (to_fd < 0) {
err = errno;
simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, TRUE), to_filename);
+ file_open_error_message(err, TRUE, 0), to_filename);
close(from_fd);
goto done;
}
diff --git a/file.h b/file.h
index 75e516a675..615c57f7c9 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.94 2002/05/27 22:00:35 guy Exp $
+ * $Id: file.h,v 1.95 2002/07/16 07:15:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -140,7 +140,7 @@ int file_mv(char *from, char *to);
/* Copies a file. Returns 0 on failure, 1 on success */
int file_cp(char *from, char *to);
-char *file_open_error_message(int, gboolean);
+char *file_open_error_message(int, gboolean, int);
char *file_read_error_message(int);
char *file_write_error_message(int);
diff --git a/tethereal.c b/tethereal.c
index 7ded2b48ac..b9be16df37 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -1,6 +1,6 @@
/* tethereal.c
*
- * $Id: tethereal.c,v 1.147 2002/07/07 21:52:48 guy Exp $
+ * $Id: tethereal.c,v 1.148 2002/07/16 07:15:04 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -675,23 +675,30 @@ main(int argc, char *argv[])
/* See if we're writing a capture file and the file is a pipe */
ld.output_to_pipe = FALSE;
if (cfile.save_file != NULL) {
- err = test_for_fifo(cfile.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 */
+ if (!strcmp(cfile.save_file, "-")) {
+ /* stdout */
+ g_free(cfile.save_file);
+ cfile.save_file = g_strdup("");
ld.output_to_pipe = TRUE;
- break;
-
- default: /* couldn't stat it */
- fprintf(stderr,
- "tethereal: Error testing whether capture file is a pipe: %s\n",
- strerror(errno));
- exit(2);
+ } else {
+ err = test_for_fifo(cfile.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 */
+ fprintf(stderr,
+ "tethereal: Error testing whether capture file is a pipe: %s\n",
+ strerror(errno));
+ exit(2);
+ }
}
}
@@ -699,7 +706,8 @@ main(int argc, char *argv[])
/* 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 && cfile.save_file == NULL) {
- fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
+ fprintf(stderr, "tethereal: Maximum capture file size specified, but "
+ "capture isn't being saved to a file.\n");
exit(2);
}
@@ -882,7 +890,8 @@ capture(int out_file_type)
struct bpf_program fcode;
void (*oldhandler)(int);
int err = 0;
- volatile int inpkts = 0;
+ int volatile volatile_err = 0;
+ int volatile inpkts = 0;
int pcap_cnt;
char errmsg[1024+1];
condition *volatile cnd_stop_capturesize = NULL;
@@ -892,7 +901,7 @@ capture(int out_file_type)
char *libpcap_warn;
#endif
struct pcap_stat stats;
- gboolean volatile write_err = FALSE;
+ gboolean write_err;
gboolean dump_ok;
/* Initialize all data structures used for dissection. */
@@ -992,6 +1001,7 @@ capture(int out_file_type)
ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
pcap_snapshot(ld.pch), &err);
} else {
+ err = errno; /* "ringbuf_init()" failed */
ld.pdh = NULL;
}
} else {
@@ -1000,8 +1010,9 @@ capture(int out_file_type)
}
if (ld.pdh == NULL) {
- snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
- cfile.save_file);
+ snprintf(errmsg, sizeof errmsg,
+ file_open_error_message(err, TRUE, out_file_type),
+ *cfile.save_file == '\0' ? "stdout" : cfile.save_file);
goto error;
}
}
@@ -1044,6 +1055,33 @@ capture(int out_file_type)
ld.go = FALSE;
ld.packet_count = 0;
while (ld.go) {
+ /* We need to be careful with automatic variables defined in the
+ outer scope which are changed inside the loop. Most compilers
+ don't try to roll them back to their original values after the
+ longjmp which causes the loop to finish, but all that the
+ standards say is that their values are indeterminate. If we
+ don't want them to be rolled back, we should define them with the
+ volatile attribute (paraphrasing W. Richard Stevens, Advanced
+ Programming in the UNIX Environment, p. 178).
+
+ The "err" variable causes a particular problem. If we give it
+ the volatile attribute, then when we pass a reference to it (as
+ in "&err") to a function, GCC warns: "passing arg <n> of
+ <function> discards qualifiers from pointer target type".
+ Therefore within the loop and just beyond we don't use "err".
+ Within the loop we define "loop_err", and assign its value to
+ "volatile_err", which is in the outer scope and is checked when
+ the loop finishes.
+
+ We also define "packet_count_prev" here to keep things tidy,
+ since it's used only inside the loop. If it were defined in the
+ outer scope, GCC would give a warning (unnecessary in this case)
+ that it might be clobbered, and we'd need to give it the volatile
+ attribute to suppress the warning. */
+
+ int loop_err = 0;
+ int packet_count_prev = 0;
+
if (cnd_stop_capturesize == NULL && cnd_stop_timeout == NULL) {
/* We're not stopping at a particular capture file size, and we're
not stopping after some particular amount of time has expired,
@@ -1064,6 +1102,7 @@ capture(int out_file_type)
pcap_cnt = -1;
else {
if (ld.packet_count >= capture_opts.autostop_count) {
+ /* XXX do we need this test here? */
/* It appears there's nothing more to capture. */
break;
}
@@ -1078,43 +1117,47 @@ capture(int out_file_type)
if (inpkts < 0) {
/* Error from "pcap_dispatch()". */
ld.go = FALSE;
- } else if (capture_opts.autostop_count != 0 &&
- ld.packet_count >= capture_opts.autostop_count) {
- /* The specified number of packets have been captured and have
- passed both any capture filter in effect and any read filter
- in effect. */
- ld.go = FALSE;
} else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
/* The specified capture time has elapsed; stop the capture. */
ld.go = FALSE;
- } else if (cnd_stop_capturesize != NULL &&
- cnd_eval(cnd_stop_capturesize,
- (guint32)wtap_get_bytes_dumped(ld.pdh))) {
- /* We're saving the capture to a file, and the capture file reached
- its maximum size. */
- if (capture_opts.ringbuffer_on) {
- /* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&cfile, &ld.pdh, &err)) {
- /* File switch succeeded: reset the condition */
- cnd_reset(cnd_stop_capturesize);
+ } else if (inpkts > 0) {
+ if (capture_opts.autostop_count != 0 &&
+ ld.packet_count >= capture_opts.autostop_count) {
+ /* The specified number of packets have been captured and have
+ passed both any capture filter in effect and any read filter
+ in effect. */
+ ld.go = FALSE;
+ } else if (cnd_stop_capturesize != NULL &&
+ cnd_eval(cnd_stop_capturesize,
+ (guint32)wtap_get_bytes_dumped(ld.pdh))) {
+ /* We're saving the capture to a file, and the capture file reached
+ its maximum size. */
+ if (capture_opts.ringbuffer_on) {
+ /* Switch to the next ringbuffer file */
+ if (ringbuf_switch_file(&cfile, &ld.pdh, &loop_err)) {
+ /* File switch succeeded: reset the condition */
+ cnd_reset(cnd_stop_capturesize);
+ } else {
+ /* File switch failed: stop here */
+ volatile_err = loop_err;
+ ld.go = FALSE;
+ }
} else {
- /* File switch failed: stop here */
+ /* No ringbuffer - just stop. */
ld.go = FALSE;
- continue;
}
- } else {
- /* No ringbuffer - just stop. */
- ld.go = FALSE;
}
- }
- if (ld.output_to_pipe) {
- /* XXX - flush only if ld.packet_count changed? */
- if (fflush(wtap_dump_file(ld.pdh))) {
- err = errno;
- ld.go = FALSE;
+ if (ld.output_to_pipe) {
+ if (ld.packet_count > packet_count_prev) {
+ if (fflush(wtap_dump_file(ld.pdh))) {
+ volatile_err = errno;
+ ld.go = FALSE;
+ }
+ packet_count_prev = ld.packet_count;
+ }
}
- }
- }
+ } /* inpkts > 0 */
+ } /* while (ld.go) */
/* delete stop conditions */
if (cnd_stop_capturesize != NULL)
@@ -1124,7 +1167,7 @@ capture(int out_file_type)
if ((cfile.save_file != NULL) && !quiet) {
/* We're saving to a file, which means we're printing packet counts
- to the standard output if we are not running silent and deep.
+ to stderr if we are not running silent and deep.
Send a newline so that we move to the line after the packet count. */
fprintf(stderr, "\n");
}
@@ -1135,8 +1178,10 @@ capture(int out_file_type)
pcap_geterr(ld.pch));
}
- if (err != 0) {
- show_capture_file_io_error(cfile.save_file, err, FALSE);
+ if (volatile_err == 0)
+ write_err = FALSE;
+ else {
+ show_capture_file_io_error(cfile.save_file, volatile_err, FALSE);
write_err = TRUE;
}
@@ -1147,7 +1192,9 @@ capture(int out_file_type)
} else {
dump_ok = wtap_dump_close(ld.pdh, &err);
}
- if (!dump_ok && ! write_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 (!dump_ok && !write_err)
show_capture_file_io_error(cfile.save_file, err, TRUE);
}
@@ -1195,8 +1242,8 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
int err;
/* Convert from libpcap to Wiretap format.
- If that fails, ignore the packet.
- XXX - print a message. */
+ If that fails, ignore the packet (wtap_process_pcap_packet has
+ written an error message). */
pd = wtap_process_pcap_packet(ld->linktype, phdr, pd, &pseudo_header,
&whdr, &err);
if (pd == NULL) {
@@ -1295,31 +1342,28 @@ load_cap_file(capture_file *cf, int out_file_type)
case WTAP_ERR_UNSUPPORTED_ENCAP:
case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
fprintf(stderr,
-"tethereal: The capture file being read cannot be written in that format.\n");
+ "tethereal: The capture file being read cannot be written in "
+ "that format.\n");
break;
case WTAP_ERR_CANT_OPEN:
fprintf(stderr,
-"tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
- cf->save_file);
+ "tethereal: The file \"%s\" couldn't be created for some "
+ "unknown reason.\n",
+ *cf->save_file == '\0' ? "stdout" : cf->save_file);
break;
case WTAP_ERR_SHORT_WRITE:
fprintf(stderr,
-"tethereal: A full header couldn't be written to the file \"%s\".\n",
- cf->save_file);
+ "tethereal: A full header couldn't be written to the file \"%s\".\n",
+ *cf->save_file == '\0' ? "stdout" : cf->save_file);
break;
default:
- if (err < 0) {
- fprintf(stderr,
- "tethereal: The file \"%s\" could not be opened: Error %d.\n",
- cf->save_file, err);
- } else {
- fprintf(stderr,
- "tethereal: The file \"%s\" could not be opened: %s\n.",
- cf->save_file, strerror(err));
- }
+ fprintf(stderr,
+ "tethereal: The file \"%s\" could not be created: %s\n.",
+ *cf->save_file == '\0' ? "stdout" : cf->save_file,
+ wtap_strerror(err));
break;
}
goto out;
@@ -1499,6 +1543,9 @@ wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
static void
show_capture_file_io_error(const char *fname, int err, gboolean is_close)
{
+ if (*fname == '\0')
+ fname = "stdout";
+
switch (err) {
case ENOSPC:
@@ -1814,7 +1861,7 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
}
char *
-file_open_error_message(int err, gboolean for_writing)
+file_open_error_message(int err, gboolean for_writing, int file_type)
{
char *errmsg;
static char errmsg_errno[1024+1];
@@ -1831,6 +1878,14 @@ file_open_error_message(int err, gboolean for_writing)
errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
break;
+ case WTAP_ERR_CANT_WRITE_TO_PIPE:
+ /* Seen only when opening a capture file for writing. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" is a pipe, and %s capture files cannot be "
+ "written to a pipe.", wtap_file_type_string(file_type));
+ errmsg = errmsg_errno;
+ break;
+
case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
/* Seen only when opening a capture file for writing. */
errmsg = "Tethereal does not support writing capture files in that format.";
@@ -1884,7 +1939,8 @@ file_open_error_message(int err, gboolean for_writing)
default:
snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" could not be opened: %s.",
+ "The file \"%%s\" could not be %s: %s.",
+ for_writing ? "created" : "opened",
wtap_strerror(err));
errmsg = errmsg_errno;
break;
@@ -1944,7 +2000,8 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
return (0);
fail:
- snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
+ snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE, 0),
+ fname);
fprintf(stderr, "tethereal: %s\n", err_msg);
return (err);
}
diff --git a/wiretap/file.c b/wiretap/file.c
index 036b9057dc..3253ecb974 100644
--- a/wiretap/file.c
+++ b/wiretap/file.c
@@ -1,6 +1,6 @@
/* file.c
*
- * $Id: file.c,v 1.93 2002/06/27 22:46:47 guy Exp $
+ * $Id: file.c,v 1.94 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -308,7 +308,7 @@ static const struct file_type_info {
const char *name;
const char *short_name;
int (*can_write_encap)(int);
- int (*dump_open)(wtap_dumper *, int *);
+ int (*dump_open)(wtap_dumper *, gboolean, int *);
} dump_open_table[WTAP_NUM_FILE_TYPES] = {
/* WTAP_FILE_UNKNOWN */
{ NULL, NULL,
@@ -513,20 +513,26 @@ wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
if (wdh == NULL)
return NULL; /* couldn't allocate it */
- /* In case "fopen()" fails but doesn't set "errno", set "errno"
- to a generic "the open failed" error. */
- errno = WTAP_ERR_CANT_OPEN;
- fh = fopen(filename, "wb");
- if (fh == NULL) {
- *err = errno;
- return NULL; /* can't create file */
+ /* Empty filename means stdout */
+ if (*filename == '\0')
+ wdh->fh = stdout;
+ else {
+ /* In case "fopen()" fails but doesn't set "errno", set "errno"
+ to a generic "the open failed" error. */
+ errno = WTAP_ERR_CANT_OPEN;
+ fh = fopen(filename, "wb");
+ if (fh == NULL) {
+ *err = errno;
+ return NULL; /* can't create file */
+ }
+ wdh->fh = fh;
}
- wdh->fh = fh;
if (!wtap_dump_open_finish(wdh, filetype, err)) {
/* Get rid of the file we created; we couldn't finish
opening it. */
- unlink(filename);
+ if (wdh->fh != stdout)
+ unlink(filename);
return NULL;
}
return wdh;
@@ -604,12 +610,27 @@ static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, int *err)
{
+ int fd;
+ gboolean cant_seek;
+
+ /* Can we do a seek on the file descriptor?
+ If not, note that fact. */
+ fd = fileno(wdh->fh);
+ if (lseek(fd, 1, SEEK_CUR) == -1)
+ cant_seek = TRUE;
+ else {
+ /* Undo the seek. */
+ lseek(fd, 0, SEEK_SET);
+ cant_seek = FALSE;
+ }
+
/* Now try to open the file for writing. */
- if (!(*dump_open_table[filetype].dump_open)(wdh, err)) {
+ if (!(*dump_open_table[filetype].dump_open)(wdh, cant_seek, err)) {
/* The attempt failed. Close the stream for the file.
NOTE: this means the FD handed to "wtap_dump_fdopen()"
will be closed if the open fails. */
- fclose(wdh->fh);
+ if (wdh->fh != stdout)
+ fclose(wdh->fh);
/* Now free up the dumper handle. */
g_free(wdh);
@@ -640,15 +661,18 @@ gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
ret = FALSE;
}
errno = WTAP_ERR_CANT_CLOSE;
- if (fclose(wdh->fh) == EOF) {
- if (ret) {
- /* The per-format close function succeeded,
- but the fclose didn't. Save the reason
- why, if our caller asked for it. */
- if (err != NULL)
- *err = errno;
+ /* Don't close stdout */
+ if (wdh->fh != stdout) {
+ if (fclose(wdh->fh) == EOF) {
+ if (ret) {
+ /* The per-format close function succeeded,
+ but the fclose didn't. Save the reason
+ why, if our caller asked for it. */
+ if (err != NULL)
+ *err = errno;
+ }
+ ret = FALSE;
}
- ret = FALSE;
}
if (wdh->dump.opaque != NULL)
g_free(wdh->dump.opaque);
diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c
index 18b8571c05..095f9d5e0c 100644
--- a/wiretap/lanalyzer.c
+++ b/wiretap/lanalyzer.c
@@ -1,6 +1,6 @@
/* lanalyzer.c
*
- * $Id: lanalyzer.c,v 1.34 2002/06/27 22:46:48 guy Exp $
+ * $Id: lanalyzer.c,v 1.35 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -594,12 +594,18 @@ int lanalyzer_dump_can_write_encap(int encap)
* Returns TRUE on success, FALSE on failure; sets "*err" to an
* error code on failure
*---------------------------------------------------*/
-gboolean lanalyzer_dump_open(wtap_dumper *wdh, int *err)
+gboolean lanalyzer_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err)
{
int jump;
void *tmp;
- /* This is a LANalyzer file */
+ /* This is a LANalyzer file. We can't fill in some fields in the
+ header until all the packets have been written, so we can't
+ write to a pipe. */
+ if (cant_seek) {
+ *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
+ return FALSE;
+ }
tmp = g_malloc(sizeof(LA_TmpInfo));
if (!tmp) {
diff --git a/wiretap/lanalyzer.h b/wiretap/lanalyzer.h
index e42a347699..42d030d034 100644
--- a/wiretap/lanalyzer.h
+++ b/wiretap/lanalyzer.h
@@ -1,6 +1,6 @@
/* lanalyzer.h
*
- * $Id: lanalyzer.h,v 1.6 2002/06/27 22:46:48 guy Exp $
+ * $Id: lanalyzer.h,v 1.7 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -170,7 +170,7 @@ typedef struct {
} LA_TmpInfo;
int lanalyzer_open(wtap *wth, int *err);
-gboolean lanalyzer_dump_open(wtap_dumper *wdh, int *err);
+gboolean lanalyzer_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int lanalyzer_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index 5e37b7c856..3d31a72920 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -1,6 +1,6 @@
/* libpcap.c
*
- * $Id: libpcap.c,v 1.78 2002/06/13 11:03:23 guy Exp $
+ * $Id: libpcap.c,v 1.79 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -1249,7 +1249,7 @@ int libpcap_dump_can_write_encap(int encap)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
+gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
{
guint32 magic;
struct pcap_hdr file_hdr;
diff --git a/wiretap/libpcap.h b/wiretap/libpcap.h
index 3e272b1abc..b7cbcb7c81 100644
--- a/wiretap/libpcap.h
+++ b/wiretap/libpcap.h
@@ -1,6 +1,6 @@
/* libpcap.h
*
- * $Id: libpcap.h,v 1.12 2002/02/27 08:57:25 guy Exp $
+ * $Id: libpcap.h,v 1.13 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -92,7 +92,7 @@ struct pcaprec_nokia_hdr {
};
int libpcap_open(wtap *wth, int *err);
-gboolean libpcap_dump_open(wtap_dumper *wdh, int *err);
+gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int libpcap_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/netmon.c b/wiretap/netmon.c
index 3de968242c..1e393b27c3 100644
--- a/wiretap/netmon.c
+++ b/wiretap/netmon.c
@@ -1,6 +1,6 @@
/* netmon.c
*
- * $Id: netmon.c,v 1.56 2002/06/07 07:27:35 guy Exp $
+ * $Id: netmon.c,v 1.57 2002/07/16 07:15:08 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -581,9 +581,16 @@ int netmon_dump_can_write_encap(int encap)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean netmon_dump_open(wtap_dumper *wdh, int *err)
+gboolean netmon_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err)
{
- /* This is a netmon file */
+ /* This is a NetMon file. We can't fill in some fields in the
+ header until all the packets have been written, so we can't
+ write to a pipe. */
+ if (cant_seek) {
+ *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
+ return FALSE;
+ }
+
wdh->subtype_write = netmon_dump;
wdh->subtype_close = netmon_dump_close;
diff --git a/wiretap/netmon.h b/wiretap/netmon.h
index 9c3611e71a..a1c2f523c5 100644
--- a/wiretap/netmon.h
+++ b/wiretap/netmon.h
@@ -1,6 +1,6 @@
/* netmon.h
*
- * $Id: netmon.h,v 1.9 2002/02/27 08:57:25 guy Exp $
+ * $Id: netmon.h,v 1.10 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -24,7 +24,7 @@
#define __NETMON_H__
int netmon_open(wtap *wth, int *err);
-gboolean netmon_dump_open(wtap_dumper *wdh, int *err);
+gboolean netmon_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int netmon_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/netxray.c b/wiretap/netxray.c
index 1500e92dde..57e54551f2 100644
--- a/wiretap/netxray.c
+++ b/wiretap/netxray.c
@@ -1,6 +1,6 @@
/* netxray.c
*
- * $Id: netxray.c,v 1.56 2002/06/07 07:27:35 guy Exp $
+ * $Id: netxray.c,v 1.57 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -549,9 +549,16 @@ int netxray_dump_can_write_encap(int encap)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err)
+gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err)
{
- /* This is a netxray file */
+ /* This is a NetXRay file. We can't fill in some fields in the header
+ until all the packets have been written, so we can't write to a
+ pipe. */
+ if (cant_seek) {
+ *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
+ return FALSE;
+ }
+
wdh->subtype_write = netxray_dump_1_1;
wdh->subtype_close = netxray_dump_close_1_1;
@@ -689,9 +696,16 @@ static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean netxray_dump_open_2_0(wtap_dumper *wdh, int *err)
+gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err)
{
- /* This is a netxray file */
+ /* This is a NetXRay file. We can't fill in some fields in the header
+ until all the packets have been written, so we can't write to a
+ pipe. */
+ if (cant_seek) {
+ *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
+ return FALSE;
+ }
+
wdh->subtype_write = netxray_dump_2_0;
wdh->subtype_close = netxray_dump_close_2_0;
diff --git a/wiretap/netxray.h b/wiretap/netxray.h
index f87229d418..1cf63abc17 100644
--- a/wiretap/netxray.h
+++ b/wiretap/netxray.h
@@ -1,6 +1,6 @@
/* netxray.h
*
- * $Id: netxray.h,v 1.8 2002/04/18 21:35:57 guy Exp $
+ * $Id: netxray.h,v 1.9 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -24,8 +24,8 @@
#define __NETXRAY_H__
int netxray_open(wtap *wth, int *err);
-gboolean netxray_dump_open_2_0(wtap_dumper *wdh, int *err);
-gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err);
+gboolean netxray_dump_open_2_0(wtap_dumper *wdh, gboolean cant_seek, int *err);
+gboolean netxray_dump_open_1_1(wtap_dumper *wdh, gboolean cant_seek, int *err);
int netxray_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c
index 219f8ec469..f975bfc970 100644
--- a/wiretap/ngsniffer.c
+++ b/wiretap/ngsniffer.c
@@ -1,6 +1,6 @@
/* ngsniffer.c
*
- * $Id: ngsniffer.c,v 1.82 2002/06/07 07:27:35 guy Exp $
+ * $Id: ngsniffer.c,v 1.83 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -1401,7 +1401,7 @@ int ngsniffer_dump_can_write_encap(int encap)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean ngsniffer_dump_open(wtap_dumper *wdh, int *err)
+gboolean ngsniffer_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
{
size_t nwritten;
char buf[6] = {REC_VERS, 0x00, 0x12, 0x00, 0x00, 0x00}; /* version record */
diff --git a/wiretap/ngsniffer.h b/wiretap/ngsniffer.h
index cde0011a30..3c5cf3b301 100644
--- a/wiretap/ngsniffer.h
+++ b/wiretap/ngsniffer.h
@@ -1,6 +1,6 @@
/* ngsniffer.h
*
- * $Id: ngsniffer.h,v 1.10 2002/02/27 08:57:25 guy Exp $
+ * $Id: ngsniffer.h,v 1.11 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -24,7 +24,7 @@
#define __NGSNIFFER_H__
int ngsniffer_open(wtap *wth, int *err);
-gboolean ngsniffer_dump_open(wtap_dumper *wdh, int *err);
+gboolean ngsniffer_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int ngsniffer_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/snoop.c b/wiretap/snoop.c
index 33817a26b3..2c3b257559 100644
--- a/wiretap/snoop.c
+++ b/wiretap/snoop.c
@@ -1,6 +1,6 @@
/* snoop.c
*
- * $Id: snoop.c,v 1.52 2002/06/07 07:27:35 guy Exp $
+ * $Id: snoop.c,v 1.53 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -597,7 +597,7 @@ int snoop_dump_can_write_encap(int encap)
/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
failure */
-gboolean snoop_dump_open(wtap_dumper *wdh, int *err)
+gboolean snoop_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
{
struct snoop_hdr file_hdr;
size_t nwritten;
diff --git a/wiretap/snoop.h b/wiretap/snoop.h
index 405ede821f..4b45a1c18e 100644
--- a/wiretap/snoop.h
+++ b/wiretap/snoop.h
@@ -1,6 +1,6 @@
/* snoop.h
*
- * $Id: snoop.h,v 1.10 2002/02/27 08:57:25 guy Exp $
+ * $Id: snoop.h,v 1.11 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -24,7 +24,7 @@
#define __W_SNOOP_H__
int snoop_open(wtap *wth, int *err);
-gboolean snoop_dump_open(wtap_dumper *wdh, int *err);
+gboolean snoop_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int snoop_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/visual.c b/wiretap/visual.c
index 41dca79594..b1d4efbf03 100644
--- a/wiretap/visual.c
+++ b/wiretap/visual.c
@@ -2,7 +2,7 @@
* File read and write routines for Visual Networks cap files.
* Copyright (c) 2001, Tom Nisbet tnisbet@visualnetworks.com
*
- * $Id: visual.c,v 1.8 2002/06/07 07:27:35 guy Exp $
+ * $Id: visual.c,v 1.9 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -412,10 +412,17 @@ int visual_dump_can_write_encap(int encap)
/* Open a file for writing.
Returns TRUE on success, FALSE on failure; sets "*err" to an
error code on failure */
-gboolean visual_dump_open(wtap_dumper *wdh, int *err)
+gboolean visual_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err)
{
struct visual_write_info *visual;
+ /* We can't fill in some fields in the header until all the packets
+ have been written, so we can't write to a pipe. */
+ if (cant_seek) {
+ *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
+ return FALSE;
+ }
+
/* Set the write routines for a visual file. */
wdh->subtype_write = visual_dump;
wdh->subtype_close = visual_dump_close;
diff --git a/wiretap/visual.h b/wiretap/visual.h
index 7102664280..0d9b02aae9 100644
--- a/wiretap/visual.h
+++ b/wiretap/visual.h
@@ -5,7 +5,7 @@
*
* Based on the code that handles netmon files.
*
- * $Id: visual.h,v 1.3 2002/02/27 08:57:25 guy Exp $
+ * $Id: visual.h,v 1.4 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -29,7 +29,7 @@
#define __VISUAL_H__
int visual_open(wtap *wth, int *err);
-gboolean visual_dump_open(wtap_dumper *wdh, int *err);
+gboolean visual_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err);
int visual_dump_can_write_encap(int encap);
#endif
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index c0cc35c003..023b93833d 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -1,6 +1,6 @@
/* wtap.c
*
- * $Id: wtap.c,v 1.66 2002/06/07 07:47:57 guy Exp $
+ * $Id: wtap.c,v 1.67 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -179,14 +179,15 @@ wtap_short_string_to_encap(const char *short_name)
}
static const char *wtap_errlist[] = {
- "The file isn't a plain file",
+ "The file isn't a plain file or pipe",
"The file is being opened for random access but is a pipe",
"The file isn't a capture file in a known format",
"File contains record data we don't support",
+ "That file format cannot be written to a pipe",
NULL,
"Files can't be saved in that format",
"Files from that network type can't be saved in that format",
- "That format doesn't support per-packet encapsulations",
+ "That file format doesn't support per-packet encapsulations",
NULL,
NULL,
"Less data was read than was expected",
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index e961d68164..7b73452804 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1,6 +1,6 @@
/* wtap.h
*
- * $Id: wtap.h,v 1.116 2002/07/12 22:52:43 guy Exp $
+ * $Id: wtap.h,v 1.117 2002/07/16 07:15:09 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -393,30 +393,32 @@ void wtap_set_bytes_dumped(wtap_dumper *wdh, long bytes_dumped);
#define WTAP_ERR_UNSUPPORTED -4
/* Supported file type, but there's something in the file we
can't support */
-#define WTAP_ERR_CANT_OPEN -5
+#define WTAP_ERR_CANT_WRITE_TO_PIPE -5
+ /* Wiretap can't save to a pipe in the specified format */
+#define WTAP_ERR_CANT_OPEN -6
/* The file couldn't be opened, reason unknown */
-#define WTAP_ERR_UNSUPPORTED_FILE_TYPE -6
+#define WTAP_ERR_UNSUPPORTED_FILE_TYPE -7
/* Wiretap can't save files in the specified format */
-#define WTAP_ERR_UNSUPPORTED_ENCAP -7
+#define WTAP_ERR_UNSUPPORTED_ENCAP -8
/* Wiretap can't read or save files in the specified format with the
specified encapsulation */
-#define WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED -8
+#define WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED -9
/* The specified format doesn't support per-packet encapsulations */
-#define WTAP_ERR_CANT_CLOSE -9
+#define WTAP_ERR_CANT_CLOSE -10
/* The file couldn't be closed, reason unknown */
-#define WTAP_ERR_CANT_READ -10
+#define WTAP_ERR_CANT_READ -11
/* An attempt to read failed, reason unknown */
-#define WTAP_ERR_SHORT_READ -11
+#define WTAP_ERR_SHORT_READ -12
/* An attempt to read read less data than it should have */
-#define WTAP_ERR_BAD_RECORD -12
+#define WTAP_ERR_BAD_RECORD -13
/* We read an invalid record */
-#define WTAP_ERR_SHORT_WRITE -13
+#define WTAP_ERR_SHORT_WRITE -14
/* An attempt to write wrote less data than it should have */
-#define WTAP_ERR_UNC_TRUNCATED -14
+#define WTAP_ERR_UNC_TRUNCATED -15
/* Sniffer compressed data was oddly truncated */
-#define WTAP_ERR_UNC_OVERFLOW -15
+#define WTAP_ERR_UNC_OVERFLOW -16
/* Uncompressing Sniffer data would overflow buffer */
-#define WTAP_ERR_UNC_BAD_OFFSET -16
+#define WTAP_ERR_UNC_BAD_OFFSET -17
/* LZ77 compressed data has bad offset to string */
/* Errors from zlib; zlib error Z_xxx turns into Wiretap error