From Graeme Hewson:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 9 Sep 2002 20:39:01 +0000 (20:39 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 9 Sep 2002 20:39:01 +0000 (20:39 +0000)
Currently Ethereal sets and uses a default directory for reading
and writing, but only in some places.  This set of patches extends
the setting of the default directory to the -w option as well as
the -r option, and causes all file dialogs to use and set the
default consistently.  (I haven't changed the
Preferences/Printing/File dialog, though, as that's a special
case.)

There's also a fix for a bug where Ethereal was issuing the
message "Ring buffer requested, but capture isn't being saved to
a permanent file" even though a file was specified with -w.

There also appear to be some other cleanups in his patch.

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

12 files changed:
capture.c
capture.h
gtk/capture_dlg.c
gtk/file_dlg.c
gtk/follow_dlg.c
gtk/main.c
gtk/print_dlg.c
gtk2/capture_dlg.c
gtk2/file_dlg.c
gtk2/follow_dlg.c
gtk2/main.c
gtk2/print_dlg.c

index 4e6b05b388d3ad003294bb34f9b22c738b41d2e6..a645d650449e4db744f7380e2ec08e456fc10795 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
 /* capture.c
  * Routines for packet capture windows
  *
- * $Id: capture.c,v 1.189 2002/08/28 21:00:05 jmayer Exp $
+ * $Id: capture.c,v 1.190 2002/09/09 20:38:56 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -289,7 +289,7 @@ quote_encapsulate(const char *string)
 /* Open a specified file, or create a temporary file, and start a capture
    to the file in question. */
 void
-do_capture(char *capfile_name)
+do_capture(const char *save_file)
 {
   char tmpname[128+1];
   gboolean is_tempfile;
@@ -301,8 +301,14 @@ do_capture(char *capfile_name)
   int capture_succeeded;
   gboolean stats_known;
   struct pcap_stat stats;
-
-  if (capfile_name != NULL) {
+  gchar *capfile_name;
+
+  if (save_file != NULL) {
+    /* If the Sync option is set, we return to the caller while the capture
+     * is in progress.  Therefore we need to take a copy of save_file in
+     * case the caller destroys it after we return.
+     */
+    capfile_name = g_strdup(save_file);
     if (capture_opts.ringbuffer_on) {
       /* ringbuffer is enabled */
       cfile.save_file_fd = ringbuf_init(capfile_name,
@@ -331,11 +337,14 @@ do_capture(char *capfile_name)
       simple_dialog(ESD_TYPE_CRIT, NULL,
        file_open_error_message(errno, TRUE, WTAP_FILE_PCAP), capfile_name);
     }
+    g_free(capfile_name);
     return;
   }
   close_cap_file(&cfile);
   g_assert(cfile.save_file == NULL);
   cfile.save_file = capfile_name;
+  /* cfile.save_file is "g_free"ed below, which is equivalent to
+     "g_free(capfile_name)". */
 
   if (capture_opts.sync_mode) {        /* do the capture in a child process */
     char ssnap[24];
@@ -676,7 +685,8 @@ do_capture(char *capfile_name)
         case READ_ABORTED:
           /* Exit by leaving the main loop, so that any quit functions
              we registered get called. */
-          gtk_main_quit();
+          if (gtk_main_level() > 0)
+            gtk_main_quit();
           return;
         }
       }
index b90e04bbd55cad038d49fa664fd3a7b0262754f6..a74d490603d446e2c0df326362837973d8faad6f 100644 (file)
--- a/capture.h
+++ b/capture.h
@@ -1,7 +1,7 @@
 /* capture.h
  * Definitions for packet capture windows
  *
- * $Id: capture.h,v 1.32 2002/08/28 21:00:05 jmayer Exp $
+ * $Id: capture.h,v 1.33 2002/09/09 20:38:56 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -59,7 +59,7 @@ extern gboolean capture_child;        /* if this is the child for "-S" */
 
 /* Open a specified file, or create a temporary file, and start a capture
    to the file in question. */
-void   do_capture(char *capfile_name);
+void   do_capture(const char *save_file);
 
 /* Do the low-level work of a capture. */
 int    capture(gboolean *stats_known, struct pcap_stat *stats);
index 440f7cae9adab3fd599ce1f68a541bcd4a69a098..8bc94d2a3a632bf7dc23af0139ad85b71c50996b 100644 (file)
@@ -1,7 +1,7 @@
 /* capture_dlg.c
  * Routines for packet capture windows
  *
- * $Id: capture_dlg.c,v 1.72 2002/09/05 18:47:44 jmayer Exp $
+ * $Id: capture_dlg.c,v 1.73 2002/09/09 20:38:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -45,6 +45,7 @@
 #include "pcap-util.h"
 #include "prefs.h"
 #include "ringbuffer.h"
+#include <epan/filesystem.h>
 
 #ifdef _WIN32
 #include "capture-wpcap.h"
@@ -86,7 +87,7 @@ static void
 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
 
 static void
-cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data);
+cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
 
 static void
 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
@@ -530,7 +531,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
      widgets. */
   capture_prep_adjust_sensitivity(NULL, cap_open_w);
 
-  /* Catch the "activate" signal on the frame number and file name text
+  /* Catch the "activate" signal on the filter and file name text
      entries, so that if the user types Return there, we act as if the
      "OK" button had been selected, as happens if Return is typed if some
      widget that *doesn't* handle the Return key has the input focus. */
@@ -586,6 +587,11 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
 
   fs = gtk_file_selection_new ("Ethereal: Capture File");
 
+  /* If we've opened a file, start out by showing the files in the directory
+     in which that file resided. */
+  if (last_open_dir)
+    gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+
   gtk_object_set_data(GTK_OBJECT(fs), E_CAP_FILE_TE_KEY, file_te);
 
   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
@@ -597,7 +603,7 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
   /* Call a handler when the file selection box is destroyed, so we can inform
      our caller, if any, that it's been destroyed. */
   gtk_signal_connect(GTK_OBJECT(fs), "destroy",
-           GTK_SIGNAL_FUNC(cap_prep_fs_destroy_cb), NULL);
+           GTK_SIGNAL_FUNC(cap_prep_fs_destroy_cb), file_te);
 
   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
     "clicked", (GtkSignalFunc) cap_prep_fs_ok_cb, fs);
@@ -617,10 +623,32 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
 static void
 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
 {
+  gchar     *cf_name;
+  gchar     *dirname;
+
+  cf_name = g_strdup(gtk_file_selection_get_filename(
+    GTK_FILE_SELECTION (data)));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display it. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
+          last_open_dir);
+        return;
+  }
+
   gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
