From Graeme Hewson:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 16 Jul 2002 07:15:09 +0000 (07:15 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 16 Jul 2002 07:15:09 +0000 (07:15 +0000)
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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@5884 f5534014-38df-0310-8fa8-9805f1628bb7

22 files changed:
capture.c
doc/tethereal.pod.template
file.c
file.h
tethereal.c
wiretap/file.c
wiretap/lanalyzer.c
wiretap/lanalyzer.h
wiretap/libpcap.c
wiretap/libpcap.h
wiretap/netmon.c
wiretap/netmon.h
wiretap/netxray.c
wiretap/netxray.h
wiretap/ngsniffer.c
wiretap/ngsniffer.h
wiretap/snoop.c
wiretap/snoop.h
wiretap/visual.c
wiretap/visual.h
wiretap/wtap.c
wiretap/wtap.h

index bc96b585e31508ccd70ebc2ae1c83b07ca17ffde..064072771378973ce0b0de4930ec4fb9be6ab229 100644 (file)
--- 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;
   }
index 84a675bdb77dbf8d2b39cb2b9021b07a7509f45a..e9114cdbd6ba61309090767ee8c36c88b5c05dab 100644 (file)
@@ -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 59d1c44c127917e82b80c7bb5cb0532f715eb334..a08c3f0cdec74fe247f236655603acd71752b059 100644 (file)
--- 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 75e516a67524b7222bc8c65cf65201483865687f..615c57f7c9adaaedfefe88d01f9a0c452de48d3c 100644 (file)
--- 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);
 
index 7ded2b48acd0fe803882324f782ded502fb8c552..b9be16df37605d7f233bdf2ea0653de07bc0d204 100644 (file)
@@ -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);
 }
index 036b9057dc9577e25137569470e6814b4bc74d64..3253ecb9746c64b6a840383e17cd1cff0128069b 100644 (file)
@@ -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);
index 18b8571c0581b5aeb65bccf1899d14c820775cd4..095f9d5e0c54eb03ada267ed54c3d9656d56983a 100644 (file)
@@ -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) {
index e42a34769957ac61577e33f7bd8443c6bbf91677..42d030d0341eb4f08e61527bfb5df794f396a8df 100644 (file)
@@ -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
index 5e37b7c856040cfb9a696b554e85d318a6a24d0e..3d31a7292081ca9265ec59090b1508c564267367 100644 (file)
@@ -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;
index 3e272b1abc65f06e80bf202e37cb599af05566a4..b7cbcb7c81240a730e5fb3d5791566d36c02767a 100644 (file)
@@ -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
index 3de968242c9f1886c7bc9c0bd445461675c75849..1e393b27c3997b2fd93021313291b1495d276a21 100644 (file)
@@ -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;
 
index 9c3611e71a6da55f5414e13c1e1ccc346629c5f9..a1c2f523c5ab67677a0dcf95fa11ceecd0657cd2 100644 (file)
@@ -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
index 1500e92dde7da2506be51d09b5d7863789122043..57e54551f2657f1c651a14c7cbf00c1d67aa580b 100644 (file)
@@ -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;
 
index f87229d418e5aee39c6b4a0cd452ac830d64ad35..1cf63abc178f4ef669b1639545010b9d26976f8b 100644 (file)
@@ -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
index 219f8ec4697c27e3b01c671154e3f6914eaec151..f975bfc9706e25eaf76aca9ccd3695844416a0f6 100644 (file)
@@ -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 */
index cde0011a301ff93e07c6c2e3c76bfa7030e2b953..3c5cf3b3015f93174083f6403e87e15bd724b502 100644 (file)
@@ -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
index 33817a26b3c2223715d2bead7a288b07fcaaaa6f..2c3b2575593cd43f02711cb03f79b35a5d74e565 100644 (file)
@@ -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;
index 405ede821fe80a12d4b9ded17865b89a9b0bcaaa..4b45a1c18ec7a55baa105cb7a3e35b48e32ef648 100644 (file)
@@ -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
index 41dca795948976aa77833592d0e954ea931380f9..b1d4efbf03b512128923ab850d68e18edf25527e 100644 (file)
@@ -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;
index 7102664280aae5436293c43864f48d7daa30ccf4..0d9b02aae92d84c0b8203d89ab4857be263359c7 100644 (file)
@@ -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
index c0cc35c00390a5339cd2b195646ebb1784343dbc..023b93833dcee0575d4ca69b9e8fe790788d36f3 100644 (file)
@@ -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",
index e961d681648c93260d143db2b418842bc299a497..7b7345280498c32d74a7ae2fdef59157bf7b5526 100644 (file)
@@ -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