Add a routine to report write errors to the list of failure-reporting
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 15 Feb 2009 21:47:57 +0000 (21:47 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 15 Feb 2009 21:47:57 +0000 (21:47 +0000)
routines handled by epan/report_err.c.

Move copy_binary_file() in file.c to epan/filesystem.c, and rename it to
copy_file_binary_mode() (to clarify that it *can* copy text files;
arguably, *all* files are "binary" unless you're on, say, an IBM 1401
:-)).  Have it use the report_err.c routines, so it works in
console-mode programs.

Clean up some comments while we're at it.

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

13 files changed:
capinfos.c
dftest.c
editcap.c
epan/epan.c
epan/epan.h
epan/filesystem.c
epan/filesystem.h
epan/report_err.c
epan/report_err.h
file.c
gtk/main.c
rawshark.c
tshark.c

index 5941fffa87485248d25830a8593a10308016e6a3..1eb6b6a7e3ffd4f1a7c2492ee98cc9dc612b238b 100644 (file)
@@ -306,7 +306,7 @@ main(int argc, char *argv[])
                g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error);
                g_free(init_progfile_dir_error);
     } else {
-               init_report_err(failure_message,NULL,NULL);
+               init_report_err(failure_message,NULL,NULL,NULL);
                init_plugins();
     }
 #endif
index 7317f3b561657fea25d37485abce2fe4ef7ff569..84b198cbde65e2272d56959c446736de152180a7 100644 (file)
--- a/dftest.c
+++ b/dftest.c
@@ -1,4 +1,5 @@
-/* dftest.c.c
+/* dftest.c
+ * Shows display filter byte-code, for debugging dfilter routines.
  *
  * $Id$
  *
@@ -6,8 +7,6 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * Shows display filter byte-code, for debugging dfilter routines.
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -55,6 +54,7 @@ static void failure_message(const char *msg_format, va_list ap);
 static void open_failure_message(const char *filename, int err,
     gboolean for_writing);
 static void read_failure_message(const char *filename, int err);
+static void write_failure_message(const char *filename, int err);
 
 int
 main(int argc, char **argv)
@@ -89,7 +89,8 @@ main(int argc, char **argv)
           in case any dissectors register preferences. */
        epan_init(register_all_protocols,
                  register_all_protocol_handoffs, NULL, NULL,
-                 failure_message, open_failure_message, read_failure_message);
+                 failure_message, open_failure_message, read_failure_message,
+                 write_failure_message);
 
        /* now register the preferences for any non-dissector modules.
        we must do that before we read the preferences as well. */
@@ -191,3 +192,13 @@ read_failure_message(const char *filename, int err)
        fprintf(stderr, "dftest: An error occurred while reading from the file \"%s\": %s.\n",
            filename, strerror(err));
 }
+
+/*
+ * Write errors are reported with an console message in "dftest".
+ */
+static void
+write_failure_message(const char *filename, int err)
+{
+       fprintf(stderr, "dftest: An error occurred while writing to the file \"%s\": %s.\n",
+           filename, strerror(err));
+}
index b91902cc0b4e9db55d8345d7a6f4eec963923dd2..8c541e1b9cbdba5226cb9c49e47008ec02438f4a 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -428,7 +428,7 @@ main(int argc, char *argv[])
     g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error);
     g_free(init_progfile_dir_error);
   } else {
-    init_report_err(failure_message,NULL,NULL);
+    init_report_err(failure_message,NULL,NULL,NULL);
     init_plugins();
   }
 #endif
index c835defd85cd624f99092c9c13a12e9432def498..7e496c008f4d98c5890fd3954dd0c8bd25dbf6ba 100644 (file)
@@ -75,9 +75,11 @@ epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_da
          gpointer client_data,
          void (*report_failure)(const char *, va_list),
          void (*report_open_failure)(const char *, int, gboolean),
