bugfix to a bug reported by Ian Schorr:
[obnox/wireshark/wip.git] / file.c
diff --git a/file.c b/file.c
index c95f602103aebe4c6909f65ceb17e936944089e7..24f46b810061462e73c2090c37bdfa3c3e5bd84f 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.383 2004/05/09 10:03:37 guy Exp $
+ * $Id: file.c,v 1.389 2004/07/08 11:07:29 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 #include "tap_dfilter_dlg.h"
 #include "packet-data.h"
 
+/* Win32 needs the O_BINARY flag for open() */
+#ifndef O_BINARY
+#define O_BINARY       0
+#endif
+
 #ifdef HAVE_LIBPCAP
 gboolean auto_scroll_live;
 #endif
@@ -378,10 +383,6 @@ cf_read(capture_file *cf)
      bump that value by this amount. */
   progbar_quantum = cf->f_len/N_PROGBAR_UPDATES;
 
-#ifndef O_BINARY
-#define O_BINARY       0
-#endif
-
   packet_list_freeze();
 
   stop_flag = FALSE;
@@ -487,7 +488,10 @@ cf_read(capture_file *cf)
     switch (err) {
 
     case WTAP_ERR_UNSUPPORTED_ENCAP:
-      errmsg = "The capture file is for a network type that Ethereal doesn't support.";
+      snprintf(errmsg_errno, sizeof(errmsg_errno),
+               "The capture file has a packet with a network type that Ethereal doesn't support.\n(%s)",
+               err_info);
+      errmsg = errmsg_errno;
       break;
 
     case WTAP_ERR_CANT_READ:
@@ -1421,6 +1425,7 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
       ret = PSP_FAILED;
       break;
     }
+    /* Process the packet */
     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
       /* Callback failed.  We assume it reported the error appropriately. */
       ret = PSP_FAILED;
