Sync up my changes so far to the content list (now called object
authorsfisher <sfisher@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 28 Feb 2007 23:20:40 +0000 (23:20 +0000)
committersfisher <sfisher@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 28 Feb 2007 23:20:40 +0000 (23:20 +0000)
list) feature for http traffic.  It's now available under File->
Export->Objects->HTTP.  More changes to come..

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

gtk/Makefile.common
gtk/content_list_http.c [deleted file]
gtk/export_object.c [new file with mode: 0644]
gtk/export_object.h [new file with mode: 0644]
gtk/export_object_http.c [new file with mode: 0644]
gtk/file_dlg.c
gtk/file_dlg.h
gtk/menu.c
stat_menu.h

index 93d4577873d8e505b762105ed5c7a8d522c475ad..43de810214c3b3c0ab54caae0e18771744257ed7 100644 (file)
@@ -63,6 +63,8 @@ WIRESHARK_GTK_SRC = \
        drag_and_drop.c         \
        wireshark-tap-register.c        \
        expert_comp_table.c    \
+       export_object.c        \
+       export_object_http.c   \
        file_dlg.c      \
        fileset_dlg.c   \
        filter_dlg.c    \
@@ -125,7 +127,6 @@ WIRESHARK_TAP_SRC = \
        bootp_stat.c    \
        camel_counter.c \
        camel_srt.c     \
-       content_list_http.c     \
        conversations_eth.c     \
        conversations_fc.c      \
        conversations_fddi.c    \