-      E_CAP_FILE_TE_KEY)),
-      gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
+      E_CAP_FILE_TE_KEY)), cf_name);
+
   gtk_widget_destroy(GTK_WIDGET(data));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
+  g_free(cf_name);
 }
 
 static void
@@ -630,7 +658,7 @@ cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
 }
 
 static void
-cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
+cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
 {
   GtkWidget *caller;
 
@@ -645,6 +673,10 @@ cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
   /* Now nuke this window. */
   gtk_grab_remove(GTK_WIDGET(win));
   gtk_widget_destroy(GTK_WIDGET(win));
+
+  /* Give the focus to the file text entry widget so the user can just press
+     Return to start the capture. */
+  gtk_widget_grab_focus(file_te);
 }
 
 static void
@@ -782,6 +814,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
       simple_dialog(ESD_TYPE_CRIT, NULL,
         "You must specify a file size at which to rotate the capture files\n"
         "if you want to use the ring buffer.");
+      g_free(save_file);
       return;
     }
   }
@@ -796,6 +829,8 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   gtk_widget_destroy(GTK_WIDGET(parent_w));
 
   do_capture(save_file);
+  if (save_file != NULL)
+    g_free(save_file);
 }
 
 static void
index f90bb45d2848571ab1ad972b72d3e3d7cbbab25c..d17b4981af8ace583e394b798c1983331a901209 100644 (file)
@@ -1,7 +1,7 @@
 /* file_dlg.c
  * Dialog boxes for handling files
  *
- * $Id: file_dlg.c,v 1.51 2002/09/05 18:47:45 jmayer Exp $
+ * $Id: file_dlg.c,v 1.52 2002/09/09 20:38:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -181,6 +181,7 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
   filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
   rfilter = gtk_entry_get_text(GTK_ENTRY(filter_te));
   if (!dfilter_compile(rfilter, &rfcode)) {
+    g_free(cf_name);
     simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
     return;
   }
@@ -191,6 +192,7 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
        /* It's a directory - set the file selection box to display that
           directory, don't try to open the directory as a capture file. */
        set_last_open_dir(cf_name);
