summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorRichard Sharpe <sharpe@ns.aus.com>2003-11-29 06:09:54 +0000
committerRichard Sharpe <sharpe@ns.aus.com>2003-11-29 06:09:54 +0000
commit02087e332f732dab10eceabe2d5ffc32fde5fcb2 (patch)
tree84984243a958447fe63286df1d793aa9cd46bfba /gtk
parentc34428926028b6f81f43ac2c3e2c9ddddbfe19ac (diff)
downloadwireshark-02087e332f732dab10eceabe2d5ffc32fde5fcb2.tar.gz
Add an entry in the byte_view pane that allows the user to save the highlighted
data to a file. This allows the user to select some stuff, and analyse it with external tools, and is very useful for quickly prototying dissectors etc. This works by retrieving the info that is needed to define where the selected region is. It puts up a dialog box that asks for the file to save in. However, it is an ugly hack, because it reuses print_file_cb, while print_file_cb should be moved into file_dlg.c. It also needs to have some warning dialogs put up in error cases. Finally, it would be good to be able to select a region in the byte_view, which you can do with click and drag, and then have a menu item to save the selected bytes. svn path=/trunk/; revision=9116
Diffstat (limited to 'gtk')
-rw-r--r--gtk/file_dlg.h5
-rw-r--r--gtk/menu.c6
-rw-r--r--gtk/print_dlg.c32
-rw-r--r--gtk/proto_draw.c179
4 files changed, 211 insertions, 11 deletions
diff --git a/gtk/file_dlg.h b/gtk/file_dlg.h
index e6117e928e..f252c6380b 100644
--- a/gtk/file_dlg.h
+++ b/gtk/file_dlg.h
@@ -1,7 +1,7 @@
/* file_dlg.h
* Definitions for dialog boxes for handling files
*
- * $Id: file_dlg.h,v 1.4 2003/08/18 21:27:11 sahlberg Exp $
+ * $Id: file_dlg.h,v 1.5 2003/11/29 06:09:53 sharpe Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -34,6 +34,9 @@ void file_reload_cmd_cb(GtkWidget *, gpointer);
void file_color_import_cmd_cb(GtkWidget *w, gpointer data);
void file_color_export_cmd_cb(GtkWidget *, gpointer);
+/* Keys ... */
+#define E_FILE_TE_PTR_KEY "file_te_ptr"
+
/*
* Set the "Save only marked packets" toggle button as appropriate for
* the current output file type and count of marked packets.
diff --git a/gtk/menu.c b/gtk/menu.c
index fdf7f7e7c0..15744e12eb 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
- * $Id: menu.c,v 1.112 2003/11/28 19:13:25 ulfl Exp $
+ * $Id: menu.c,v 1.113 2003/11/29 06:09:53 sharpe Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -371,12 +371,16 @@ static GtkItemFactoryEntry tree_view_menu_items[] =
ITEM_FACTORY_ENTRY("/Expand All", NULL, expand_all_cb, 0, NULL, NULL)
};
+extern void savehex_cb(GtkWidget * w, gpointer data _U_);
+
static GtkItemFactoryEntry hexdump_menu_items[] =
{
ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
0, NULL, NULL),
ITEM_FACTORY_ENTRY("/Decode As...", NULL, decode_as_cb, 0, NULL, NULL),
ITEM_FACTORY_ENTRY("/Display Filters...", NULL, dfilter_dialog_cb,
+ 0, NULL, NULL),
+ ITEM_FACTORY_ENTRY("/Save highlighted data...", NULL, savehex_cb,
0, NULL, NULL)
};
diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c
index ff2d9804f2..c3166c0239 100644
--- a/gtk/print_dlg.c
+++ b/gtk/print_dlg.c
@@ -1,7 +1,7 @@
/* print_dlg.c
* Dialog boxes for printing
*
- * $Id: print_dlg.c,v 1.45 2003/11/18 19:27:39 ulfl Exp $
+ * $Id: print_dlg.c,v 1.46 2003/11/29 06:09:54 sharpe Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -33,6 +33,11 @@
#include "print.h"
#include "prefs.h"
#include "simple_dialog.h"
+/*
+ * Only need this for construct_args
+ */
+#include "filter_prefs.h"
+#include "file_dlg.h"
#include "ui_util.h"
#include "dlg_utils.h"
#include "main.h"
@@ -54,9 +59,9 @@
for this (and also use various UNIX printing APIs, when present?).
*/
+void print_file_cb(GtkWidget *file_bt, construct_args_t *args);
static void print_cmd_toggle_dest(GtkWidget *widget, gpointer data);
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, GtkWidget* file_te);
@@ -95,6 +100,7 @@ static gchar * print_cmd;
#define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
+
/*
* Keep a static pointer to the current "Print" window, if any, so that if
* somebody tries to do "File:Print" while there's already a "Print" window
@@ -134,7 +140,11 @@ file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
gchar label_text[100];
frame_data *packet;
guint32 displayed_count;
-
+ static construct_args_t file_dlg_args = {
+ "Ethereal: Print to File",
+ FALSE,
+ FALSE
+ };
if (print_w != NULL) {
/* There's already a "Print" dialog box; reactivate it. */
@@ -260,6 +270,7 @@ file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
file_bt = gtk_button_new_with_label("Browse");
OBJECT_SET_DATA(dest_cb, PRINT_FILE_BT_KEY, file_bt);
+ OBJECT_SET_DATA(file_bt, E_FILE_TE_PTR_KEY, file_te);
gtk_tooltips_set_tip (tooltips, file_bt, ("Browse output filename in filesystem"), NULL);
gtk_table_attach_defaults(GTK_TABLE(printer_tb), file_bt, 2, 3, 0, 1);
gtk_widget_set_sensitive(file_bt, print_to_file);
@@ -286,7 +297,7 @@ file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
#endif
SIGNAL_CONNECT(dest_cb, "toggled", print_cmd_toggle_dest, NULL);
- SIGNAL_CONNECT(file_bt, "clicked", print_file_cb, file_te);
+ SIGNAL_CONNECT(file_bt, "clicked", print_file_cb, &file_dlg_args);
/*****************************************************/
@@ -591,16 +602,16 @@ print_cmd_toggle_detail(GtkWidget *widget, gpointer data _U_)
gtk_widget_set_sensitive(hex_cb, print_detail);
}
-static void
-print_file_cb(GtkWidget *file_bt, gpointer file_te)
+void
+print_file_cb(GtkWidget *file_bt, construct_args_t *args _U_)
{
GtkWidget *caller = gtk_widget_get_toplevel(file_bt);
- GtkWidget *fs;
+ GtkWidget *fs, *file_te;
/* Has a file selection dialog box already been opened for that top-level
widget? */
fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
-
+ file_te = OBJECT_GET_DATA(file_bt, E_FILE_TE_PTR_KEY);
if (fs != NULL) {
/* Yes. Just re-activate that dialog box. */
reactivate_window(fs);
@@ -891,3 +902,8 @@ file_print_packet_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
}
#endif
}
+
+
+
+
+
diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c
index c80c91c745..0acf96efa1 100644
--- a/gtk/proto_draw.c
+++ b/gtk/proto_draw.c
@@ -1,7 +1,7 @@
/* proto_draw.c
* Routines for GTK+ packet display
*
- * $Id: proto_draw.c,v 1.65 2003/11/25 14:07:45 sahlberg Exp $
+ * $Id: proto_draw.c,v 1.66 2003/11/29 06:09:54 sharpe Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -44,8 +44,11 @@
#include "colors.h"
#include "prefs.h"
+#include "filter_prefs.h"
+#include "file_dlg.h"
#include "proto_draw.h"
#include "packet_win.h"
+#include "dlg_utils.h"
#include "ui_util.h"
#include "gtkglobals.h"
#include "compat_macros.h"
@@ -729,6 +732,179 @@ add_byte_views(epan_dissect_t *edt, GtkWidget *tree_view,
gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
}
+#include <fcntl.h>
+
+static GtkWidget *savehex_dlg=NULL;
+static GtkWidget *file_entry=NULL;
+
+static void
+savehex_dlg_destroy_cb(void)
+{
+ savehex_dlg = NULL;
+}
+
+static void
+savehex_dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
+{
+ gtk_widget_destroy(GTK_WIDGET(parent_w));
+}
+
+/* Needed because we don't declare it yet anywhere */
+void print_file_cb(GtkWidget *file_bt, construct_args_t *args _U_);
+
+/* Forward declaration */
+static void
+savehex_save_clicked_cb(GtkWidget * w, gpointer data);
+
+/* Launch the dialog box to put up the file selection box etc */
+void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
+{
+
+ GtkWidget *dlg_box;
+ GtkWidget *file_box, *file_bt = NULL;
+ GtkWidget *bbox, *save_button, *cancel_button;
+ GtkTooltips *tooltips;
+ static construct_args_t args = {
+ "Save Highlighted Data to File",
+ TRUE,
+ FALSE
+ };
+
+ /* if the window is already open, bring it to front */
+ if(savehex_dlg){
+ gdk_window_raise(savehex_dlg->window);
+ return;
+ }
+
+ tooltips = gtk_tooltips_new();
+
+ /*
+ * Build the dialog box we need ... a text entry field and a
+ * browse button, along with OK and Cancel
+ */
+
+ savehex_dlg=dlg_window_new("Ethereal: Save Highlighted Data to File");
+ SIGNAL_CONNECT(savehex_dlg, "destroy", savehex_dlg_destroy_cb, NULL);
+
+ dlg_box=gtk_vbox_new(FALSE, 10);
+ gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
+ gtk_container_add(GTK_CONTAINER(savehex_dlg), dlg_box);
+ gtk_widget_show(dlg_box);
+
+ /* File entry box */
+ file_box=gtk_hbox_new(FALSE, 3);
+
+ /* File entry */
+ file_entry=gtk_entry_new();
+ gtk_widget_set_usize(file_entry, 300, -2);
+ gtk_tooltips_set_tip(tooltips, file_entry, ("Enter Save Data filename"), NULL);
+ gtk_box_pack_start(GTK_BOX(file_box), file_entry, TRUE, TRUE, 0);
+ gtk_widget_show(file_entry);
+
+ /* File Browse button */
+ file_bt = gtk_button_new_with_label("Browse:");
+ SIGNAL_CONNECT(file_bt, "clicked", print_file_cb, &args);
+
+ /* file entry for print dialog */
+ OBJECT_SET_DATA(file_bt, E_FILE_TE_PTR_KEY, file_entry);
+ /* file entry for print dialog */
+
+ gtk_tooltips_set_tip (tooltips, file_bt, ("Browse output filename in filesystem"), NULL);
+ gtk_box_pack_start(GTK_BOX(file_box), file_bt, FALSE, TRUE, 0);
+ gtk_widget_show(file_bt);
+
+ gtk_box_pack_start(GTK_BOX(dlg_box), file_box, TRUE, TRUE, 0);
+ gtk_widget_show(file_box);
+
+ /* Now, the button box */
+ bbox=gtk_hbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_DEFAULT_STYLE);
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ /* the save button */
+ save_button=gtk_button_new_with_label("Save");
+ SIGNAL_CONNECT_OBJECT(save_button, "clicked",
+ savehex_save_clicked_cb, NULL);
+ gtk_box_pack_start(GTK_BOX(bbox), save_button, TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS(save_button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(save_button);
+ gtk_widget_show(save_button);
+
+#if GTK_MAJOR_VERSION < 2
+ cancel_button=gtk_button_new_with_label("Cancel");
+#else
+ cancel_button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+#endif
+ SIGNAL_CONNECT(cancel_button, "clicked", savehex_dlg_cancel_cb, savehex_dlg);
+ GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
+ gtk_box_pack_start(GTK_BOX(bbox), cancel_button, TRUE, TRUE, 0);
+ gtk_widget_show(cancel_button);
+
+ /* Catch the "activate" signal on the filter text entry, so that
+ if the user types Return there, we act as if the "Create Stat"
+ button had been selected, as happens if Return is typed if some
+ widget that *doesn't* handle the Return key has the input
+ focus. */
+ dlg_set_activate(file_entry, save_button);
+
+ /* Catch the "key_press_event" signal in the window, so that we can
+ catch the ESC key being pressed and act as if the "Cancel" button
+ had been selected. */
+ dlg_set_cancel(savehex_dlg, cancel_button);
+
+ /* Give the initial focus to the "File" entry box. */
+ gtk_widget_grab_focus(file_entry);
+
+ gtk_widget_show_all(savehex_dlg);
+}
+
+/* save the current highlighted hex data as hex_raw.dat */
+static void
+savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_)
+{
+ GtkWidget *bv;
+ int fd, start, end, len;
+ const guint8 *data_p = NULL;
+ char *file = NULL;
+
+ file = (char *)gtk_entry_get_text(GTK_ENTRY(file_entry));
+
+ /* Get rid of the dialog box */
+ gtk_widget_destroy(GTK_WIDGET(savehex_dlg));
+ if (!file ||! *file) {
+ return; /* XXX, put up an error box */
+ }
+
+ /* Must check if file name exists first */
+
+ bv = get_notebook_bv_ptr(byte_nb_ptr);
+ if (bv == NULL) {
+ return; /* none ... should complain */
+ }
+ /*
+ * Retrieve the info we need
+ */
+ end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
+ start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
+ data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
+
+ if (data_p == NULL || start == -1 || start > end) {
+ printf("No data to save\n"); /* XXX put up an error box */
+ return;
+ }
+
+ fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd == -1) { /* XXX - put up an error dialog */
+ perror(file);
+ return;
+ }
+ write(fd, data_p + start, end - start);
+ close(fd);
+}
+
+
#if GTK_MAJOR_VERSION < 2
static void
packet_hex_print_common(GtkText *bv, const guint8 *pd, int len, int bstart,
@@ -1539,3 +1715,4 @@ clear_tree_and_hex_views(void)
gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))));
#endif
}
+