Ethereal-dev: [Ethereal-dev] Forget button on TCP stream window

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: emre <emre@xxxxxxxxx>
Date: Sun, 30 Mar 2003 12:32:10 -0600
The Forget button appends the negation of the current filter to the previous filter,
processes the filter, and Closes the TCP stream window.

This enables a relatively painless exhaustive examination of multiple TCP stream
content.

e.

ps - as this is my first foray into GTK, i would appreciate any -/+ feedback.

Index: gtk/follow_dlg.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/follow_dlg.c,v
retrieving revision 1.31
diff -u -r1.31 gtk/follow_dlg.c
--- gtk/follow_dlg.c	6 Mar 2003 04:23:51 -0000	1.31
+++ gtk/follow_dlg.c	30 Mar 2003 19:10:53 -0000
@@ -90,11 +90,15 @@
 	GtkWidget	*carray_bt;
 	GtkWidget	*follow_save_as_w;
 	gboolean        is_ipv6;
+	char		*forget_filter;
+	GtkWidget	*filter_te;
+	GtkWidget	*streamwindow;
 } follow_info_t;
 
 static void follow_destroy_cb(GtkWidget * win, gpointer data);
 static void follow_charset_toggle_cb(GtkWidget * w, gpointer parent_w);
 static void follow_load_text(follow_info_t *follow_info);
+static void follow_forget(GtkWidget * w, gpointer parent_w);
 static void follow_print_stream(GtkWidget * w, gpointer parent_w);
 static void follow_save_as_cmd_cb(GtkWidget * w, gpointer data);
 static void follow_save_as_ok_cb(GtkWidget * w, GtkFileSelection * fs);
@@ -151,6 +155,7 @@
 	GtkWidget	*stream_om, *stream_menu, *stream_mi;
 	int		tmp_fd;
 	gchar		*follow_filter;
+	const gchar	*previous_filter;
 	const char	*hostname0, *hostname1;
 	char		*port0, *port1;
 	char		string[128];
@@ -204,6 +209,26 @@
 
 	/* Set the display filter entry accordingly */
 	filter_te = OBJECT_GET_DATA(w, E_DFILTER_TE_KEY);
+
+	/* needed in follow_forget(), is there a better way? */
+	follow_info->filter_te = filter_te;
+
+	/* save previous filter, const since we're not supposed to alter */
+	previous_filter =
+	    (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te));
+
+	/* allocate our new filter. API claims g_malloc terminates program on failure */
+	/* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */
+	follow_info->forget_filter =
+	    (gchar *)g_malloc(strlen(follow_filter) + strlen(previous_filter) + 16);
+
+	/* append the negation */
+	if(strlen(previous_filter)) {
+	    sprintf(follow_info->forget_filter, "%s \nand !(%s)", previous_filter, follow_filter);
+	} else {
+	    sprintf(follow_info->forget_filter, "!(%s)", follow_filter);
+	}
+
 	gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter);
 
 	/* Run the display filter so it goes in effect. */
@@ -217,6 +242,10 @@
 
 	/* The data_out_filename file now has all the text that was in the session */
 	streamwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+	/* needed in follow_forget(), is there a better way? */
+	follow_info->streamwindow = streamwindow;
+
 	gtk_widget_set_name(streamwindow, "TCP stream window");
 
 	SIGNAL_CONNECT(streamwindow, "destroy", follow_destroy_cb, NULL);
@@ -358,12 +387,19 @@
                        follow_info);
 	follow_info->carray_bt = radio_bt;
 
+	/* Create forget button */
+	button = gtk_button_new_with_label("Forget");
+	SIGNAL_CONNECT(button, "clicked", follow_forget, follow_info);
+
+	gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
 	/* Create Close Button */
 #if GTK_MAJOR_VERSION < 2
 	button = gtk_button_new_with_label("Close");
 #else
         button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
 #endif
+
 	SIGNAL_CONNECT_OBJECT(button, "clicked", gtk_widget_destroy,
                               streamwindow);
 	gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
@@ -408,7 +444,8 @@
 }
 
 /* The destroy call back has the responsibility of
- * unlinking the temporary file */
+ * unlinking the temporary file
+ * and freeing the forget_filter */
 static void
 follow_destroy_cb(GtkWidget *w, gpointer data _U_)
 {
@@ -416,6 +453,7 @@
 
 	follow_info = OBJECT_GET_DATA(w, E_FOLLOW_INFO_KEY);
 	unlink(follow_info->data_out_filename);
+	g_free(follow_info->forget_filter);
 	gtk_widget_destroy(w);
 	forget_follow_info(follow_info);
 	g_free(follow_info);
@@ -666,6 +704,26 @@
     FILE *fh = arg;
 
     fwrite(buffer, nchars, 1, fh);
+}
+
+static void
+follow_forget(GtkWidget * w _U_, gpointer data) 
+{
+    follow_info_t	*follow_info = data;
+
+    /* Lock out user from messing with us. (ie. don't free our data!) */
+    gtk_widget_set_sensitive(follow_info->streamwindow, FALSE);
+
+    /* Set the display filter. */
+    gtk_entry_set_text(GTK_ENTRY(follow_info->filter_te), follow_info->forget_filter);
+
+    /* Run the display filter so it goes in effect. */
+    filter_packets(&cfile, follow_info->forget_filter);
+
+    /* we force a subsequent close */
+    gtk_widget_destroy(follow_info->streamwindow);
+  
+    return;
 }
 
 static void