+        g_free(cf_name);
        gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
        return;
   }
@@ -554,17 +556,39 @@ file_set_save_marked_sensitive(void)
 static void
 file_save_as_ok_cb(GtkWidget *w _U_, GtkFileSelection *fs) {
   gchar        *cf_name;
+  gchar        *dirname;
 
   cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
-  gtk_widget_hide(GTK_WIDGET (fs));
-  gtk_widget_destroy(GTK_WIDGET (fs));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display that
+           directory, and leave the selection box displayed. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+        return;
+  }
 
   /* Write out the packets (all, or only the ones that are currently
      displayed or marked) to the file with the specified name. */
-  save_cap_file(cf_name, &cfile, filtered, marked, filetype);
 
-  /* If "save_cap_file()" saved the file name we handed it, it saved
-     a copy, so we should free up our copy. */
+  if (! save_cap_file(cf_name, &cfile, filtered, marked, filetype)) {
+    /* The write failed; don't dismiss the open dialog box,
+       just leave it around so that the user can, after they
+       dismiss the alert box popped up for the error, try again. */
+    g_free(cf_name);
+    return;
+  }
+
+  /* The write succeeded; get rid of the file selection box. */
+  gtk_widget_hide(GTK_WIDGET (fs));
+  gtk_widget_destroy(GTK_WIDGET (fs));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
   g_free(cf_name);
 }
 
index 9b8f40d71facead778c8bc066681f5eae8e0f02c..356695cab0b704c63547bcfb89073537b0199bd3 100644 (file)
@@ -1,6 +1,6 @@
 /* follow_dlg.c
  *
- * $Id: follow_dlg.c,v 1.27 2002/09/07 10:01:55 jmayer Exp $
+ * $Id: follow_dlg.c,v 1.28 2002/09/09 20:38:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -61,6 +61,7 @@
 #include "util.h"
 #include "ui_util.h"
 #include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
 
 /* Show Stream */
 typedef enum {
@@ -733,7 +734,7 @@ follow_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
     /* If we've opened a file, start out by showing the files in the directory
        in which that file resided. */
     if (last_open_dir)
-       gtk_file_selection_complete(GTK_FILE_SELECTION(new_win),
+       gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win),
                                    last_open_dir);
 
     /* Connect the ok_button to file_save_as_ok_cb function and pass along a
@@ -767,22 +768,40 @@ follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
        gchar           *to_name;
        follow_info_t   *follow_info;
        FILE            *fh;
+       gchar           *dirname;
 
        to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
 
-       gtk_widget_hide(GTK_WIDGET(fs));
-       follow_info = gtk_object_get_data(GTK_OBJECT(fs), E_FOLLOW_INFO_KEY);
-       gtk_widget_destroy(GTK_WIDGET(fs));
+       /* Perhaps the user specified a directory instead of a file.
+          Check whether they did. */
+       if (test_for_directory(to_name) == EISDIR) {
+               /* It's a directory - set the file selection box to display that
+                  directory, and leave the selection box displayed. */
+               set_last_open_dir(to_name);
+               g_free(to_name);
+               gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs),
+                       last_open_dir);
+               return;
+       }
 
        fh = fopen(to_name, "wb");
        if (fh == NULL) {
                simple_dialog(ESD_TYPE_WARN, NULL,
                        file_write_error_message(errno), to_name);
+               g_free(to_name);
                return;
        }
 
+       gtk_widget_hide(GTK_WIDGET(fs));
+       follow_info = gtk_object_get_data(GTK_OBJECT(fs), E_FOLLOW_INFO_KEY);
+       gtk_widget_destroy(GTK_WIDGET(fs));
+
        follow_read_stream(follow_info, follow_print_text, fh);
        fclose(fh);
+
+       /* Save the directory name for future file dialogs. */
+       dirname = get_dirname(to_name);  /* Overwrites to_name */
+       set_last_open_dir(dirname);
        g_free(to_name);
 }
 