-         void (*report_read_failure)(const char *, int))
+         void (*report_read_failure)(const char *, int),
+         void (*report_write_failure)(const char *, int))
 {
-       init_report_err(report_failure, report_open_failure, report_read_failure);
+       init_report_err(report_failure, report_open_failure,
+           report_read_failure, report_write_failure);
 
        /* initialize memory allocation subsystem */
        ep_init_chunk();
index c8b72d080b6569103dbe3ef4c7e30fb14d373732..01a8a849575e5f1550a38b52f9b9eddf37bee1ca 100644 (file)
@@ -40,11 +40,15 @@ void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer clie
               void *client_data,
               void (*report_failure)(const char *, va_list),
               void (*report_open_failure)(const char *, int, gboolean),
-              void (*report_read_failure)(const char *, int));
+              void (*report_read_failure)(const char *, int),
+              void (*report_write_failure)(const char *, int));
+
 /* cleanup the whole epan module, this is used to be called only once in a program */
 void epan_cleanup(void);
+
 /* Initialize the table of conversations. */
 void epan_conversation_init(void);
+
 /* Initialize the table of circuits. */
 /* XXX - what is a circuit and should this better be combined with epan_conversation_init? */
 void epan_circuit_init(void);
index 6632eb1c82fa6adf917fd4aba2051683919bd47f..cf1a347720bdfd8ab9b361396782e5f61348cbd4 100644 (file)
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 #endif
 
 #include "filesystem.h"
+#include "report_err.h"
 #include <wsutil/privileges.h>
 #include <wsutil/file_util.h>
 
+#include <wiretap/wtap.h>      /* for WTAP_ERR_SHORT_WRITE */
+
 #define PROFILES_DIR    "profiles"
 #define U3_MY_CAPTURES  "\\My Captures"
 
@@ -1552,6 +1559,72 @@ files_identical(const char *fname1, const char *fname2)
 #endif
 }
 
+/*
+ * Copy a file in binary mode, for those operating systems that care about
+ * such things.  This should be OK for all files, even text files, as
+ * we'll copy the raw bytes, and we don't look at the bytes as we copy
+ * them.
+ *
+ * Returns TRUE on success, FALSE on failure. If a failure, it also
+ * displays a simple dialog window with the error message.
+ */
+gboolean
+copy_file_binary_mode(const char *from_filename, const char *to_filename)
+{
+  int           from_fd, to_fd, nread, nwritten, err;
+  guint8        pd[65536];
+
+  /* Copy the raw bytes of the file. */
+  from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
+  if (from_fd < 0) {
+    report_open_failure(from_filename, errno, FALSE);
+    goto done;
+  }
+
+  /* Use open() instead of creat() so that we can pass the O_BINARY
+     flag, which is relevant on Win32; it appears that "creat()"
+     may open the file in text mode, not binary mode, but we want
+     to copy the raw bytes of the file, so we need the output file
+     to be open in binary mode. */
+  to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+  if (to_fd < 0) {
+    report_open_failure(to_filename, errno, TRUE);
+    ws_close(from_fd);
+    goto done;
+  }
+
+  while ((nread = ws_read(from_fd, pd, sizeof pd)) > 0) {
+    nwritten = ws_write(to_fd, pd, nread);
+    if (nwritten < nread) {
+      if (nwritten < 0)
+       err = errno;
+      else
+       err = WTAP_ERR_SHORT_WRITE;
+      report_write_failure(to_filename, err);
+      ws_close(from_fd);
+      ws_close(to_fd);
+      goto done;
+    }
+  }
+  if (nread < 0) {
+    err = errno;
+    report_read_failure(from_filename, err);
+    ws_close(from_fd);
+    ws_close(to_fd);
+    goto done;
+  }
+  ws_close(from_fd);
+  if (ws_close(to_fd) < 0) {
+    report_write_failure(to_filename, errno);
+    goto done;
+  }
+
+  return TRUE;
+
+done:
+  return FALSE;
+}
+
 /*
  * Editor modelines
  *
@@ -1564,4 +1637,3 @@ files_identical(const char *fname1, const char *fname2)
  * ex: set shiftwidth=4 tabstop=4 noexpandtab
  * :indentSize=4:tabSize=4:noTabs=false:
  */