@@ -1514,14 +1519,20 @@ print_packet(capture_file *cf, frame_data *fdata,
   int             cp_off;
   gboolean        proto_tree_needed;
 
+  /* Create the protocol tree, and make it visible, if we're printing
+     the dissection or the hex data.
+     XXX - do we need it if we're just printing the hex data? */
   proto_tree_needed = 
       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex;
-
-  /* Fill in the column information, but don't bother creating
-     the logical protocol tree. */
   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
-  epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
-  epan_dissect_fill_in_columns(edt);
+
+  /* Fill in the column information if we're printing the summary
+     information. */
+  if (args->print_args->print_summary) {
+    epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
+    epan_dissect_fill_in_columns(edt);
+  } else
+    epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
 
   if (args->print_formfeed) {
     print_formfeed(args->print_fh, args->print_args->format);
@@ -1530,7 +1541,7 @@ print_packet(capture_file *cf, frame_data *fdata,
         print_line(args->print_fh, 0, args->print_args->format, "");
   }
 
-  if (args->print_args->print_summary || args->print_args->format == PR_FMT_PS) {
+  if (args->print_args->print_summary) {
     if (args->print_header_line) {
       print_line(args->print_fh, 0, args->print_args->format,
                  args->header_line_buf);
@@ -1567,9 +1578,7 @@ print_packet(capture_file *cf, frame_data *fdata,
 
     print_packet_header(args->print_fh, args->print_args->format, fdata->num, args->line_buf);
 
-    if (args->print_args->print_summary) {
-        print_line(args->print_fh, 0, args->print_args->format, args->line_buf);
-    }
+    print_line(args->print_fh, 0, args->print_args->format, args->line_buf);
   } /* if (print_summary) */
   
   if (args->print_args->print_dissections != print_dissections_none) {
@@ -1646,7 +1655,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
   callback_args.line_buf = NULL;
   callback_args.line_buf_len = 256;
   callback_args.col_widths = NULL;
-  if (print_args->print_summary || print_args->format == PR_FMT_PS) {
+  if (print_args->print_summary) {
     /* We're printing packet summaries.  Allocate the header line buffer
        and get the column widths. */
     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
@@ -1746,11 +1755,152 @@ print_packets(capture_file *cf, print_args_t *print_args)
     return PP_WRITE_ERROR;
   }
 
+  /* XXX - check for an error */
   close_print_dest(print_args->to_file, callback_args.print_fh);
 
   return PP_OK;
 }
 
+static gboolean
+write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
+                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
+                 void *argsp)
+{
+  FILE *fh = argsp;
+  epan_dissect_t *edt;
+
+  /* Create the protocol tree, but don't fill in the column information. */
+  edt = epan_dissect_new(TRUE, TRUE);
+  epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
+
+  /* Write out the information in that tree. */
+  proto_tree_write_pdml(edt, fh);
+
+  epan_dissect_free(edt);
+
+  return !ferror(fh);
+}
+
+pp_return_t
+write_pdml_packets(capture_file *cf, print_args_t *print_args)
+{
+  FILE        *fh;
+  psp_return_t ret;
+
+  fh = fopen(print_args->file, "w");
+  if (fh == NULL)
+    return PP_OPEN_ERROR;      /* attempt to open destination failed */
+
+  write_pdml_preamble(fh);
+  if (ferror(fh)) {
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  /* Iterate through the list of packets, printing the packets we were
+     told to print. */
+  ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
+                                  "selected packets", write_pdml_packet,
+                                  fh);
+
+  switch (ret) {
+
+  case PSP_FINISHED:
+    /* Completed successfully. */
+    break;
+
+  case PSP_STOPPED:
+    /* Well, the user decided to abort the printing. */
+    break;
+
+  case PSP_FAILED:
+    /* Error while printing. */
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  write_pdml_finale(fh);
+  if (ferror(fh)) {
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  /* XXX - check for an error */
+  fclose(fh);
+
+  return PP_OK;
+}
+
+static gboolean
+write_psml_packet(capture_file *cf, frame_data *fdata,
+                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
+                 void *argsp)
+{
+  FILE *fh = argsp;
+  epan_dissect_t *edt;
+
+  /* Fill in the column information, but don't create the protocol tree. */
+  edt = epan_dissect_new(FALSE, FALSE);
+  epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
+
+  /* Write out the information in that tree. */
+  proto_tree_write_psml(edt, fh);
+
+  epan_dissect_free(edt);
+
+  return !ferror(fh);
+}
+
+pp_return_t
+write_psml_packets(capture_file *cf, print_args_t *print_args)
+{
+  FILE        *fh;
+  psp_return_t ret;
+
+  fh = fopen(print_args->file, "w");
+  if (fh == NULL)
+    return PP_OPEN_ERROR;      /* attempt to open destination failed */
+
+  write_psml_preamble(fh);
+  if (ferror(fh)) {
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  /* Iterate through the list of packets, printing the packets we were
+     told to print. */
+  ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
+                                  "selected packets", write_psml_packet,
+                                  fh);
+
+  switch (ret) {
+
+  case PSP_FINISHED:
+    /* Completed successfully. */
+    break;
+
+  case PSP_STOPPED:
+    /* Well, the user decided to abort the printing. */
+    break;
+
+  case PSP_FAILED:
+    /* Error while printing. */
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  write_psml_finale(fh);
+  if (ferror(fh)) {
+    fclose(fh);
+    return PP_WRITE_ERROR;
+  }
+
+  /* XXX - check for an error */
+  fclose(fh);
+
+  return PP_OK;
+}
+
 /* Scan through the packet list and change all columns that use the
    "command-line-specified" time stamp format to use the current
    value of that format. */
@@ -2981,8 +3131,12 @@ cf_read_error_message(int err, gchar *err_info)
 
   switch (err) {
 
-  case WTAP_ERR_UNSUPPORTED:
   case WTAP_ERR_UNSUPPORTED_ENCAP:
+      snprintf(errmsg_errno, sizeof(errmsg_errno),
+               "The file \"%%s\" has a packet with a network type that Ethereal doesn't support.\n(%s)",
+               err_info);
+      break;
+
   case WTAP_ERR_BAD_RECORD:
     snprintf(errmsg_errno, sizeof(errmsg_errno),
             "An error occurred while reading from the file \"%%s\": %s.\n(%s)",