index d014862f368dff8cc968656ffbeb88eed07e99db..f465cc7ef31b08c609f0d7d31a79cc171fdfc4ab 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.262 2002/09/07 10:02:29 sahlberg Exp $
+ * $Id: main.c,v 1.263 2002/09/09 20:38:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1729,7 +1729,7 @@ main(int argc, char *argv[])
           sync_mode takes precedence;
        c) it makes no sense to enable the ring buffer if the maximum
           file size is set to "infinite". */
-    if (cfile.save_file == NULL) {
+    if (save_file == NULL) {
       fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
       capture_opts.ringbuffer_on = FALSE;
     }
@@ -1931,6 +1931,8 @@ main(int argc, char *argv[])
              argument. */
           s = get_dirname(cf_name);
          set_last_open_dir(s);
+          g_free(cf_name);
+          cf_name = NULL;
         } else {
           if (rfcode != NULL)
             dfilter_free(rfcode);
@@ -1998,6 +2000,13 @@ main(int argc, char *argv[])
     if (start_capture) {
       /* "-k" was specified; start a capture. */
       do_capture(save_file);
+      if (save_file != NULL) {
+        /* Save the directory name for future file dialogs. */
+        s = get_dirname(save_file);  /* Overwrites save_file */
+        set_last_open_dir(s);
+        g_free(save_file);
+        save_file = NULL;
+      }
     }
     else {
       set_menus_for_capture_in_progress(FALSE);
@@ -2492,7 +2501,10 @@ set_last_open_dir(char *dirname)
 
        if (dirname) {
                len = strlen(dirname);
-               if (dirname[len-1] != G_DIR_SEPARATOR) {
+               if (dirname[len-1] == G_DIR_SEPARATOR) {
+                       last_open_dir = g_strconcat(dirname, NULL);
+               }
+               else {
                        last_open_dir = g_strconcat(dirname, G_DIR_SEPARATOR_S,
                                NULL);
                }
index 1b6ab11e77cb794afb7fa8a516c8b1c65067b14b..ea9f6083b93b1aef2c35fef2fb72929fe55fee80 100644 (file)
@@ -1,7 +1,7 @@
 /* print_dlg.c
  * Dialog boxes for printing
  *
- * $Id: print_dlg.c,v 1.36 2002/09/05 18:47:47 jmayer Exp $
+ * $Id: print_dlg.c,v 1.37 2002/09/09 20:38:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -35,7 +35,9 @@
 #include "simple_dialog.h"
 #include "ui_util.h"
 #include "dlg_utils.h"
+#include "main.h"
 #include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
 #ifdef _WIN32
 #include <io.h>
 #include "print_mswin.h"
@@ -56,7 +58,7 @@ static void print_cmd_toggle_detail(GtkWidget *widget, gpointer data);
 static void print_file_cb(GtkWidget *file_bt, gpointer file_te);
 static void print_fs_ok_cb(GtkWidget *w, gpointer data);
 static void print_fs_cancel_cb(GtkWidget *w, gpointer data);
-static void print_fs_destroy_cb(GtkWidget *win, gpointer data);
+static void print_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
 static void print_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
 static void print_close_cb(GtkWidget *close_bt, gpointer parent_w);
 static void print_destroy_cb(GtkWidget *win, gpointer user_data);
@@ -241,6 +243,8 @@ file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
   gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
   gtk_widget_set_sensitive(file_te, print_to_file);
   gtk_widget_show(file_te);
+  if (print_to_file)
+    gtk_widget_grab_focus(file_te);
 
   gtk_signal_connect(GTK_OBJECT(file_bt), "clicked",
                GTK_SIGNAL_FUNC(print_file_cb), GTK_OBJECT(file_te));
@@ -442,6 +446,12 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
   }
 
   fs = gtk_file_selection_new ("Ethereal: Print to File");
+
+  /* If we've opened a file, start out by showing the files in the directory
+     in which that file resided. */
+  if (last_open_dir)
+    gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+
   gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
 
   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
@@ -453,7 +463,7 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
   /* Call a handler when the file selection box is destroyed, so we can inform
      our caller, if any, that it's been destroyed. */
   gtk_signal_connect(GTK_OBJECT(fs), "destroy",
-           GTK_SIGNAL_FUNC(print_fs_destroy_cb), NULL);
+           GTK_SIGNAL_FUNC(print_fs_destroy_cb), file_te);
 
   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
     "clicked", (GtkSignalFunc) print_fs_ok_cb, fs);
@@ -473,11 +483,31 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
 static void
 print_fs_ok_cb(GtkWidget *w _U_, gpointer data)
 {
+  gchar     *cf_name;
+  gchar     *dirname;
+
+  cf_name = g_strdup(gtk_file_selection_get_filename(
+    GTK_FILE_SELECTION (data)));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display it. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
+          last_open_dir);
+        return;
+  }
 
   gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
-      PRINT_FILE_TE_KEY)),
-      gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
+      PRINT_FILE_TE_KEY)), cf_name);
   gtk_widget_destroy(GTK_WIDGET(data));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