-
index b8dba0fcd5ccfdc9f2fa48b1f53d55f94bc2fd69..a97f8d7880639c361d0fef4d523c13337741944e 100644 (file)
@@ -234,10 +234,22 @@ extern gboolean deletefile (const char *path);
 extern gboolean file_exists(const char *fname);
 
 /*
- * Check, if two filenames are identical (with absolute and relative paths).
+ * Check if two filenames are identical (with absolute and relative paths).
  */
 extern gboolean files_identical(const char *fname1, const char *fname2);
 
+/*
+ * Copy a file in binary mode, for those operating systems that care about
+ * such things.  This should be OK for all files, even text files, as
+ * we'll copy the raw bytes, and we don't look at the bytes as we copy
+ * them.
+ *
+ * Returns TRUE on success, FALSE on failure. If a failure, it also
+ * displays a simple dialog window with the error message.
+ */
+extern gboolean copy_file_binary_mode(const char *from_filename,
+    const char *to_filename);
+
 #ifdef _WIN32
 /*
  * utf8 version of getenv, needed to get win32 filename paths
index 68924c64b8d4f0334aff659cd3c265fedd1b7633..ca03bb210caf11b63d1bbf068086e70e243bce34 100644 (file)
@@ -1,6 +1,13 @@
-/* report_err.h
-* Declarations of routines for dissectors to use to report errors to
-* the user (e.g., problems with preference settings)
+/* report_err.c
+* Routines for code that can run in GUI and command-line environments to
+* use to report errors to the user (e.g., I/O errors, or problems with
+* preference settings).
+*
+* The application using libwireshark will register error-reporting
+* routines, and the routines defined here will call the registered
+* routines.  That way, these routines can be called by code that
+* doesn't itself know whether to pop up a dialog or print something
+* to the standard error.
 *
 * $Id$
 *
 static void (*report_failure_func)(const char *, va_list);
 static void (*report_open_failure_func)(const char *, int, gboolean);
 static void (*report_read_failure_func)(const char *, int);
+static void (*report_write_failure_func)(const char *, int);
 
 void init_report_err(void (*report_failure)(const char *, va_list),
                                         void (*report_open_failure)(const char *, int, gboolean),
-                                        void (*report_read_failure)(const char *, int)) {
+                                        void (*report_read_failure)(const char *, int),
+                                        void (*report_write_failure)(const char *, int))
+{
        report_failure_func = report_failure;
        report_open_failure_func = report_open_failure;
        report_read_failure_func = report_read_failure;
+       report_write_failure_func = report_write_failure;
 }
 
 /*
@@ -78,3 +89,12 @@ report_read_failure(const char *filename, int err)
        (*report_read_failure_func)(filename, err);
 }
 
+/*
+ * Report an error when trying to write a file.
+ * "err" is assumed to be a UNIX-style errno.
+ */
+void
+report_write_failure(const char *filename, int err)
+{
+       (*report_write_failure_func)(filename, err);
+}
index 159cd96ceeb214271cfdeea406572252b8a25cfe..9717221424c8ea2b6e9c0a9b248c0d7b5a7b8fbd 100644 (file)
@@ -1,6 +1,13 @@
 /* report_err.h
- * Declarations of routines for dissectors to use to report errors to
- * the user (e.g., problems with preference settings)
+ * Declarations of routines for code that can run in GUI and command-line
+ * environments to use to report errors to the user (e.g., I/O errors, or
+ * problems with preference settings).
+ *
+ * The application using libwireshark will register error-reporting
+ * routines, and the routines declared here will call the registered
+ * routines.  That way, these routines can be called by code that
+ * doesn't itself know whether to pop up a dialog or print something
+ * to the standard error.
  *
  * $Id$
  *
@@ -36,23 +43,34 @@ extern "C" {
 extern void init_report_err(
        void (*report_failure)(const char *, va_list),
        void (*report_open_failure)(const char *, int, gboolean),
-       void (*report_read_failure)(const char *, int));
+       void (*report_read_failure)(const char *, int),
+       void (*report_write_failure)(const char *, int));
+
+/*
+ * Report a general error.
+ */
+extern void report_failure(const char *msg_format, ...);
 
 /*
  * Report an error when trying to open a file.
+ * "err" is assumed to be an error code from Wiretap; positive values are
+ * UNIX-style errnos, so this can be used for open failures not from
+ * Wiretap as long as the failure code is just an errno.
  */
 extern void report_open_failure(const char *filename, int err,
     gboolean for_writing);
 
 /*
  * Report an error when trying to read a file.
+ * "err" is assumed to be a UNIX-style errno.
  */
 extern void report_read_failure(const char *filename, int err);
 
 /*
- * Report a general error.
+ * Report an error when trying to write a file.
+ * "err" is assumed to be a UNIX-style errno.
  */
