aboutsummaryrefslogtreecommitdiffstats
path: root/ui/gtk
diff options
context:
space:
mode:
authorMoshe Kaplan <me@moshekaplan.com>2016-11-24 09:37:01 -0500
committerMichael Mann <mmann78@netscape.net>2016-12-02 16:07:35 +0000
commit20c57cb298e4f3b7ac66a22fb7477e4cf424a11b (patch)
tree3929a45a2f0df5182af007af697edfa9a55a4634 /ui/gtk
parent9ca313cfbe4993a0a36520d216a3e4282b0b7b99 (diff)
Enable exporting objects with tshark
A new "--export-object <protocol>,<destdir>" option is added to tshark. This required refactoring Export Object behavior in all GUIs to give the export object handling to the dissector, rather than the ui layer. Included in the refactoring was fixing some serious memory leaks in Qt Export Object dialog, crash due to memory scope issues in GTK Export Object dialog, and addition sorting column feature in Qt dialog (set up by creating a widget to manage the items that were previously leaking memory) Bug: 9319 Ping-Bug: 13174 Change-Id: I515d7662fa1f150f672b1476716f347ec27deb9b Reviewed-on: https://code.wireshark.org/review/18927 Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Tested-by: Michael Mann <mmann78@netscape.net> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'ui/gtk')
-rw-r--r--ui/gtk/export_object_dlg.c115
-rw-r--r--ui/gtk/export_object_dlg.h8
-rw-r--r--ui/gtk/main_menubar.c86
3 files changed, 126 insertions, 83 deletions
diff --git a/ui/gtk/export_object_dlg.c b/ui/gtk/export_object_dlg.c
index ee1c3af8b3..ba7ce9c136 100644
--- a/ui/gtk/export_object_dlg.c
+++ b/ui/gtk/export_object_dlg.c
@@ -32,7 +32,7 @@
#include <wsutil/str_util.h>
-#include <ui/export_object.h>
+#include <ui/export_object_ui.h>
#include <ui/simple_dialog.h>
#include "dlg_utils.h"
@@ -43,13 +43,6 @@
#include "stock_icons.h"
#include "export_object_dlg.h"
-/* When a protocol needs intermediate data structures to construct the
-export objects, then it must specifiy a function that cleans up all
-those data structures. This function is passed to export_object_window
-and called when tap reset or windows closes occurs. If no function is needed
-a NULL value should be passed instead */
-typedef void (*eo_protocoldata_reset_cb)(void);
-
enum {
EO_PKT_NUM_COLUMN,
EO_HOSTNAME_COLUMN,
@@ -59,22 +52,23 @@ enum {
EO_NUM_COLUMNS /* must be last */
};
-struct _export_object_list_t {
+typedef struct _export_object_list_gui_t {
GSList *entries;
GtkWidget *tree, *dlg;
GtkTreeView *tree_view;
GtkTreeIter *iter;
GtkTreeStore *store;
gint row_selected;
-};
+} export_object_list_gui_t;
-static eo_protocoldata_reset_cb eo_protocoldata_reset = NULL;
+static export_object_gui_reset_cb eo_protocoldata_reset = NULL;
static void
eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
GtkTreeIter *iter _U_, gpointer arg)
{
- export_object_list_t *object_list = (export_object_list_t *)arg;
+ export_object_list_t *tap_object = (export_object_list_t *)arg;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
export_object_entry_t *entry;
gint *path_index;
@@ -102,23 +96,19 @@ eo_remember_row_num(GtkTreeSelection *sel, gpointer data)
static void
eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
- export_object_list_t *object_list = (export_object_list_t *)data;
+ export_object_list_t *tap_object = (export_object_list_t *)data;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
export_object_entry_t *entry;
GSList *slist = object_list->entries;
- remove_tap_listener(object_list);
+ remove_tap_listener(tap_object);
/* Free the GSList attributes */
while(slist) {
entry = (export_object_entry_t *)slist->data;
-
- g_free(entry->hostname);
- g_free(entry->content_type);
- g_free(entry->filename);
- wmem_free(wmem_file_scope(), entry->payload_data);
+ eo_free_entry(entry);
slist = slist->next;
- wmem_free(wmem_file_scope(), entry);
}
/* Free the GSList elements */
@@ -130,7 +120,7 @@ eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
}
static char *
-gtk_eo_save_object_as_file(export_object_list_t *object_list, char *auxfilename)
+gtk_eo_save_object_as_file(export_object_list_gui_t *object_list, char *auxfilename)
{
GtkWidget *save_as_w;
char *pathname;
@@ -156,7 +146,8 @@ gtk_eo_save_object_as_file(export_object_list_t *object_list, char *auxfilename)
static void
eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
{
- export_object_list_t *object_list = (export_object_list_t *)arg;
+ export_object_list_t *tap_object = (export_object_list_t *)arg;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
export_object_entry_t *entry;
GString *safe_filename = NULL;
char *pathname;
@@ -193,12 +184,12 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
g_string_free(safe_filename, TRUE);
}
-#define MAXFILELEN 255
static void
eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
{
gchar *save_as_fullpath = NULL;
- export_object_list_t *object_list = (export_object_list_t *)arg;
+ export_object_list_t *tap_object = (export_object_list_t *)arg;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
export_object_entry_t *entry;
GtkWidget *save_in_w;
GSList *slist = object_list->entries;
@@ -216,21 +207,21 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
entry = (export_object_entry_t *)slist->data;
save_in_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w));
- if ((strlen(save_in_path) < MAXFILELEN)) {
+ if ((strlen(save_in_path) < EXPORT_OBJECT_MAXFILELEN)) {
do {
g_free(save_as_fullpath);
if (entry->filename) {
safe_filename = eo_massage_str(entry->filename,
- MAXFILELEN - strlen(save_in_path), count);
+ EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count);
} else {
- char generic_name[MAXFILELEN+1];
+ char generic_name[EXPORT_OBJECT_MAXFILELEN+1];
const char *ext;
- ext = ct2ext(entry->content_type);
+ ext = eo_ct2ext(entry->content_type);
g_snprintf(generic_name, sizeof(generic_name),
"object%u%s%s", entry->pkt_num, ext ? "." : "",
ext ? ext : "");
safe_filename = eo_massage_str(generic_name,
- MAXFILELEN - strlen(save_in_path), count);
+ EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count);
}
save_as_fullpath = g_build_filename(
save_in_path, safe_filename->str, NULL);
@@ -260,7 +251,8 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
static void
eo_reset(void *tapdata)
{
- export_object_list_t *object_list = (export_object_list_t *)tapdata;
+ export_object_list_t *tap_object = (export_object_list_t *)tapdata;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
object_list->entries = NULL;
object_list->iter = NULL;
@@ -272,7 +264,8 @@ eo_reset(void *tapdata)
static void
eo_draw(void *tapdata)
{
- export_object_list_t *object_list = (export_object_list_t *)tapdata;
+ export_object_list_t *tap_object = (export_object_list_t *)tapdata;
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data;
export_object_entry_t *eo_entry;
gchar *size_str;
@@ -305,17 +298,23 @@ eo_draw(void *tapdata)
}
}
-void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry)
+static void
+object_list_add_entry(void *gui_data, export_object_entry_t *entry)
{
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
+
object_list->entries = g_slist_append(object_list->entries, entry);
}
-export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row) {
+static export_object_entry_t*
+object_list_get_entry(void *gui_data, int row) {
+ export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data;
+
return (export_object_entry_t *)g_slist_nth_data(object_list->entries, row);
}
static void
-export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_packet, eo_protocoldata_reset_cb eo_protocoldata_resetfn)
+export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_packet, export_object_gui_reset_cb eo_protocoldata_resetfn)
{
GtkWidget *sw;
GtkCellRenderer *renderer;
@@ -323,17 +322,23 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
GtkTreeSelection *selection;
GtkWidget *vbox, *bbox, *help_bt, *cancel_bt, *save_bt, *save_all_bt;
GString *error_msg;
- export_object_list_t *object_list;
+ export_object_list_t *tap_data;
+ export_object_list_gui_t *object_list;
gchar *window_title;
/* Initialize the pointer to the private data clearing function */
eo_protocoldata_reset = eo_protocoldata_resetfn;
/* Initialize our object list structure */
- object_list = g_new0(export_object_list_t,1);
+ tap_data = g_new0(export_object_list_t,1);
+ object_list = g_new0(export_object_list_gui_t,1);
+
+ tap_data->add_entry = object_list_add_entry;
+ tap_data->get_entry = object_list_get_entry;
+ tap_data->gui_data = (void*)object_list;
/* Data will be gathered via a tap callback */
- error_msg = register_tap_listener(tapname, object_list, NULL, 0,
+ error_msg = register_tap_listener(tapname, tap_data, NULL, 0,
eo_reset,
tap_packet,
eo_draw);
@@ -342,6 +347,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't register %s tap: %s\n", name, error_msg->str);
g_string_free(error_msg, TRUE);
+ g_free(tap_data);
g_free(object_list);
return;
}
@@ -425,7 +431,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
gtk_container_add(GTK_CONTAINER(sw), object_list->tree);
selection = gtk_tree_view_get_selection(object_list->tree_view);
- g_signal_connect(selection, "changed", G_CALLBACK(eo_remember_row_num), object_list);
+ g_signal_connect(selection, "changed", G_CALLBACK(eo_remember_row_num), tap_data);
bbox = dlg_button_row_new(GTK_STOCK_HELP, WIRESHARK_STOCK_SAVE_ALL, GTK_STOCK_SAVE_AS, GTK_STOCK_CANCEL, NULL);
@@ -436,13 +442,12 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
/* Save All button */
save_all_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_SAVE_ALL);
- g_signal_connect(save_all_bt, "clicked", G_CALLBACK(eo_save_all_clicked_cb),
- object_list);
+ g_signal_connect(save_all_bt, "clicked", G_CALLBACK(eo_save_all_clicked_cb), tap_data);
gtk_widget_set_tooltip_text(save_all_bt, "Save all listed objects with their displayed filenames.");
/* Save As button */
save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE_AS);
- g_signal_connect(save_bt, "clicked", G_CALLBACK(eo_save_clicked_cb), object_list);
+ g_signal_connect(save_bt, "clicked", G_CALLBACK(eo_save_clicked_cb), tap_data);
gtk_widget_set_tooltip_text(save_bt, "Saves the currently selected content to a file.");
/* Cancel button */
@@ -455,8 +460,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
/* Setup cancel/delete/destroy signal handlers */
g_signal_connect(object_list->dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
- g_signal_connect(object_list->dlg, "destroy",
- G_CALLBACK(eo_win_destroy_cb), object_list);
+ g_signal_connect(object_list->dlg, "destroy", G_CALLBACK(eo_win_destroy_cb), tap_data);
window_set_cancel_button(object_list->dlg, cancel_bt,
window_cancel_button_cb);
@@ -467,30 +471,9 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_
cf_retap_packets(&cfile);
}
-void
-eo_dicom_cb(GtkWidget *widget _U_, gpointer data _U_)
-{
- export_object_window("dicom_eo", "DICOM", eo_dicom_packet, NULL);
-}
-
-void
-eo_http_cb(GtkWidget *widget _U_, gpointer data _U_)
-{
- export_object_window("http_eo", "HTTP", eo_http_packet, NULL);
-}
-
-void
-eo_smb_cb(GtkWidget *widget _U_, gpointer data _U_)
-{
- /* Call the export_object window */
- export_object_window("smb_eo", "SMB", eo_smb_packet, eo_smb_cleanup);
-}
-
-void
-eo_tftp_cb(GtkWidget *widget _U_, gpointer data _U_)
+void exportobject_cb(register_eo_t *eo)
{
- /* Call the export_object window */
- export_object_window("tftp_eo", "TFTP", eo_tftp_packet, eo_tftp_cleanup);
+ export_object_window(get_eo_tap_listener_name(eo), proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))), get_eo_packet_func(eo), get_eo_reset_func(eo));
}
/*
diff --git a/ui/gtk/export_object_dlg.h b/ui/gtk/export_object_dlg.h
index 73fae69a34..72121df593 100644
--- a/ui/gtk/export_object_dlg.h
+++ b/ui/gtk/export_object_dlg.h
@@ -25,10 +25,8 @@
#ifndef __EXPORT_OBJECT_DLG_H__
#define __EXPORT_OBJECT_DLG_H__
-/* Protocol specific */
-void eo_dicom_cb(GtkWidget *widget _U_, gpointer data _U_);
-void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_);
-void eo_smb_cb(GtkWidget *widget _U_, gpointer data _U_);
-void eo_tftp_cb(GtkWidget *widget _U_, gpointer data _U_);
+#include <epan/export_object.h>
+
+void exportobject_cb(register_eo_t *eo);
#endif /* __EXPORT_OBJECT_DLG_H__ */
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index 0b8aeacc60..907f65285d 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -34,6 +34,7 @@
#include <epan/column.h>
#include <epan/stats_tree_priv.h>
#include <epan/plugin_if.h>
+#include <epan/export_object.h>
#include "globals.h"
#include <epan/color_filters.h>
@@ -821,11 +822,8 @@ static const char *ui_desc_menubar =
" <menuitem name='ExportSelectedPacketBytes' action='/File/ExportSelectedPacketBytes'/>\n"
" <menuitem name='ExportPDUs' action='/File/ExportPDUs'/>\n"
" <menuitem name='ExportSSLSessionKeys' action='/File/ExportSSLSessionKeys'/>\n"
-" <menu name= 'ExportObjects' action='/File/ExportObjects'>\n"
-" <menuitem name='HTTP' action='/File/ExportObjects/HTTP'/>\n"
-" <menuitem name='DICOM' action='/File/ExportObjects/DICOM'/>\n"
-" <menuitem name='SMB' action='/File/ExportObjects/SMB'/>\n"
-" <menuitem name='TFTP' action='/File/ExportObjects/TFTP'/>\n"
+" <menu name= 'ExportObjectsMenu' action='/File/ExportObjects'>\n"
+" <placeholder name='ExportObjects'/>\n"
" </menu>\n"
" <separator/>\n"
" <menuitem name='Print' action='/File/Print'/>\n"
@@ -1280,10 +1278,6 @@ static const GtkActionEntry main_menu_bar_entries[] = {
NULL, NULL, G_CALLBACK(export_pdml_cmd_cb) },
{ "/File/ExportPacketDissections/JSON", NULL, "as \"_JSON\" file...",
NULL, NULL, G_CALLBACK(export_json_cmd_cb) },
- { "/File/ExportObjects/HTTP", NULL, "_HTTP", NULL, NULL, G_CALLBACK(eo_http_cb) },
- { "/File/ExportObjects/DICOM", NULL, "_DICOM", NULL, NULL, G_CALLBACK(eo_dicom_cb) },
- { "/File/ExportObjects/SMB", NULL, "_SMB/SMB2", NULL, NULL, G_CALLBACK(eo_smb_cb) },
- { "/File/ExportObjects/TFTP", NULL, "_TFTP", NULL, NULL, G_CALLBACK(eo_tftp_cb) },
{ "/Edit/Copy", NULL, "Copy", NULL, NULL, NULL },
@@ -2810,6 +2804,73 @@ menu_hostlist_list(capture_file *cf)
conversation_table_iterate_tables(add_hostlist_menuitem, &conv_data);
}
+typedef struct {
+ guint merge_id;
+ GtkActionGroup *action_group;
+ int counter;
+} eo_menu_t;
+
+static void
+menu_exportobject_cb(GtkAction *action _U_, gpointer user_data)
+{
+ register_eo_t *eo = (register_eo_t*)user_data;
+
+ exportobject_cb(eo);
+}
+
+static void
+add_export_object_menuitem(gpointer data, gpointer user_data)
+{
+ register_eo_t *eo = (register_eo_t*)data;
+ eo_menu_t *eo_menu_data = (eo_menu_t*)user_data;
+ gchar *action_name;
+ GtkAction *action;
+
+ action_name = g_strdup_printf ("exportobject-%u", eo_menu_data->counter);
+ /*g_warning("action_name %s, filter_entry->name %s",action_name,filter_entry->name);*/
+ action = (GtkAction *)g_object_new (GTK_TYPE_ACTION,
+ "name", action_name,
+ "label", proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))),
+ "sensitive", TRUE,
+ NULL);
+ g_signal_connect (action, "activate",
+ G_CALLBACK (menu_exportobject_cb), eo);
+ gtk_action_group_add_action (eo_menu_data->action_group, action);
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (ui_manager_main_menubar, eo_menu_data->merge_id,
+ "/Menubar/FileMenu/ExportObjectsMenu/ExportObjects",
+ action_name,
+ action_name,
+ GTK_UI_MANAGER_MENUITEM,
+ FALSE);
+ g_free(action_name);
+ eo_menu_data->counter++;
+}
+
+static void
+menu_export_object_list(void)
+{
+ GtkWidget *submenu_export_object;
+ eo_menu_t eo_data;
+
+ eo_data.merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar);
+
+ eo_data.action_group = gtk_action_group_new ("exportobject-list-group");
+
+ submenu_export_object = gtk_ui_manager_get_widget(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects");
+ if(!submenu_export_object){
+ g_warning("menu_export_object_list: No submenu_exportobject_list found, path= /Menubar/FileMenu/ExportObjects");
+ }
+
+ gtk_ui_manager_insert_action_group (ui_manager_main_menubar, eo_data.action_group, 0);
+ g_object_set_data (G_OBJECT (ui_manager_main_menubar),
+ "exportobject-list-merge-id", GUINT_TO_POINTER (eo_data.merge_id));
+
+ eo_data.counter = 0;
+ eo_iterate_tables(add_export_object_menuitem, &eo_data);
+}
+
static void
menu_conversation_display_filter_cb(GtkAction *action _U_, gpointer data)
{
@@ -3253,6 +3314,7 @@ menus_init(void)
menu_dissector_filter(&cfile);
menu_conversation_list(&cfile);
menu_hostlist_list(&cfile);
+ menu_export_object_list();
/* Add additional entries which may have been introduced by dissectors and/or plugins */
ws_menubar_external_menus();
@@ -4396,7 +4458,7 @@ set_menus_for_capture_file(capture_file *cf)
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPacketDissections", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSelectedPacketBytes", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys", FALSE);
- set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects", FALSE);
+ set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPDUs", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/Reload", FALSE);
} else {
@@ -4415,7 +4477,7 @@ set_menus_for_capture_file(capture_file *cf)
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPacketDissections", TRUE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSelectedPacketBytes", TRUE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys", TRUE);
- set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects", TRUE);
+ set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu", TRUE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPDUs", TRUE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/Reload", TRUE);
}
@@ -4441,7 +4503,7 @@ set_menus_for_capture_in_progress(gboolean capture_in_progress)
capture_in_progress);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys",
capture_in_progress);
- set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects",
+ set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu",
capture_in_progress);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/Set",
!capture_in_progress);