+  g_free(cf_name);
 }
 
 static void
@@ -487,7 +517,7 @@ print_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
 }
 
 static void
-print_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
+print_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
 {
   GtkWidget *caller;
 
@@ -502,6 +532,10 @@ print_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
   /* Now nuke this window. */
   gtk_grab_remove(GTK_WIDGET(win));
   gtk_widget_destroy(GTK_WIDGET(win));
+
+  /* Give the focus to the file text entry widget so the user can just press
+     Return to print to the file. */
+  gtk_widget_grab_focus(file_te);
 }
 
 #ifdef _WIN32
index a7484d5d858754950ed17727bc96ab59af3741a1..2ccc0707924ae5c2f97fc4092c2ee1be7ad091f5 100644 (file)
@@ -1,7 +1,7 @@
 /* capture_dlg.c
  * Routines for packet capture windows
  *
- * $Id: capture_dlg.c,v 1.5 2002/09/05 18:48:51 jmayer Exp $
+ * $Id: capture_dlg.c,v 1.6 2002/09/09 20:39:01 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -45,6 +45,7 @@
 #include "pcap-util.h"
 #include "prefs.h"
 #include "ringbuffer.h"
+#include <epan/filesystem.h>
 
 #ifdef _WIN32
 #include "capture-wpcap.h"
@@ -86,7 +87,7 @@ static void
 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
 
 static void
-cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data);
+cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
 
 static void
 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
@@ -527,7 +528,7 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
      widgets. */
   capture_prep_adjust_sensitivity(NULL, cap_open_w);
 
-  /* Catch the "activate" signal on the frame number and file name text
+  /* Catch the "activate" signal on the filter and file name text
      entries, so that if the user types Return there, we act as if the
      "OK" button had been selected, as happens if Return is typed if some
      widget that *doesn't* handle the Return key has the input focus. */
@@ -583,6 +584,11 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
 
   fs = gtk_file_selection_new ("Ethereal: Capture File");
 
+  /* If we've opened a file, start out by showing the files in the directory
+     in which that file resided. */
+  if (last_open_dir)
+    gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+
   gtk_object_set_data(GTK_OBJECT(fs), E_CAP_FILE_TE_KEY, file_te);
 
   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
@@ -594,7 +600,7 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
   /* Call a handler when the file selection box is destroyed, so we can inform
      our caller, if any, that it's been destroyed. */
   g_signal_connect(G_OBJECT(fs), "destroy",
-                   G_CALLBACK(cap_prep_fs_destroy_cb), NULL);
+                   G_CALLBACK(cap_prep_fs_destroy_cb), file_te);
 
   g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked",
                    G_CALLBACK(cap_prep_fs_ok_cb), fs);
@@ -614,10 +620,32 @@ capture_prep_file_cb(GtkWidget *w, gpointer file_te)
 static void
 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
 {
+  gchar     *cf_name;
+  gchar     *dirname;
+
+  cf_name = g_strdup(gtk_file_selection_get_filename(
+    GTK_FILE_SELECTION (data)));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display it. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
+          last_open_dir);
+        return;
+  }
+
   gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
-      E_CAP_FILE_TE_KEY)),
-      gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
+      E_CAP_FILE_TE_KEY)), cf_name);
+
   gtk_widget_destroy(GTK_WIDGET(data));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
+  g_free(cf_name);
 }
 
 static void
