2 * Common routines for tracking & saving objects found in streams of data
3 * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
34 /* This feature has not been ported to GTK1 */
35 #if GTK_MAJOR_VERSION >= 2
37 #include <alert_box.h>
38 #include <simple_dialog.h>
40 #include <epan/packet_info.h>
41 #include <epan/prefs.h>
43 #include <gtk/compat_macros.h>
44 #include <gtk/dlg_utils.h>
45 #include <gtk/file_dlg.h>
46 #include <gtk/gui_utils.h>
47 #include <gtk/help_dlg.h>
49 #include <wiretap/file_util.h>
59 #include "export_object.h"
64 EO_CONTENT_TYPE_COLUMN,
67 EO_NUM_COLUMNS /* must be last */
72 eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
73 GtkTreeIter *iter _U_, gpointer arg)
75 export_object_list_t *object_list = arg;
76 export_object_entry_t *entry;
80 if((path_index = gtk_tree_path_get_indices(path)) == NULL)
83 object_list->row_selected = path_index[0];
85 entry = g_slist_nth_data(object_list->entries,
86 object_list->row_selected);
88 cf_goto_frame(&cfile, entry->pkt_num);
92 eo_remember_row_num(GtkTreeSelection *sel, gpointer data)
94 gtk_tree_selection_selected_foreach(sel, eo_remember_this_row, data);
99 eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
101 export_object_list_t *object_list = data;
103 protect_thread_critical_region();
104 remove_tap_listener(object_list);
105 unprotect_thread_critical_region();
111 eo_save_entry(gchar *save_as_filename, export_object_entry_t *entry)
115 to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL |
117 if(to_fd == -1) { /* An error occurred */
118 open_failure_alert_box(save_as_filename, errno, TRUE);
119 g_free(save_as_filename);
123 if(eth_write(to_fd, entry->payload_data, entry->payload_len) < 0) {
124 write_failure_alert_box(save_as_filename, errno);
126 g_free(save_as_filename);
130 if (eth_close(to_fd) < 0) {
131 write_failure_alert_box(save_as_filename, errno);
132 g_free(save_as_filename);
136 g_free(save_as_filename);
141 eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
143 GtkWidget *save_as_w;
144 export_object_list_t *object_list = arg;
145 export_object_entry_t *entry = NULL;
147 entry = g_slist_nth_data(object_list->entries,
148 object_list->row_selected);
151 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "No object was selected for saving. Please click on an object and click save again.");
155 save_as_w = file_selection_new("Wireshark: Save Object As ...",
156 FILE_SELECTION_SAVE);
158 gtk_window_set_transient_for(GTK_WINDOW(save_as_w),
159 GTK_WINDOW(object_list->dlg));
161 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w),
164 if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT)
165 eo_save_entry(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)), entry);
167 window_destroy(save_as_w);
171 eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
173 gchar *save_as_fullpath;
174 export_object_list_t *object_list = arg;
175 export_object_entry_t *entry;
176 GtkWidget *save_in_w;
177 GSList *last_slist_entry;
178 gint last_slist_entry_num, i;
180 save_in_w = file_selection_new("Wireshark: Save All Objects In ...",
181 FILE_SELECTION_CREATE_FOLDER);
183 gtk_window_set_transient_for(GTK_WINDOW(save_in_w),
184 GTK_WINDOW(object_list->dlg));
186 if(gtk_dialog_run(GTK_DIALOG(save_in_w)) == GTK_RESPONSE_ACCEPT) {
188 /* Find the last entry in the SList, then start at the beginning
189 saving each one until we reach the last entry. */
190 last_slist_entry = g_slist_last(object_list->entries);
191 last_slist_entry_num = g_slist_position(object_list->entries,
194 for(i = 0; i <= last_slist_entry_num; i++) {
196 entry = g_slist_nth_data(object_list->entries, i);
198 save_as_fullpath = g_build_filename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)), entry->filename, NULL);
200 eo_save_entry(save_as_fullpath, entry);
204 window_destroy(save_in_w);
208 eo_reset(void *tapdata)
210 export_object_list_t *object_list = tapdata;
212 if(object_list->entries) {
213 g_slist_free(object_list->entries);
214 object_list->entries = NULL;
217 object_list->iter = NULL;
218 object_list->row_selected = -1;
222 eo_draw(void *tapdata)
224 export_object_list_t *object_list = tapdata;
225 export_object_entry_t *eo_entry;
227 GSList *slist_entry = NULL;
228 GSList *last_slist_entry = NULL;
229 gint last_slist_entry_num;
230 GtkTreeIter new_iter;
231 gchar *column_text[EO_NUM_COLUMNS];
233 last_slist_entry = g_slist_last(object_list->entries);
234 last_slist_entry_num = g_slist_position(object_list->entries,
237 while(object_list->slist_pos <= last_slist_entry_num &&
238 last_slist_entry_num != -1) {
239 slist_entry = g_slist_nth(object_list->entries,
240 object_list->slist_pos);
241 eo_entry = slist_entry->data;
243 column_text[0] = g_strdup_printf("%u", eo_entry->pkt_num);
244 column_text[1] = g_strdup_printf("%s", eo_entry->hostname);
245 column_text[2] = g_strdup_printf("%s", eo_entry->content_type);
246 column_text[3] = g_strdup_printf("%u", eo_entry->payload_len);
247 column_text[4] = g_strdup_printf("%s", eo_entry->filename);
249 gtk_tree_store_append(object_list->store, &new_iter,
252 gtk_tree_store_set(object_list->store, &new_iter,
253 EO_PKT_NUM_COLUMN, column_text[0],
254 EO_HOSTNAME_COLUMN, column_text[1],
255 EO_CONTENT_TYPE_COLUMN, column_text[2],
256 EO_BYTES_COLUMN, column_text[3],
257 EO_FILENAME_COLUMN, column_text[4],
260 g_free(column_text[0]);
261 g_free(column_text[1]);
262 g_free(column_text[2]);
263 g_free(column_text[3]);
264 g_free(column_text[4]);
266 object_list->slist_pos++;
271 export_object_window(gchar *tapname, tap_packet_cb tap_packet)
274 GtkCellRenderer *renderer;
275 GtkTreeViewColumn *column;
276 GtkTreeSelection *selection;
277 GtkWidget *vbox, *bbox, *help_bt, *close_bt, *save_bt, *save_all_bt;
278 GtkTooltips *button_bar_tips;
280 export_object_list_t *object_list;
283 /* Initialize our object list structure */
284 object_list = g_malloc0(sizeof(export_object_list_t));
286 /* Data will be gathered via a tap callback */
287 error_msg = register_tap_listener(tapname, object_list, NULL,
293 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
294 "Can't register http tap: %s\n", error_msg->str);
295 g_string_free(error_msg, TRUE);
299 /* Set up our GUI window */
300 button_bar_tips = gtk_tooltips_new();
302 window_title = g_strdup_printf("Wireshark: %s object list", tapname);
303 object_list->dlg = dlg_window_new(window_title);
304 g_free(window_title);
306 gtk_window_set_default_size(GTK_WINDOW(object_list->dlg),
307 DEF_WIDTH, DEF_HEIGHT);
309 vbox = gtk_vbox_new(FALSE, 5);
311 gtk_container_border_width(GTK_CONTAINER(vbox), 5);
312 gtk_container_add(GTK_CONTAINER(object_list->dlg), vbox);
314 sw = scrolled_window_new(NULL, NULL);
315 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
318 gtk_container_add(GTK_CONTAINER(vbox), sw);
320 object_list->store = gtk_tree_store_new(EO_NUM_COLUMNS,
321 G_TYPE_STRING, G_TYPE_STRING,
322 G_TYPE_STRING, G_TYPE_STRING,
325 object_list->tree = tree_view_new(GTK_TREE_MODEL(object_list->store));
327 object_list->tree_view = GTK_TREE_VIEW(object_list->tree);
329 renderer = gtk_cell_renderer_text_new();
330 column = gtk_tree_view_column_new_with_attributes("Packet num",
335 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
336 gtk_tree_view_append_column(object_list->tree_view, column);
338 renderer = gtk_cell_renderer_text_new();
339 column = gtk_tree_view_column_new_with_attributes("Hostname",
344 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
345 gtk_tree_view_append_column(object_list->tree_view, column);
347 renderer = gtk_cell_renderer_text_new();
348 column = gtk_tree_view_column_new_with_attributes("Content Type",
351 EO_CONTENT_TYPE_COLUMN,
353 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
354 gtk_tree_view_append_column(object_list->tree_view, column);
356 renderer = gtk_cell_renderer_text_new();
357 column = gtk_tree_view_column_new_with_attributes("Bytes",
362 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
363 gtk_tree_view_append_column(object_list->tree_view, column);
365 renderer = gtk_cell_renderer_text_new();
366 column = gtk_tree_view_column_new_with_attributes("Filename",
371 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
372 gtk_tree_view_append_column(object_list->tree_view, column);
374 gtk_container_add(GTK_CONTAINER(sw), object_list->tree);
376 selection = gtk_tree_view_get_selection(object_list->tree_view);
377 SIGNAL_CONNECT(selection, "changed", eo_remember_row_num, object_list);
380 bbox = gtk_hbox_new(FALSE, 5);
383 help_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_HELP);
384 SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_EXPORT_OBJECT_LIST);
385 gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), help_bt,
386 "Show help on this dialog", NULL);
387 gtk_box_pack_start(GTK_BOX(bbox), help_bt, FALSE, FALSE, 0);
389 /* Save All button */
390 save_all_bt = gtk_button_new_with_mnemonic("Save _All");
391 SIGNAL_CONNECT(save_all_bt, "clicked", eo_save_all_clicked_cb,
393 gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_all_bt,
394 "Save all listed objects with their displayed "
396 gtk_box_pack_end(GTK_BOX(bbox), save_all_bt, FALSE, FALSE, 0);
399 save_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_SAVE_AS);
400 SIGNAL_CONNECT(save_bt, "clicked", eo_save_clicked_cb, object_list);
401 gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_bt,
402 "Saves the currently selected content to a file.",
404 gtk_box_pack_end(GTK_BOX(bbox), save_bt, FALSE, FALSE, 0);
407 close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
408 GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT);
409 gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), close_bt,
410 "Close this dialog.", NULL);
411 gtk_box_pack_end(GTK_BOX(bbox), close_bt, FALSE, FALSE, 0);
413 /* Pack the buttons into the "button box" */
414 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
415 gtk_widget_show(bbox);
417 /* Setup cancel/delete/destroy signal handlers */
418 SIGNAL_CONNECT(object_list->dlg, "delete_event",
419 window_delete_event_cb, NULL);
420 SIGNAL_CONNECT(object_list->dlg, "destroy",
421 eo_win_destroy_cb, NULL);
422 window_set_cancel_button(object_list->dlg, close_bt,
423 window_cancel_button_cb);
425 /* Show the window */
426 gtk_widget_show_all(object_list->dlg);
427 window_present(object_list->dlg);
429 cf_retap_packets(&cfile, FALSE);
432 #endif /* GTK_MAJOR_VERSION >= 2 */