There's no need to keep a "FILE *" for the file being printed to in a
authorGuy Harris <guy@alum.mit.edu>
Sun, 25 Jan 2004 00:58:13 +0000 (00:58 -0000)
committerGuy Harris <guy@alum.mit.edu>
Sun, 25 Jan 2004 00:58:13 +0000 (00:58 -0000)
"capture_file" structure.  Keep it locally, instead.

Check for errors when printing packets.

Report failure to open a print destination and failure to write to a
print destination differently.

Don't have the "print preamble" and "print final" routines return
success/failure indications - revert to the old scheme where they
didn't, and have the callers use "ferror()" to check for errors.

Report write errors when printing dissections in Tethereal.

Report print errors as errors, not warnings.

svn path=/trunk/; revision=9828

cfile.h
file.c
file.h
gtk/follow_dlg.c
gtk/print_dlg.c
print.c
print.h
ps.h
rdps.c
tethereal.c

diff --git a/cfile.h b/cfile.h
index 2d0cac446ce67751981da60bdfda28b9cb89357b..816f672eefb4262ca298df5cd9faaa2cd90aabf0 100644 (file)
--- a/cfile.h
+++ b/cfile.h
@@ -1,7 +1,7 @@
 /* cfile.h
  * capture_file definition & GUI-independent manipulation
  *
- * $Id: cfile.h,v 1.7 2004/01/09 21:38:21 guy Exp $
+ * $Id: cfile.h,v 1.8 2004/01/25 00:58:11 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -88,7 +88,6 @@ typedef struct _capture_file {
   frame_data  *current_frame;  /* Frame data for current frame */
   epan_dissect_t *edt; /* Protocol dissection for currently selected packet */
   field_info  *finfo_selected; /* Field info for currently selected field */
-  FILE        *print_fh;  /* File we're printing to */
   struct ph_stats_s* pstats; /* accumulated stats (reset on redisplay in GUI)*/
 } capture_file;
 
diff --git a/file.c b/file.c
index 83addae9a145daaa8f2220783eeb652fa54abfea..d580bfb6c5710776b975363a3e47a2bba775f442 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.347 2004/01/24 10:53:24 guy Exp $
+ * $Id: file.c,v 1.348 2004/01/25 00:58:11 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1431,6 +1431,7 @@ retap_packets(capture_file *cf)
 
 typedef struct {
   print_args_t *print_args;
+  FILE         *print_fh;
   gboolean      print_separator;
   char         *line_buf;
   int           line_buf_len;
@@ -1484,10 +1485,10 @@ print_packet(capture_file *cf, frame_data *fdata,
         *cp++ = ' ';
     }
     *cp = '\0';
-    print_line(cf->print_fh, 0, args->print_args->format, args->line_buf);
+    print_line(args->print_fh, 0, args->print_args->format, args->line_buf);
   } else {
     if (args->print_separator)
-      print_line(cf->print_fh, 0, args->print_args->format, "");
+      print_line(args->print_fh, 0, args->print_args->format, "");
 
     /* Create the logical protocol tree, complete with the display
        representation of the items; we don't need the columns here,
@@ -1496,11 +1497,11 @@ print_packet(capture_file *cf, frame_data *fdata,
     epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
 
     /* Print the information in that tree. */
-    proto_tree_print(args->print_args, edt, cf->print_fh);
+    proto_tree_print(args->print_args, edt, args->print_fh);
 
     if (args->print_args->print_hex) {
       /* Print the full packet data as hex. */
-      print_hex_data(cf->print_fh, args->print_args->format, edt);
+      print_hex_data(args->print_fh, args->print_args->format, edt);
     }
 
     /* Print a blank line if we print anything after this. */
@@ -1508,10 +1509,10 @@ print_packet(capture_file *cf, frame_data *fdata,
   } /* if (print_summary) */
   epan_dissect_free(edt);
 
-  return TRUE;
+  return !ferror(args->print_fh);
 }
 
-int
+pp_return_t
 print_packets(capture_file *cf, print_args_t *print_args)
 {
   int         i;
@@ -1521,12 +1522,18 @@ print_packets(capture_file *cf, print_args_t *print_args)
   int         cp_off;
   int         column_len;
   int         line_len;
+  psp_return_t ret;
 
-  cf->print_fh = open_print_dest(print_args->to_file, print_args->dest);
-  if (cf->print_fh == NULL)
-    return FALSE;      /* attempt to open destination failed */
+  callback_args.print_fh = open_print_dest(print_args->to_file,
+                                           print_args->dest);
+  if (callback_args.print_fh == NULL)
+    return PP_OPEN_ERROR;      /* attempt to open destination failed */
 
-  print_preamble(cf->print_fh, print_args->format);
+  print_preamble(callback_args.print_fh, print_args->format);
+  if (ferror(callback_args.print_fh)) {
+    close_print_dest(print_args->to_file, callback_args.print_fh);
+    return PP_WRITE_ERROR;
+  }
 
   callback_args.print_args = print_args;
   callback_args.print_separator = FALSE;
@@ -1581,14 +1588,23 @@ print_packets(capture_file *cf, print_args_t *print_args)
         *cp++ = ' ';
     }
     *cp = '\0';