@@ -627,7 +655,7 @@ cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
 }
 
 static void
-cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
+cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
 {
   GtkWidget *caller;
 
@@ -642,6 +670,10 @@ cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
   /* Now nuke this window. */
   gtk_grab_remove(GTK_WIDGET(win));
   gtk_widget_destroy(GTK_WIDGET(win));
+
+  /* Give the focus to the file text entry widget so the user can just press
+     Return to start the capture. */
+  gtk_widget_grab_focus(file_te);
 }
 
 static void
@@ -656,7 +688,8 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   gchar *if_text;
   gchar *if_name;
   const gchar *filter_text;
-  const gchar *save_file;
+  const gchar *g_save_file;
+  gchar *save_file;
 
   if_cb     = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY);
   snap_cb   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY);
@@ -726,10 +759,10 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   g_assert(filter_text != NULL);
   cfile.cfilter = g_strdup(filter_text);
 
-  save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
-  if (save_file && save_file[0]) {
+  g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
+  if (g_save_file && g_save_file[0]) {
     /* User specified a file to which the capture should be written. */
-    save_file = g_strdup(save_file);
+    save_file = g_strdup(g_save_file);
   } else {
     /* User didn't specify a file; save to a temporary file. */
     save_file = NULL;
@@ -779,6 +812,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
       simple_dialog(ESD_TYPE_CRIT, NULL,
         "You must specify a file size at which to rotate the capture files\n"
         "if you want to use the ring buffer.");
+      g_free(save_file);
       return;
     }
   }
@@ -793,6 +827,8 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   gtk_widget_destroy(GTK_WIDGET(parent_w));
 
   do_capture(save_file);
+  if (save_file != NULL)
+    g_free(save_file);
 }
 
 static void
index bf5bf4ed81876613eae02fae3cc924be48dc2a16..efc37d04a6ada49ea9839f206356d0ededf4af8f 100644 (file)
@@ -1,7 +1,7 @@
 /* file_dlg.c
  * Dialog boxes for handling files
  *
- * $Id: file_dlg.c,v 1.3 2002/09/05 18:48:51 jmayer Exp $
+ * $Id: file_dlg.c,v 1.4 2002/09/09 20:39:01 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -175,6 +175,7 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
   filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
   rfilter = gtk_entry_get_text(GTK_ENTRY(filter_te));
   if (!dfilter_compile(rfilter, &rfcode)) {
+    g_free(cf_name);
     simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
     return;
   }
@@ -185,6 +186,7 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
        /* It's a directory - set the file selection box to display that
           directory, don't try to open the directory as a capture file. */
        set_last_open_dir(cf_name);
+       g_free(cf_name);
        gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
        return;
   }
@@ -548,17 +550,39 @@ file_set_save_marked_sensitive(void)
 static void
 file_save_as_ok_cb(GtkWidget *w _U_, GtkFileSelection *fs) {
   gchar        *cf_name;
+  gchar *dirname;
 
   cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
-  gtk_widget_hide(GTK_WIDGET (fs));
-  gtk_widget_destroy(GTK_WIDGET (fs));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display that
+           directory, and leave the selection box displayed. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+        return;
+  }
 
   /* Write out the packets (all, or only the ones that are currently
      displayed or marked) to the file with the specified name. */
-  save_cap_file(cf_name, &cfile, filtered, marked, filetype);
 
-  /* If "save_cap_file()" saved the file name we handed it, it saved
-     a copy, so we should free up our copy. */
+  if (! save_cap_file(cf_name, &cfile, filtered, marked, filetype)) {
+    /* The write failed; don't dismiss the open dialog box,
+       just leave it around so that the user can, after they
+       dismiss the alert box popped up for the error, try again. */
+    g_free(cf_name);
+    return;
+  }
+
+  /* The write succeeded; get rid of the file selection box. */
+  gtk_widget_hide(GTK_WIDGET (fs));
+  gtk_widget_destroy(GTK_WIDGET (fs));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
   g_free(cf_name);
 }
 