-extern void report_failure(const char *msg_format, ...);
+extern void report_write_failure(const char *filename, int err);
 
 #ifdef __cplusplus
 }
diff --git a/file.c b/file.c
index ca4e22911ba54523444d1406e9d2ba12d712d714..28fd5a9b99366d2b140312d72db80df583b92299 100644 (file)
--- a/file.c
+++ b/file.c
 #include <fcntl.h>
 #endif
 
-#ifdef NEED_STRERROR_H
-#include "strerror.h"
-#endif
-
 #include <epan/epan.h>
 #include <epan/filesystem.h>
 
@@ -117,7 +113,6 @@ static void cf_open_failure_alert_box(const char *filename, int err,
 static const char *file_rename_error_message(int err);
 static void cf_write_failure_alert_box(const char *filename, int err);
 static void cf_close_failure_alert_box(const char *filename, int err);
-static   gboolean copy_binary_file(const char *from_filename, const char *to_filename);
 
 /* Update the progress bar this many times when reading a file. */
 #define N_PROGBAR_UPDATES      100
@@ -3575,7 +3570,7 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
 
     if (do_copy) {
       /* Copy the file, if we haven't moved it. */
-      if (!copy_binary_file(from_filename, fname))
+      if (!copy_file_binary_mode(from_filename, fname))
        goto fail;
     }
   } else {
@@ -3957,67 +3952,3 @@ cf_reload(capture_file *cf) {
      we should free up our copy. */
   g_free(filename);
 }
-
-/* Copies a file in binary mode, for those operating systems that care about
- * such things.
- * Returns TRUE on success, FALSE on failure. If a failure, it also
- * displays a simple dialog window with the error message.
- */
-static gboolean
-copy_binary_file(const char *from_filename, const char *to_filename)
-{
-  int           from_fd, to_fd, nread, nwritten, err;
-  guint8        pd[65536];
-
-  /* Copy the raw bytes of the file. */
-  from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
-  if (from_fd < 0) {
-    open_failure_alert_box(from_filename, errno, FALSE);
-    goto done;
-  }
-
-  /* Use open() instead of creat() so that we can pass the O_BINARY
-     flag, which is relevant on Win32; it appears that "creat()"
-     may open the file in text mode, not binary mode, but we want
-     to copy the raw bytes of the file, so we need the output file
-     to be open in binary mode. */
-  to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-  if (to_fd < 0) {
-    open_failure_alert_box(to_filename, errno, TRUE);
-    ws_close(from_fd);
-    goto done;
-  }
-
-  while ((nread = ws_read(from_fd, pd, sizeof pd)) > 0) {
-    nwritten = ws_write(to_fd, pd, nread);
-    if (nwritten < nread) {
-      if (nwritten < 0)
-       err = errno;
-      else
-       err = WTAP_ERR_SHORT_WRITE;
-      write_failure_alert_box(to_filename, err);
-      ws_close(from_fd);
-      ws_close(to_fd);
-      goto done;
-    }
-  }
-  if (nread < 0) {
-    err = errno;
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                 "An error occurred while reading from the file \"%s\": %s.",
-                 from_filename, strerror(err));
-    ws_close(from_fd);
-    ws_close(to_fd);
-    goto done;
-  }
-  ws_close(from_fd);
-  if (ws_close(to_fd) < 0) {
-    write_failure_alert_box(to_filename, errno);
-    goto done;
-  }
-
-  return TRUE;
-
-done:
-  return FALSE;
-}
index ed50229ae254dcb0de56b1837fa37ebe6b64f95c..38d8eed4f50cea40777e2acd80d8adf43abe2aa7 100644 (file)
@@ -2016,7 +2016,8 @@ main(int argc, char *argv[])
      case any dissectors register preferences. */
   epan_init(register_all_protocols,register_all_protocol_handoffs,
            splash_update, (gpointer) splash_win,
-            failure_alert_box,open_failure_alert_box,read_failure_alert_box);
+            failure_alert_box,open_failure_alert_box,read_failure_alert_box,
+            write_failure_alert_box);
 
   splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
 