-    print_line(cf->print_fh, 0, print_args->format, callback_args.line_buf);
+    print_line(callback_args.print_fh, 0, print_args->format,
+               callback_args.line_buf);
   } /* if (print_summary) */
 
   /* Iterate through the list of packets, printing the packets we were
      told to print. */
-  switch (process_specified_packets(cf, &print_args->range, "Printing",
-                                    "selected packets", print_packet,
-                                    &callback_args)) {
+  ret = process_specified_packets(cf, &print_args->range, "Printing",
+                                  "selected packets", print_packet,
+                                  &callback_args);
+
+  if (callback_args.col_widths != NULL)
+    g_free(callback_args.col_widths);
+  if (callback_args.line_buf != NULL)
+    g_free(callback_args.line_buf);
+
+  switch (ret) {
+
   case PSP_FINISHED:
     /* Completed successfully. */
     break;
@@ -1597,28 +1613,31 @@ print_packets(capture_file *cf, print_args_t *print_args)
     /* Well, the user decided to abort the printing.
 
        XXX - note that what got generated before they did that
-       will get printed, as we're piping to a print program; we'd
+       will get printed if we're piping to a print program; we'd
        have to write to a file and then hand that to the print
        program to make it actually not print anything. */
     break;
 
   case PSP_FAILED:
-    /* Error while saving. */
-    break;
-  }
+    /* Error while printing.
 
-  if (callback_args.col_widths != NULL)
-    g_free(callback_args.col_widths);
-  if (callback_args.line_buf != NULL)
-    g_free(callback_args.line_buf);
-
-  print_finale(cf->print_fh, print_args->format);
+       XXX - note that what got generated before they did that
+       will get printed if we're piping to a print program; we'd
+       have to write to a file and then hand that to the print
+       program to make it actually not print anything. */
+    close_print_dest(print_args->to_file, callback_args.print_fh);
+    return PP_WRITE_ERROR;
+  }
 
-  close_print_dest(print_args->to_file, cf->print_fh);
+  print_finale(callback_args.print_fh, print_args->format);
+  if (ferror(callback_args.print_fh)) {
+    close_print_dest(print_args->to_file, callback_args.print_fh);
+    return PP_WRITE_ERROR;
+  }
 
-  cf->print_fh = NULL;
+  close_print_dest(print_args->to_file, callback_args.print_fh);
 
-  return TRUE;
+  return PP_OK;
 }
 
 /* Scan through the packet list and change all columns that use the
diff --git a/file.h b/file.h
index 55ec3457948a253951ec74d4094742c90ff02e22..f9a6968713897ff3d037154e4842dac50e1bd8be 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.113 2004/01/24 02:01:42 guy Exp $
+ * $Id: file.h,v 1.114 2004/01/25 00:58:12 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -57,7 +57,12 @@ void reftime_packets(capture_file *);
 void colorize_packets(capture_file *);
 void redissect_packets(capture_file *cf);
 int retap_packets(capture_file *cf);
-int print_packets(capture_file *cf, print_args_t *print_args);
+typedef enum {
+       PP_OK,
+       PP_OPEN_ERROR,
+       PP_WRITE_ERROR
+} pp_return_t;
+pp_return_t print_packets(capture_file *cf, print_args_t *print_args);
 void change_time_formats(capture_file *);
 
 gboolean find_packet_protocol_tree(capture_file *cf, const char *string);
index 043a1955ef494cb229b8f7bd79ebe0afcaefc7f6..7e67f3538f5daaa092cb3b8bfaea203caaded65a 100644 (file)
@@ -1,6 +1,6 @@
 /* follow_dlg.c
  *
- * $Id: follow_dlg.c,v 1.36 2004/01/24 10:53:25 guy Exp $
+ * $Id: follow_dlg.c,v 1.37 2004/01/25 00:58:12 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -774,7 +774,8 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
        return;
     }
 
-    if (!print_preamble(fh, PR_FMT_TEXT)) {
+    print_preamble(fh, PR_FMT_TEXT);
+    if (ferror(fh)) {
        if (to_file) {
            simple_dialog(ESD_TYPE_WARN, NULL,
                          file_write_error_message(errno), prefs.pr_file);
@@ -791,7 +792,8 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
     args.filename = prefs.pr_file;
     args.fh = fh;
     follow_read_stream(follow_info, follow_print_text, &args);
-    if (!print_finale(fh, PR_FMT_TEXT)) {
+    print_finale(fh, PR_FMT_TEXT);
+    if (ferror(fh)) {
        if (to_file) {
            simple_dialog(ESD_TYPE_WARN, NULL,
                          file_write_error_message(errno), prefs.pr_file);
index b7a9ecc1c9488f433db3a9dcd79b77a28fc95897..c08c686e257a4abf4599d8397faacec1272c7532 100644 (file)
@@ -1,7 +1,7 @@
 /* print_dlg.c
  * Dialog boxes for printing
  *
- * $Id: print_dlg.c,v 1.56 2004/01/21 21:19:33 ulfl Exp $
+ * $Id: print_dlg.c,v 1.57 2004/01/25 00:58:13 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -26,6 +26,8 @@
 #include "config.h"
 #endif
 
+#include <string.h>
+
 #include <gtk/gtk.h>
 
 #include "globals.h"
@@ -833,13 +835,28 @@ print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
   gtk_widget_destroy(GTK_WIDGET(parent_w));
 
   /* Now print the packets */