index 037f9353848456f0f7b052ea4d6209058e253e37..0d83b19fff11324e199ee99ef84cbef108980ce7 100644 (file)
@@ -1,6 +1,6 @@
 /* follow_dlg.c
  *
- * $Id: follow_dlg.c,v 1.3 2002/09/07 14:56:57 jmayer Exp $
+ * $Id: follow_dlg.c,v 1.4 2002/09/09 20:39:01 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -61,6 +61,7 @@
 #include "util.h"
 #include "ui_util.h"
 #include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
 
 /* Show Stream */
 typedef enum {
@@ -749,7 +750,7 @@ follow_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
     /* If we've opened a file, start out by showing the files in the directory
        in which that file resided. */
     if (last_open_dir)
-       gtk_file_selection_complete(GTK_FILE_SELECTION(new_win),
+       gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win),
                                    last_open_dir);
 
     /* Connect the ok_button to file_save_as_ok_cb function and pass along a
@@ -780,22 +781,40 @@ follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
        gchar           *to_name;
        follow_info_t   *follow_info;
        FILE            *fh;
+       gchar           *dirname;
 
        to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
 
-       gtk_widget_hide(GTK_WIDGET(fs));
-       follow_info = gtk_object_get_data(GTK_OBJECT(fs), E_FOLLOW_INFO_KEY);
-       gtk_widget_destroy(GTK_WIDGET(fs));
+       /* Perhaps the user specified a directory instead of a file.
+          Check whether they did. */
+       if (test_for_directory(to_name) == EISDIR) {
+              /* It's a directory - set the file selection box to display that
+                 directory, and leave the selection box displayed. */
+              set_last_open_dir(to_name);
+              g_free(to_name);
+              gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs),
+                      last_open_dir);
+              return;
+       }
 
        fh = fopen(to_name, "wb");
        if (fh == NULL) {
                simple_dialog(ESD_TYPE_WARN, NULL,
                        file_write_error_message(errno), to_name);
+               g_free(to_name);
                return;
        }
 
+       gtk_widget_hide(GTK_WIDGET(fs));
+       follow_info = gtk_object_get_data(GTK_OBJECT(fs), E_FOLLOW_INFO_KEY);
+       gtk_widget_destroy(GTK_WIDGET(fs));
+
        follow_read_stream(follow_info, follow_print_text, fh);
        fclose(fh);
+
+       /* Save the directory name for future file dialogs. */
+       dirname = get_dirname(to_name);  /* Overwrites to_name */
+       set_last_open_dir(dirname);
        g_free(to_name);
 }
 
index 9177bc2cf72730e7a497e02196ce34c2d2747fbb..acd8ebaa2573c928f52f2129b6b4eeacd4be8f8e 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.10 2002/09/07 09:28:05 sahlberg Exp $
+ * $Id: main.c,v 1.11 2002/09/09 20:39:01 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1789,7 +1789,7 @@ main(int argc, char *argv[])
            sync_mode takes precedence;
            c) it makes no sense to enable the ring buffer if the maximum
            file size is set to "infinite". */