diff --git a/gtk/content_list_http.c b/gtk/content_list_http.c
deleted file mode 100644 (file)
index 6bf97ca..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/* content_list_http.c
- * Routines for tracking & saving content found in HTTP streams
- * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
- *
- * $Id$
- * 
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * 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
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-/* This feature has not been ported to GTK1 */
-#if GTK_MAJOR_VERSION >= 2
-
-#include <alert_box.h>
-#include <epan/dissectors/packet-http.h>
-#include <epan/emem.h>
-#include <epan/epan.h>
-#include <epan/packet_info.h>
-#include <epan/prefs.h>
-#include <epan/tap.h>
-#include <file.h>
-#include <globals.h>
-#include <stat_menu.h>
-#include <gtk/compat_macros.h>
-#include <gtk/dlg_utils.h>
-#include <gtk/file_dlg.h>
-#include <gtk/gui_stat_menu.h>
-#include <gtk/gui_utils.h>
-#include <gtk/main.h>
-#include <simple_dialog.h>
-#include <wiretap/file_util.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-enum {
-       PKT_NUM,
-       HOSTNAME_COLUMN,
-       CONTENT_TYPE_COLUMN,
-       BYTES_COLUMN,
-       FILENAME_COLUMN,
-       NUM_CONTENT_LIST_COLUMNS /* must be last */
-};
-
-typedef struct _cl_http_t {
-       GSList *entries;
-       GtkWidget *tree, *dlg;
-       GtkTreeView *tree_view;
-       GtkTreeIter *iter;
-       GtkTreeStore *store;
-       gint slist_pos, row_selected;
-} cl_http_t;
-
-typedef struct _cl_http_entry_t {
-       guint32 pkt_num;
-       gchar *hostname;
-       gchar *content_type;
-       gchar *filename;
-       guint payload_len;
-       guint8 *payload_data;
-} cl_http_entry_t;
-
-
-static void
-remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
-                 GtkTreeIter *iter _U_, gpointer arg)
-{
-       cl_http_t *content_list = arg;
-
-       gint *path_index;
-
-       if((path_index = gtk_tree_path_get_indices(path)) == NULL)
-               return;
-
-       content_list->row_selected = path_index[0];
-}
-
-static void
-remember_row_num(GtkTreeSelection *sel, gpointer data)
-{
-       gtk_tree_selection_selected_foreach(sel, remember_this_row, data);
-}
-
-static void
-cl_http_win_destroy_cb(GtkWindow *win _U_, gpointer data)
-{
-        cl_http_t *content_list = data;
-
-        protect_thread_critical_region();
-        remove_tap_listener(content_list);
-        unprotect_thread_critical_region();
-
-       g_free(content_list);
-}
-
-
-static void
-cl_http_reset(void *tapdata)
-{
-       cl_http_t *content_list = tapdata;
-
-       if(content_list->entries) {
-               g_slist_free(content_list->entries);
-               content_list->entries = NULL;
-       }
-
-       content_list->iter = NULL;
-}
-
-static int
-cl_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
-              const void *data)
-{
-       cl_http_t *content_list = tapdata;
-       const http_info_value_t *stat_info = data;
-       cl_http_entry_t *entry;
-
-       if(stat_info->content_type &&
-          g_ascii_strncasecmp(stat_info->content_type, "<NULL>", 6) != 0) {
-               entry = g_malloc(sizeof(cl_http_entry_t));
-
-               entry->pkt_num = pinfo->fd->num;
-               entry->hostname = g_strdup(stat_info->http_host);
-               entry->content_type = g_strdup(stat_info->content_type);
-               entry->filename = g_path_get_basename(stat_info->request_uri);
-               entry->payload_len = stat_info->payload_len;
-               entry->payload_data = g_memdup(stat_info->payload_data,
-                                              stat_info->payload_len);
-
-               content_list->entries = g_slist_append(content_list->entries, entry);
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-static void
-cl_http_draw(void *tapdata)
-{
-       cl_http_t *content_list = tapdata;
-
-       cl_http_entry_t *cl_entry;
-       GSList *slist_entry = NULL;
-       GSList *last_slist_entry = NULL;
-       gint last_slist_entry_num;
-       GtkTreeIter new_iter;
-       gchar *column_text[NUM_CONTENT_LIST_COLUMNS];
-
-       last_slist_entry = g_slist_last(content_list->entries);
-       last_slist_entry_num = g_slist_position(content_list->entries,
-                                               last_slist_entry);
-
-       while(content_list->slist_pos <= last_slist_entry_num &&
-             last_slist_entry_num != -1) {
-               slist_entry = g_slist_nth(content_list->entries,
-                                         content_list->slist_pos);
-               cl_entry = slist_entry->data;
-               
-               column_text[0] = g_strdup_printf("%u", cl_entry->pkt_num);
-               column_text[1] = g_strdup_printf("%s", cl_entry->hostname);
-               column_text[2] = g_strdup_printf("%s", cl_entry->content_type);
-               column_text[3] = g_strdup_printf("%u", cl_entry->payload_len);
-               column_text[4] = g_strdup_printf("%s", cl_entry->filename);
-
-               gtk_tree_store_append(content_list->store, &new_iter, content_list->iter);
-
-               gtk_tree_store_set(content_list->store, &new_iter,
-                                  PKT_NUM, column_text[0],
-                                  HOSTNAME_COLUMN, column_text[1],
-                                  CONTENT_TYPE_COLUMN, column_text[2],
-                                  BYTES_COLUMN, column_text[3],
-                                  FILENAME_COLUMN, column_text[4],
-                                  -1);
-
-               g_free(column_text[0]);
-               g_free(column_text[1]);
-               g_free(column_text[2]);
-               g_free(column_text[3]);
-               g_free(column_text[4]);
-
-               content_list->slist_pos++;
-       }
-}
-
-static void
-cl_http_save_clicked_cb(GtkWidget *widget, cl_http_entry_t *entry)
-{
-       int to_fd;
-       gchar *save_as_filename;
-
-       save_as_filename = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)));
-
-       to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_TRUNC |
-                        O_BINARY, 0644);
-       if(to_fd == -1) {
-               open_failure_alert_box(save_as_filename, errno, TRUE);
-               g_free(save_as_filename);
-               return;
-       }
-
-       if(eth_write(to_fd, entry->payload_data, entry->payload_len) < 0) {
-               write_failure_alert_box(save_as_filename, errno);
-               eth_close(to_fd);
-               g_free(save_as_filename);
-               return;
-       }
-
-       if (eth_close(to_fd) < 0) {
-               write_failure_alert_box(save_as_filename, errno);
-               g_free(save_as_filename);
-               return;
-       }
-
-       g_free(save_as_filename);
-}
-
-
-static void
-cl_http_save_entry_cb(GtkWidget *widget _U_, gpointer arg)
-{
-       GtkWidget *save_as_w;
-       cl_http_entry_t *entry;
-       cl_http_t *content_list = arg;
-
-       entry = g_slist_nth_data(content_list->entries,
-                                content_list->row_selected);
-
-       if(!entry)
-               return;
-
-       save_as_w = file_selection_new("Wireshark: Save Content As ...",
-                                      FILE_SELECTION_SAVE);
-
-       gtk_window_set_transient_for(GTK_WINDOW(save_as_w),
-                                    GTK_WINDOW(content_list->dlg));
-
-       gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w),
-                                         entry->filename);
-
-       if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT)
-               cl_http_save_clicked_cb(save_as_w, entry);
-
-       window_destroy(save_as_w);
-}
-
-
-static void
-cl_http_cb(GtkWidget *widget _U_, gpointer data _U_)
-{
-       GString *error_msg;
-       GtkWidget *sw;
-       GtkCellRenderer *renderer;
-       GtkTreeViewColumn *column;
-       GtkTreeSelection *selection;
-       GtkWidget *vbox, *bbox, *close_bt, *save_bt;
-
-       cl_http_t *content_list = g_malloc0(sizeof(cl_http_t));
-
-       /* Data will be gathered via a tap callback */
-       error_msg = register_tap_listener("http", content_list, NULL,
-                                         cl_http_reset,
-                                         cl_http_packet,
-                                         cl_http_draw);
-
-       if (error_msg) {
-               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                             "Can't register http tap: %s\n", error_msg->str);
-               g_string_free(error_msg, TRUE);
-               return;
-       }
-
-       content_list->dlg = dlg_window_new("Wireshark: HTTP Content List");
-       gtk_window_set_default_size(GTK_WINDOW(content_list->dlg),
-                                   DEF_WIDTH, DEF_HEIGHT);
-
-       vbox = gtk_vbox_new(FALSE, 5);
-
-        gtk_container_border_width(GTK_CONTAINER(vbox), 5);
-        gtk_container_add(GTK_CONTAINER(content_list->dlg), vbox);
-
-       sw = scrolled_window_new(NULL, NULL);
-       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
-                                           GTK_SHADOW_IN);
-
-       gtk_container_add(GTK_CONTAINER(vbox), sw);
-
-       content_list->store = gtk_tree_store_new(NUM_CONTENT_LIST_COLUMNS,
-                                                G_TYPE_STRING, G_TYPE_STRING,
-                                                G_TYPE_STRING, G_TYPE_STRING,
-                                                G_TYPE_STRING);
-
-       content_list->tree = tree_view_new(GTK_TREE_MODEL(content_list->store));
-
-       content_list->tree_view = GTK_TREE_VIEW(content_list->tree);
-
-       renderer = gtk_cell_renderer_text_new();
-       column = gtk_tree_view_column_new_with_attributes("Packet num",
-                                                         renderer,
-                                                         "text",
-                                                         PKT_NUM,
-                                                         NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(content_list->tree_view, column);
-
-       renderer = gtk_cell_renderer_text_new();
-       column = gtk_tree_view_column_new_with_attributes("Hostname",
-                                                         renderer,
-                                                         "text",
-                                                         HOSTNAME_COLUMN,
-                                                         NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(content_list->tree_view, column);
-
-       renderer = gtk_cell_renderer_text_new();
-       column = gtk_tree_view_column_new_with_attributes("Content Type",
-                                                         renderer,
-                                                         "text",
-                                                         CONTENT_TYPE_COLUMN,
-                                                         NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(content_list->tree_view, column);
-
-       renderer = gtk_cell_renderer_text_new();
-       column = gtk_tree_view_column_new_with_attributes("Bytes",
-                                                         renderer,
-                                                         "text",
-                                                         BYTES_COLUMN,
-                                                         NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(content_list->tree_view, column);
-
-       renderer = gtk_cell_renderer_text_new();
-       column = gtk_tree_view_column_new_with_attributes("Filename",
-                                                         renderer,
-                                                         "text",
-                                                         FILENAME_COLUMN,
-                                                         NULL);
-       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-       gtk_tree_view_append_column(content_list->tree_view, column);
-
-       gtk_container_add(GTK_CONTAINER(sw), content_list->tree);
-
-       selection = gtk_tree_view_get_selection(content_list->tree_view);
-        SIGNAL_CONNECT(selection, "changed", remember_row_num, content_list);
-
-       bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_SAVE, NULL);
-        gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
-        gtk_widget_show(bbox);
-
-       save_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_SAVE);
-       SIGNAL_CONNECT(save_bt, "clicked", cl_http_save_entry_cb, content_list);
-
-        SIGNAL_CONNECT(content_list->dlg, "delete_event",
-                      window_delete_event_cb, NULL);
-       SIGNAL_CONNECT(content_list->dlg, "destroy",
-                      cl_http_win_destroy_cb, NULL);
-
-        close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
-               window_set_cancel_button(content_list->dlg, close_bt,
-                                window_cancel_button_cb);
-
-       gtk_widget_show_all(content_list->dlg);
-       window_present(content_list->dlg);
-
-       cf_retap_packets(&cfile, FALSE);
-}
-#endif /* GTK_MAJOR_VERSION >= 2 */
-
-
-void
-register_tap_listener_gtk_cl_http_stat(void)
-{
-#if GTK_MAJOR_VERSION >= 2
-       register_stat_menu_item("HTTP", REGISTER_STAT_GROUP_CONTENT_LIST,
-                               cl_http_cb, NULL, NULL, NULL);
-#endif
-}
diff --git a/gtk/export_object.c b/gtk/export_object.c
new file mode 100644 (file)
index 0000000..bb986ca
--- /dev/null
@@ -0,0 +1,195 @@
+/* export_object.c
+ * Common routines for tracking & saving objects found in streams of data
+ * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ * 
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+/* This feature has not been ported to GTK1 */
+#if GTK_MAJOR_VERSION >= 2
+
+#include "export_object.h"
+
+#include <alert_box.h>
+#include <simple_dialog.h>
+
+#include <epan/packet_info.h>
+#include <epan/tap.h>
+#include <gtk/file_dlg.h>
+#include <gtk/gui_utils.h>
+#include <gtk/main.h>
+#include <wiretap/file_util.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+static void
+eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
+                    GtkTreeIter *iter _U_, gpointer arg)
+{
+       export_object_list_t *object_list = arg;
+       export_object_entry_t *entry;
+
+       gint *path_index;
+
+       if((path_index = gtk_tree_path_get_indices(path)) == NULL)
+               return;
+
+       object_list->row_selected = path_index[0];
+
+       entry = g_slist_nth_data(object_list->entries,
+                                object_list->row_selected);
+       
+       cf_goto_frame(&cfile, entry->pkt_num);
+}
+
+void
+eo_remember_row_num(GtkTreeSelection *sel, gpointer data)
+{
+       gtk_tree_selection_selected_foreach(sel, eo_remember_this_row, data);
+}
+
+
+void
+eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
+{
+        export_object_list_t *object_list = data;
+
+        protect_thread_critical_region();
+        remove_tap_listener(object_list);
+        unprotect_thread_critical_region();
+
+       g_free(object_list);
+}
+
+void
+eo_save_entry(gchar *save_as_filename, export_object_entry_t *entry)
+{
+       int to_fd;
+
+       to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_TRUNC |
+                        O_BINARY, 0644);
+       if(to_fd == -1) {
+               open_failure_alert_box(save_as_filename, errno, TRUE);
+               g_free(save_as_filename);
+               return;
+       }
+
+       if(eth_write(to_fd, entry->payload_data, entry->payload_len) < 0) {
+               write_failure_alert_box(save_as_filename, errno);
+               eth_close(to_fd);
+               g_free(save_as_filename);
+               return;
+       }
+
+       if (eth_close(to_fd) < 0) {
+               write_failure_alert_box(save_as_filename, errno);
+               g_free(save_as_filename);
+               return;
+       }
+
+       g_free(save_as_filename);
+}
+
+
+void
+eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
+{
+       GtkWidget *save_as_w;
+       export_object_list_t *object_list = arg;
+       export_object_entry_t *entry = NULL;
+
+       entry = g_slist_nth_data(object_list->entries,
+                                object_list->row_selected);
+
+       if(!entry) {
+               simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "No object was selected for saving.  Please click on an object and click on save again.");
+               return;
+       }
+
+       save_as_w = file_selection_new("Wireshark: Save Object As ...",
+                                      FILE_SELECTION_SAVE);
+
+       gtk_window_set_transient_for(GTK_WINDOW(save_as_w),
+                                    GTK_WINDOW(object_list->dlg));
+
+       gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w),
+                                         entry->filename);
+
+       if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT)
+               eo_save_entry(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)), entry);
+
+       window_destroy(save_as_w);
+}
+
+void
+eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
+{
+       gchar *save_as_fullpath = NULL;
+       export_object_list_t *object_list = arg;
+       export_object_entry_t *entry;
+       GtkWidget *save_in_w;
+       GSList *last_slist_entry;
+       gint last_slist_entry_num, i;
+
+       save_in_w = file_selection_new("Wireshark: Save All Objects In ...",
+                                      FILE_SELECTION_CREATE_FOLDER);
+
+       gtk_window_set_transient_for(GTK_WINDOW(save_in_w),
+                                    GTK_WINDOW(object_list->dlg));
+
+       if(gtk_dialog_run(GTK_DIALOG(save_in_w)) == GTK_RESPONSE_ACCEPT) {
+
+               /* Find the last entry in the SList, then start at the beginning
+                  saving each one. */
+               last_slist_entry = g_slist_last(object_list->entries);
+               last_slist_entry_num = g_slist_position(object_list->entries,
+                                                       last_slist_entry);
+
+               for(i = 0; i <= last_slist_entry_num; i++) {
+                       
+                       entry = g_slist_nth_data(object_list->entries, i);
+
+                       save_as_fullpath = g_strdup_printf("%s%c%s", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)), G_DIR_SEPARATOR, entry->filename);
+                       
+                       eo_save_entry(save_as_fullpath, entry);
+
+               }
+
+       }
+
+       window_destroy(save_in_w);
+}
+
+#endif /* GTK_MAJOR_VERSION >= 2 */
diff --git a/gtk/export_object.h b/gtk/export_object.h
new file mode 100644 (file)
index 0000000..861fee5
--- /dev/null
@@ -0,0 +1,67 @@
+/* export_object.h
+ * Declarations of routines for tracking & saving content found in HTTP streams
+ * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ * 
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ */
+
+#ifndef __EXPORT_OBJECT_H__
+#define __EXPORT_OBJECT_H__
+
+/* Common between protocols */
+enum {
+       EO_PKT_NUM_COLUMN,
+       EO_HOSTNAME_COLUMN,
+       EO_CONTENT_TYPE_COLUMN,
+       EO_BYTES_COLUMN,
+       EO_FILENAME_COLUMN,
+       EO_NUM_COLUMNS /* must be last */
+};
+
+typedef struct _export_object_list_t {
+       GSList *entries;
+       GtkWidget *tree, *dlg;
+       GtkTreeView *tree_view;
+       GtkTreeIter *iter;
+       GtkTreeStore *store;
+       gint slist_pos, row_selected;
+} export_object_list_t;
+
+typedef struct _export_object_entry_t {
+       guint32 pkt_num;
+       gchar *hostname;
+       gchar *content_type;
+       gchar *filename;
+       guint payload_len;
+       guint8 *payload_data;
+} export_object_entry_t;
+
+void eo_remember_row_num(GtkTreeSelection *sel, gpointer data);
+void eo_win_destroy_cb(GtkWindow *win _U_, gpointer data);
+void eo_save_entry_cb(GtkWidget *widget, export_object_entry_t *entry);
+void eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg);
+void eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg);
+
+/* Protocol specific */
+void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_);
+
+#endif /* __EXPORT_OBJECT_H__ */
diff --git a/gtk/export_object_http.c b/gtk/export_object_http.c
new file mode 100644 (file)
index 0000000..6465612
--- /dev/null
@@ -0,0 +1,298 @@
+/* export_object_http.c
+ * Routines for tracking & saving objects found in HTTP streams
+ * See also: export_object.c / export_object.h for common code
+ * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
+ *
+ * $Id$
+ * 
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+/* This feature has not been ported to GTK1 */
+#if GTK_MAJOR_VERSION >= 2
+
+#include "export_object.h"
+
+#include <epan/dissectors/packet-http.h>
+#include <epan/emem.h>
+#include <epan/epan.h>
+#include <epan/prefs.h>
+#include <epan/tap.h>
+#include <file.h>
+#include <globals.h>
+#include <simple_dialog.h>
+#include <stat_menu.h>
+#include <gtk/compat_macros.h>
+#include <gtk/dlg_utils.h>
+#include <gtk/file_dlg.h>
+#include <gtk/gui_utils.h>
+#include <gtk/gui_stat_menu.h>
+
+static void
+eo_http_reset(void *tapdata)
+{
+       export_object_list_t *object_list = tapdata;
+
+       if(object_list->entries) {
+               g_slist_free(object_list->entries);
+               object_list->entries = NULL;
+       }
+
+       object_list->iter = NULL;
+       object_list->row_selected = -1;
+}
+
+static int
+eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
+              const void *data)
+{
+       export_object_list_t *object_list = tapdata;
+       const http_info_value_t *stat_info = data;
+       export_object_entry_t *entry;
+
+       if(stat_info->content_type &&
+          g_ascii_strncasecmp(stat_info->content_type, "<NULL>", 6) != 0) {
+               entry = g_malloc(sizeof(export_object_entry_t));
+
+               entry->pkt_num = pinfo->fd->num;
+               entry->hostname = g_strdup(stat_info->http_host);
+               entry->content_type = g_strdup(stat_info->content_type);
+
+               if(stat_info->request_uri)
+                       entry->filename =
+                               g_path_get_basename(stat_info->request_uri);
+               else
+                       entry->filename = NULL;
+
+               entry->payload_len = stat_info->payload_len;
+               entry->payload_data = g_memdup(stat_info->payload_data,
+                                              stat_info->payload_len);
+
+               object_list->entries =
+                       g_slist_append(object_list->entries, entry);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+static void
+eo_http_draw(void *tapdata)
+{
+       export_object_list_t *object_list = tapdata;
+       export_object_entry_t *eo_entry;
+
+       GSList *slist_entry = NULL;
+       GSList *last_slist_entry = NULL;
+       gint last_slist_entry_num;
+       GtkTreeIter new_iter;
+       gchar *column_text[EO_NUM_COLUMNS];
+
+       last_slist_entry = g_slist_last(object_list->entries);
+       last_slist_entry_num = g_slist_position(object_list->entries,
+                                               last_slist_entry);
+
+       while(object_list->slist_pos <= last_slist_entry_num &&
+             last_slist_entry_num != -1) {
+               slist_entry = g_slist_nth(object_list->entries,
+                                         object_list->slist_pos);
+               eo_entry = slist_entry->data;
+               
+               column_text[0] = g_strdup_printf("%u", eo_entry->pkt_num);
+               column_text[1] = g_strdup_printf("%s", eo_entry->hostname);
+               column_text[2] = g_strdup_printf("%s", eo_entry->content_type);
+               column_text[3] = g_strdup_printf("%u", eo_entry->payload_len);
+               column_text[4] = g_strdup_printf("%s", eo_entry->filename);
+
+               gtk_tree_store_append(object_list->store, &new_iter,
+                                     object_list->iter);
+
+               gtk_tree_store_set(object_list->store, &new_iter,
+                                  EO_PKT_NUM_COLUMN, column_text[0],
+                                  EO_HOSTNAME_COLUMN, column_text[1],
+                                  EO_CONTENT_TYPE_COLUMN, column_text[2],
+                                  EO_BYTES_COLUMN, column_text[3],
+                                  EO_FILENAME_COLUMN, column_text[4],
+                                  -1);
+
+               g_free(column_text[0]);
+               g_free(column_text[1]);
+               g_free(column_text[2]);
+               g_free(column_text[3]);
+               g_free(column_text[4]);
+
+               object_list->slist_pos++;
+       }
+}
+
+void
+eo_http_cb(GtkWidget *widget _U_, gpointer data _U_)
+{
+       GString *error_msg;
+       GtkWidget *sw;
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+       GtkTreeSelection *selection;
+       GtkWidget *vbox, *bbox, *close_bt, *save_bt, *save_all_bt;
+       GtkTooltips *button_bar_tips;
+
+       export_object_list_t *object_list = g_malloc0(sizeof(export_object_list_t));
+
+       button_bar_tips = gtk_tooltips_new();
+
+       /* Data will be gathered via a tap callback */
+       error_msg = register_tap_listener("http", object_list, NULL,
+                                         eo_http_reset,
+                                         eo_http_packet,
+                                         eo_http_draw);
+
+       if (error_msg) {
+               simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                             "Can't register http tap: %s\n", error_msg->str);
+               g_string_free(error_msg, TRUE);
+               return;
+       }
+
+       object_list->dlg = dlg_window_new("Wireshark: HTTP Content List");
+
+       gtk_window_set_default_size(GTK_WINDOW(object_list->dlg),
+                                   DEF_WIDTH, DEF_HEIGHT);
+
+       vbox = gtk_vbox_new(FALSE, 5);
+
+        gtk_container_border_width(GTK_CONTAINER(vbox), 5);
+        gtk_container_add(GTK_CONTAINER(object_list->dlg), vbox);
+
+       sw = scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
+                                           GTK_SHADOW_IN);
+
+       gtk_container_add(GTK_CONTAINER(vbox), sw);
+
+       object_list->store = gtk_tree_store_new(EO_NUM_COLUMNS,
+                                                G_TYPE_STRING, G_TYPE_STRING,
+                                                G_TYPE_STRING, G_TYPE_STRING,
+                                                G_TYPE_STRING);
+
+       object_list->tree = tree_view_new(GTK_TREE_MODEL(object_list->store));
+
+       object_list->tree_view = GTK_TREE_VIEW(object_list->tree);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Packet num",
+                                                         renderer,
+                                                         "text",
+                                                         EO_PKT_NUM_COLUMN,
+                                                         NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(object_list->tree_view, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Hostname",
+                                                         renderer,
+                                                         "text",
+                                                         EO_HOSTNAME_COLUMN,
+                                                         NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(object_list->tree_view, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Content Type",
+                                                         renderer,
+                                                         "text",
+                                                         EO_CONTENT_TYPE_COLUMN,
+                                                         NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(object_list->tree_view, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Bytes",
+                                                         renderer,
+                                                         "text",
+                                                         EO_BYTES_COLUMN,
+                                                         NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(object_list->tree_view, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Filename",
+                                                         renderer,
+                                                         "text",
+                                                         EO_FILENAME_COLUMN,
+                                                         NULL);
+       gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+       gtk_tree_view_append_column(object_list->tree_view, column);
+
+       gtk_container_add(GTK_CONTAINER(sw), object_list->tree);
+
+       selection = gtk_tree_view_get_selection(object_list->tree_view);
+        SIGNAL_CONNECT(selection, "changed", eo_remember_row_num, object_list);
+
+       bbox = gtk_hbox_new(FALSE, 5);
+
+       /* Save All button */
+       save_all_bt = gtk_button_new_with_mnemonic("Save _All");
+       SIGNAL_CONNECT(save_all_bt, "clicked", eo_save_all_clicked_cb,
+                      object_list);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_all_bt,
+                            "Save all displayed objects with their displayed "
+                            "filenames.", NULL);
+       gtk_box_pack_end(GTK_BOX(bbox), save_all_bt, FALSE, FALSE, 0);
+
+       /* Save button */
+       save_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_SAVE);
+       SIGNAL_CONNECT(save_bt, "clicked", eo_save_clicked_cb, object_list);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_bt,
+                            "Saves the currently selected content to a file.",
+                            NULL);
+       gtk_box_pack_end(GTK_BOX(bbox), save_bt, FALSE, FALSE, 0);
+
+       /* Close button */
+        close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
+               window_set_cancel_button(object_list->dlg, close_bt,
+                                window_cancel_button_cb);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), close_bt,
+                            "Close this dialog.", NULL);
+       gtk_box_pack_end(GTK_BOX(bbox), close_bt, FALSE, FALSE, 0);
+
+       /* Pack the buttons into the "button box" */
+        gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+        gtk_widget_show(bbox);
+
+       /* Setup delete/destroy signal handlers */
+        SIGNAL_CONNECT(object_list->dlg, "delete_event",
+                      window_delete_event_cb, NULL);
+       SIGNAL_CONNECT(object_list->dlg, "destroy",
+                      eo_win_destroy_cb, NULL);
+
+       /* Show the window */
+       gtk_widget_show_all(object_list->dlg);
+       window_present(object_list->dlg);
+
+       cf_retap_packets(&cfile, FALSE);
+}
+#endif /* GTK_MAJOR_VERSION >= 2 */
index 2b8d5ee20cf3431b3626964ed5a0d05d43a8414d..306a86c5984036764808389391e66e020d7a44b2 100644 (file)
@@ -101,6 +101,11 @@ file_selection_new(const gchar *title, file_selection_action_t action)
     ok_button_text = GTK_STOCK_OK;
     break;
 