-  if (!print_packets(&cfile, &print_args)) {
+  switch (print_packets(&cfile, &print_args)) {
+
+  case PP_OK:
+    break;
+
+  case PP_OPEN_ERROR:
     if (print_args.to_file)
-      simple_dialog(ESD_TYPE_WARN, NULL,
-        file_write_error_message(errno), print_args.dest);
+      simple_dialog(ESD_TYPE_CRIT, NULL,
+        file_open_error_message(errno, TRUE), print_args.dest);
     else
-      simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
+      simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't run print command %s.",
         print_args.dest);
+    break;
+
+  case PP_WRITE_ERROR:
+    if (print_args.to_file)
+      simple_dialog(ESD_TYPE_CRIT, NULL,
+        file_write_error_message(errno), print_args.dest);
+    else
+      simple_dialog(ESD_TYPE_CRIT, NULL,
+       "Error writing to print command: %s", strerror(errno));
+    break;
   }
 
 #ifdef _WIN32
diff --git a/print.c b/print.c
index e96b2e67d56aae83ee7875c4d24782c140b70131..99b20c2fa1b790f651dc3a62282a7f074458270c 100644 (file)
--- a/print.c
+++ b/print.c
@@ -1,7 +1,7 @@
 /* print.c
  * Routines for printing packet analysis trees.
  *
- * $Id: print.c,v 1.70 2004/01/24 10:53:24 guy Exp $
+ * $Id: print.c,v 1.71 2004/01/25 00:58:12 guy Exp $
  *
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
@@ -650,31 +650,27 @@ void ps_clean_string(unsigned char *out, const unsigned char *in,
 }
 
 /* Some formats need stuff at the beginning of the output */
-gboolean
+void
 print_preamble(FILE *fh, gint format)
 {
        if (format == PR_FMT_PS)
-               return !print_ps_preamble(fh);
+               print_ps_preamble(fh);
        else if (format == PR_FMT_PDML) {
                fputs("<?xml version=\"1.0\"?>\n", fh);
                fputs("<pdml version=\"" PDML_VERSION "\" ", fh);
                fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION);
-               return !ferror(fh);
-       } else
-               return TRUE;
+       }
 }
 
 /* Some formats need stuff at the end of the output */
-gboolean
+void
 print_finale(FILE *fh, gint format)
 {
        if (format == PR_FMT_PS)
-               return !print_ps_finale(fh);
+               print_ps_finale(fh);
        else if (format == PR_FMT_PDML) {
                fputs("</pdml>\n", fh);
-               return !ferror(fh);
-       } else
-               return TRUE;
+       }
 }
 
 void
diff --git a/print.h b/print.h
index 0771ba43357092ea5a0ad462ce6409c56869b774..a6bc44d35359661e2101fcc6c016b8b3ec78edec 100644 (file)
--- a/print.h
+++ b/print.h
@@ -1,7 +1,7 @@
 /* print.h
  * Definitions for printing packet analysis trees.
  *
- * $Id: print.h,v 1.35 2004/01/24 10:53:24 guy Exp $
+ * $Id: print.h,v 1.36 2004/01/25 00:58:12 guy Exp $
  *
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
@@ -66,8 +66,8 @@ typedef struct {
 
 FILE *open_print_dest(int to_file, const char *dest);
 gboolean close_print_dest(int to_file, FILE *fh);
-gboolean print_preamble(FILE *fh, gint format);
-gboolean print_finale(FILE *fh, gint format);
+void print_preamble(FILE *fh, gint format);
+void print_finale(FILE *fh, gint format);
 void proto_tree_print(print_args_t *print_args, epan_dissect_t *edt,
     FILE *fh);
 void print_hex_data(FILE *fh, gint format, epan_dissect_t *edt);
diff --git a/ps.h b/ps.h
index c9dc3dcdf1dedc77fb6b96aad98c358363231624..a41d0f245a2c43c9abe4d9e1b8e13dc8bcd2a47d 100644 (file)
--- a/ps.h
+++ b/ps.h
@@ -1,7 +1,7 @@
 /* ps.h
  * Definitions for generating PostScript(R) packet output.
  *
- * $Id: ps.h,v 1.6 2004/01/24 10:53:24 guy Exp $
+ * $Id: ps.h,v 1.7 2004/01/25 00:58:12 guy Exp $
  *
  * Gilbert Ramirez <gram@alumni.rice.edu>
  *
@@ -29,7 +29,7 @@
 
 /* Functions in ps.c; automatically generated by rdps */
 