index dd5cc11036f190b29dbddd26ddc06919ed820962..9dc10bcb7bbe496ec6f8c1f658bb7ccfc1731906 100644 (file)
@@ -154,6 +154,7 @@ static void open_failure_message(const char *filename, int err,
     gboolean for_writing);
 static void failure_message(const char *msg_format, va_list ap);
 static void read_failure_message(const char *filename, int err);
+static void write_failure_message(const char *filename, int err);
 static void protocolinfo_init(char *field);
 static gboolean parse_field_string_format(char *format);
 
@@ -492,7 +493,8 @@ main(int argc, char *argv[])
      dissectors, and we must do it before we read the preferences, in
      case any dissectors register preferences. */
   epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL,
-            failure_message, open_failure_message, read_failure_message);
+            failure_message, open_failure_message, read_failure_message,
+            write_failure_message);
 
   /* Now register the preferences for any non-dissector modules.
      We must do that before we read the preferences as well. */
@@ -1625,6 +1627,16 @@ read_failure_message(const char *filename, int err)
           filename, strerror(err));
 }
 
+/*
+ * Write errors are reported with an console message in Rawshark.
+ */
+static void
+write_failure_message(const char *filename, int err)
+{
+  cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
+          filename, strerror(err));
+}
+
 /*
  * Report an error in command-line arguments.
  */
index 3c1cedaa1bb40af8fccf5ebab333dbaaa1107ff3..fbbec6653695145ecfe202cdf57575a09e877495 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -1,4 +1,7 @@
 /* tshark.c
+ *
+ * Text-mode variant of Wireshark, along the lines of tcpdump and snoop,
+ * by Gilbert Ramirez <gram@alumni.rice.edu> and Guy Harris <guy@alum.mit.edu>.
  *
  * $Id$
  *
@@ -6,9 +9,6 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * Text-mode variant, by Gilbert Ramirez <gram@alumni.rice.edu>
- * and Guy Harris <guy@alum.mit.edu>.
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -179,6 +179,7 @@ static void open_failure_message(const char *filename, int err,
     gboolean for_writing);
 static void failure_message(const char *msg_format, va_list ap);
 static void read_failure_message(const char *filename, int err);
+static void write_failure_message(const char *filename, int err);
 
 capture_file cfile;
 
@@ -834,7 +835,8 @@ main(int argc, char *argv[])
      dissectors, and we must do it before we read the preferences, in
      case any dissectors register preferences. */
   epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL,
-            failure_message, open_failure_message, read_failure_message);
+            failure_message, open_failure_message, read_failure_message,
+            write_failure_message);
 
   /* Register all tap listeners; we do this before we parse the arguments,
      as the "-z" argument can specify a registered tap. */
@@ -3132,6 +3134,16 @@ read_failure_message(const char *filename, int err)
           filename, strerror(err));
 }
 
+/*
+ * Write errors are reported with an console message in TShark.
+ */
+static void
+write_failure_message(const char *filename, int err)
+{
+  cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
+          filename, strerror(err));
+}
+
 /*
  * Report an error in command-line arguments.
  */