+  case FILE_SELECTION_CREATE_FOLDER:
+    gtk_action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
+    ok_button_text = GTK_STOCK_OK;
+    break;
+
   default:
     g_assert_not_reached();
     gtk_action = -1;
index ea90a3c9113442388ca3e6d40f881e6f9c460ebf..43cdb1dd79c86022e17580f32971a174420b0775 100644 (file)
@@ -56,7 +56,8 @@ typedef enum {
        FILE_SELECTION_OPEN,            /**< open a file */
        FILE_SELECTION_READ_BROWSE,     /**< browse for a file to read */
        FILE_SELECTION_SAVE,            /**< save/export a file */
-       FILE_SELECTION_WRITE_BROWSE     /**< browse for a file to write to */
+       FILE_SELECTION_WRITE_BROWSE,    /**< browse for a file to write to */
+       FILE_SELECTION_CREATE_FOLDER    /**< browse for a dir. to save in */  
 } file_selection_action_t;
 
 /** Create a file selection dialog box window that belongs to Wireshark's
index 0ca5df11dcf85b687d08812db49a46d023c36e66..f92e78a9296097e3752d9a80570485ff90b70d66 100644 (file)
 #include "u3.h"
 #include "macros_dlg.h"
 
+#if GTK_MAJOR_VERSION >= 2
+#include "export_object.h"
+#endif
+
 GtkWidget *popup_menu_object;
 
 static void
@@ -417,6 +421,10 @@ static GtkItemFactoryEntry menu_items[] =
 #endif
     ITEM_FACTORY_ENTRY("/File/Export/Selected Packet _Bytes...", "<control>H", savehex_cb,
                              0, NULL, NULL),
+#if GTK_MAJOR_VERSION >= 2
+    ITEM_FACTORY_ENTRY("/File/Export/_Objects/_HTTP", NULL, eo_http_cb, 0, NULL,
+                      NULL),
+#endif
     ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
     ITEM_FACTORY_STOCK_ENTRY("/File/_Print...", "<control>P", file_print_cmd_cb,
                              0, GTK_STOCK_PRINT),
@@ -983,9 +991,6 @@ register_stat_menu_item(
 
     switch(group) {
     case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break;
-#if GTK_MAJOR_VERSION >= 2
-    case(REGISTER_STAT_GROUP_CONTENT_LIST): toolspath = "/Statistics/C_ontent List/"; break;
-#endif
     case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break;
     case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break;
     case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break;
@@ -1105,12 +1110,6 @@ static guint merge_tap_menus_layered(GList *node, gint group) {
                 break;
             case(REGISTER_STAT_GROUP_GENERIC):
                 break;
-           case(REGISTER_STAT_GROUP_CONTENT_LIST):
-#if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 6)
-                entry->item_type = "<StockItem>";
-                entry->extra_data = GTK_STOCK_FILE;
-#endif
-                break;
             case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
                 entry->item_type = "<StockItem>";
                 entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS;
@@ -1186,11 +1185,6 @@ void merge_all_tap_menus(GList *node) {
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
         gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
     }
-#if GTK_MAJOR_VERSION >= 2
-    if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONTENT_LIST)) {
-        /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
-    }
-#endif
     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
         /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
     }
index 5f8fa4b1e521ec368c8a5802a6c7a99786d08c28..142cc5b47e272acf64d33d629c22b8a4acbd8735 100644 (file)
@@ -45,9 +45,6 @@ extern "C" {
 typedef enum {
     REGISTER_STAT_GROUP_NONE,
     REGISTER_STAT_GROUP_GENERIC,
-#if GTK_MAJOR_VERSION >= 2
-    REGISTER_STAT_GROUP_CONTENT_LIST,
-#endif
     REGISTER_STAT_GROUP_CONVERSATION_LIST,
     REGISTER_STAT_GROUP_ENDPOINT_LIST,
     REGISTER_STAT_GROUP_RESPONSE_TIME,