-int print_ps_preamble(FILE *);
-int print_ps_finale(FILE *);
+void print_ps_preamble(FILE *);
+void print_ps_finale(FILE *);
 
 #endif /* ps.h */
diff --git a/rdps.c b/rdps.c
index 69af5be2bafc40c40d485981afa649d44ef58501..1a54c1bdc97b159df39b179eaa07707532d0d37e 100644 (file)
--- a/rdps.c
+++ b/rdps.c
@@ -1,6 +1,7 @@
 /* rdps.c
  *
- * $Id: rdps.c,v 1.7 2004/01/24 10:53:25 guy Exp $
+ * $Id: rdps.c,v 1.8 2004/01/25 00:58:12 guy Exp $
+ * 
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
@@ -127,7 +128,7 @@ int main(int argc, char **argv)
 void start_code(FILE *fd, char *func)
 {
        fprintf(fd, "/* Created by rdps.c. Do not edit! */\n");
-       fprintf(fd, "int print_ps_%s(FILE *fd) {\n", func);
+       fprintf(fd, "void print_ps_%s(FILE *fd) {\n", func);
 }
 
 void write_code(FILE *fd, char *string)
@@ -139,7 +140,6 @@ void write_code(FILE *fd, char *string)
 
 void end_code(FILE *fd)
 {
-       fprintf(fd, "\treturn ferror(fd);\n");
        fprintf(fd, "}\n\n\n");
 }
 
index 3ae5cb807197b806d59e0310ab69aaf7949460f8..e997df7f399ac99cfe8ba6c5c6d0bd2b43c0e52e 100644 (file)
@@ -1,6 +1,6 @@
 /* tethereal.c
  *
- * $Id: tethereal.c,v 1.224 2004/01/24 01:44:28 guy Exp $
+ * $Id: tethereal.c,v 1.225 2004/01/25 00:58:12 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -172,6 +172,7 @@ static void wtap_dispatch_cb_write(guchar *, const struct wtap_pkthdr *, long,
 static void show_capture_file_io_error(const char *, int, gboolean);
 static void wtap_dispatch_cb_print(guchar *, const struct wtap_pkthdr *, long,
     union wtap_pseudo_header *, const guchar *);
+static void show_print_file_io_error(int err);
 static char *cf_open_error_message(int err, gboolean for_writing,
     int file_type);
 #ifdef HAVE_LIBPCAP
@@ -2269,11 +2270,23 @@ load_cap_file(capture_file *cf, int out_file_type)
     args.cf = cf;
     args.pdh = NULL;
     print_preamble(stdout, print_format);
+    if (ferror(stdout)) {
+      err = errno;
+      show_print_file_io_error(err);
+      goto out;
+    }
     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (guchar *) &args,
                        &err);
-    print_finale(stdout, print_format);
   }
-  if (!success) {
+  if (success) {
+    if (cf->save_file == NULL) {
+      print_finale(stdout, print_format);
+      if (ferror(stdout)) {
+        err = errno;
+        show_print_file_io_error(err);
+      }
+    }
+  } else {
     /* Print up a message box noting that the read failed somewhere along
        the line. */
     switch (err) {
@@ -2816,6 +2829,33 @@ wtap_dispatch_cb_print(guchar *user, const struct wtap_pkthdr *phdr,
   clear_fdata(&fdata);
 }
 
+static void
+show_print_file_io_error(int err)
+{
+  switch (err) {
+
+  case ENOSPC:
+    fprintf(stderr,
+"tethereal: Not all the packets could be printed because there is "
+"no space left on the file system.\n");
+    break;
+
+#ifdef EDQUOT
+  case EDQUOT:
+    fprintf(stderr,
+"tethereal: Not all the packets could be printed because you are "
+"too close to, or over your disk quota.\n");
+  break;
+#endif
+
+  default:
+    fprintf(stderr,
+"tethereal: An error occurred while printing packets: %s.\n",
+      strerror(err));
+    break;
+  }
+}
+
 static char *
 cf_open_error_message(int err, gboolean for_writing, int file_type)
 {