-        if (cfile.save_file == NULL) {
+        if (save_file == NULL) {
             fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
             capture_opts.ringbuffer_on = FALSE;
         }
@@ -1991,6 +1991,8 @@ main(int argc, char *argv[])
                        argument. */
                     s = get_dirname(cf_name);
                     set_last_open_dir(s);
+                    g_free(cf_name);
+                    cf_name = NULL;
                 } else {
                     if (rfcode != NULL)
                         dfilter_free(rfcode);
@@ -2058,6 +2060,13 @@ main(int argc, char *argv[])
         if (start_capture) {
             /* "-k" was specified; start a capture. */
             do_capture(save_file);
+            if (save_file != NULL) {
+                 /* Save the directory name for future file dialogs. */
+                 s = get_dirname(save_file);  /* Overwrites save_file */
+                 set_last_open_dir(s);
+                 g_free(save_file);
+                 save_file = NULL;
+            }
         }
         else {
             set_menus_for_capture_in_progress(FALSE);
@@ -2500,7 +2509,10 @@ set_last_open_dir(char *dirname)
 
     if (dirname) {
         len = strlen(dirname);
-        if (dirname[len-1] != G_DIR_SEPARATOR) {
+        if (dirname[len-1] == G_DIR_SEPARATOR) {
+            last_open_dir = g_strconcat(dirname, NULL);
+        }
+        else {
             last_open_dir = g_strconcat(dirname, G_DIR_SEPARATOR_S,
                                         NULL);
         }
index b2c014b63295add80d4c8bb254b50e24f5f9fdcd..8645b905e927222462ee631f574ea9c7086e6f7b 100644 (file)
@@ -1,7 +1,7 @@
 /* print_dlg.c
  * Dialog boxes for printing
  *
- * $Id: print_dlg.c,v 1.3 2002/09/05 18:48:52 jmayer Exp $
+ * $Id: print_dlg.c,v 1.4 2002/09/09 20:39:01 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -35,7 +35,9 @@
 #include "simple_dialog.h"
 #include "ui_util.h"
 #include "dlg_utils.h"
+#include "main.h"
 #include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
 #ifdef _WIN32
 #include <io.h>
 #include "print_mswin.h"
@@ -54,7 +56,7 @@ static void print_cmd_toggle_detail(GtkWidget *widget, gpointer data);
 static void print_file_cb(GtkWidget *file_bt, gpointer file_te);
 static void print_fs_ok_cb(GtkWidget *w, gpointer data);
 static void print_fs_cancel_cb(GtkWidget *w, gpointer data);
-static void print_fs_destroy_cb(GtkWidget *win, gpointer data);
+static void print_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
 static void print_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
 static void print_close_cb(GtkWidget *close_bt, gpointer parent_w);
 static void print_destroy_cb(GtkWidget *win, gpointer user_data);
@@ -220,6 +222,8 @@ file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
   gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
   gtk_widget_set_sensitive(file_te, print_to_file);
   gtk_widget_show(file_te);
+  if (print_to_file)
+    gtk_widget_grab_focus(file_te);
 
   g_signal_connect(G_OBJECT(file_bt), "clicked",
                    G_CALLBACK(print_file_cb), GTK_OBJECT(file_te));
@@ -417,6 +421,12 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
   }
 
   fs = gtk_file_selection_new ("Ethereal: Print to File");
+
+  /* If we've opened a file, start out by showing the files in the directory
+     in which that file resided. */
+  if (last_open_dir)
+    gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
+
   gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
 
   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
@@ -428,7 +438,7 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
   /* Call a handler when the file selection box is destroyed, so we can inform
      our caller, if any, that it's been destroyed. */
   g_signal_connect(G_OBJECT(fs), "destroy",
-                   G_CALLBACK(print_fs_destroy_cb), NULL);
+                   G_CALLBACK(print_fs_destroy_cb), file_te);
 
   g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked",
                    G_CALLBACK(print_fs_ok_cb), fs);
@@ -448,11 +458,31 @@ print_file_cb(GtkWidget *file_bt, gpointer file_te)
 static void
 print_fs_ok_cb(GtkWidget *w _U_, gpointer data)
 {
+  gchar     *cf_name;
+  gchar     *dirname;
+
+  cf_name = g_strdup(gtk_file_selection_get_filename(
+    GTK_FILE_SELECTION (data)));
+
+  /* Perhaps the user specified a directory instead of a file.
+     Check whether they did. */
+  if (test_for_directory(cf_name) == EISDIR) {
+        /* It's a directory - set the file selection box to display it. */
+        set_last_open_dir(cf_name);
+        g_free(cf_name);
+        gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
+          last_open_dir);
+        return;
+  }
 
   gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
-      PRINT_FILE_TE_KEY)),
-      gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
+      PRINT_FILE_TE_KEY)), cf_name);
   gtk_widget_destroy(GTK_WIDGET(data));
+
+  /* Save the directory name for future file dialogs. */
+  dirname = get_dirname(cf_name);  /* Overwrites cf_name */
+  set_last_open_dir(dirname);
+  g_free(cf_name);
 }
 
 static void
@@ -462,7 +492,7 @@ print_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
 }
 
 static void
-print_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
+print_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
 {
   GtkWidget *caller;
 
@@ -477,6 +507,10 @@ print_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
   /* Now nuke this window. */
   gtk_grab_remove(GTK_WIDGET(win));
   gtk_widget_destroy(GTK_WIDGET(win));
+
+  /* Give the focus to the file text entry widget so the user can just press
+     Return to print to the file. */
+  gtk_widget_grab_focus(file_te);
 }
 
 #ifdef _WIN32